ActivityManagerService.java revision 0ce3a291fb4fdbfd041e605c0cb71dff4f681e8a
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    String mTrackAllocationApp = null;
1208
1209    final long[] mTmpLong = new long[1];
1210
1211    static final class ProcessChangeItem {
1212        static final int CHANGE_ACTIVITIES = 1<<0;
1213        static final int CHANGE_PROCESS_STATE = 1<<1;
1214        int changes;
1215        int uid;
1216        int pid;
1217        int processState;
1218        boolean foregroundActivities;
1219    }
1220
1221    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1222    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1223
1224    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1225    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1226
1227    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1228    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1229
1230    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1231    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1232
1233    /**
1234     * Runtime CPU use collection thread.  This object's lock is used to
1235     * perform synchronization with the thread (notifying it to run).
1236     */
1237    final Thread mProcessCpuThread;
1238
1239    /**
1240     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1241     * Must acquire this object's lock when accessing it.
1242     * NOTE: this lock will be held while doing long operations (trawling
1243     * through all processes in /proc), so it should never be acquired by
1244     * any critical paths such as when holding the main activity manager lock.
1245     */
1246    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1247            MONITOR_THREAD_CPU_USAGE);
1248    final AtomicLong mLastCpuTime = new AtomicLong(0);
1249    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1250
1251    long mLastWriteTime = 0;
1252
1253    /**
1254     * Used to retain an update lock when the foreground activity is in
1255     * immersive mode.
1256     */
1257    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1258
1259    /**
1260     * Set to true after the system has finished booting.
1261     */
1262    boolean mBooted = false;
1263
1264    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1265    int mProcessLimitOverride = -1;
1266
1267    WindowManagerService mWindowManager;
1268
1269    final ActivityThread mSystemThread;
1270
1271    // Holds the current foreground user's id
1272    int mCurrentUserId = 0;
1273    // Holds the target user's id during a user switch
1274    int mTargetUserId = UserHandle.USER_NULL;
1275    // If there are multiple profiles for the current user, their ids are here
1276    // Currently only the primary user can have managed profiles
1277    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1278
1279    /**
1280     * Mapping from each known user ID to the profile group ID it is associated with.
1281     */
1282    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1283
1284    private UserManagerService mUserManager;
1285
1286    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1287        final ProcessRecord mApp;
1288        final int mPid;
1289        final IApplicationThread mAppThread;
1290
1291        AppDeathRecipient(ProcessRecord app, int pid,
1292                IApplicationThread thread) {
1293            if (DEBUG_ALL) Slog.v(
1294                TAG, "New death recipient " + this
1295                + " for thread " + thread.asBinder());
1296            mApp = app;
1297            mPid = pid;
1298            mAppThread = thread;
1299        }
1300
1301        @Override
1302        public void binderDied() {
1303            if (DEBUG_ALL) Slog.v(
1304                TAG, "Death received in " + this
1305                + " for thread " + mAppThread.asBinder());
1306            synchronized(ActivityManagerService.this) {
1307                appDiedLocked(mApp, mPid, mAppThread, true);
1308            }
1309        }
1310    }
1311
1312    static final int SHOW_ERROR_MSG = 1;
1313    static final int SHOW_NOT_RESPONDING_MSG = 2;
1314    static final int SHOW_FACTORY_ERROR_MSG = 3;
1315    static final int UPDATE_CONFIGURATION_MSG = 4;
1316    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1317    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1318    static final int SERVICE_TIMEOUT_MSG = 12;
1319    static final int UPDATE_TIME_ZONE = 13;
1320    static final int SHOW_UID_ERROR_MSG = 14;
1321    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1322    static final int PROC_START_TIMEOUT_MSG = 20;
1323    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1324    static final int KILL_APPLICATION_MSG = 22;
1325    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1326    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1327    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1328    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1329    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1330    static final int CLEAR_DNS_CACHE_MSG = 28;
1331    static final int UPDATE_HTTP_PROXY_MSG = 29;
1332    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1333    static final int DISPATCH_PROCESSES_CHANGED = 31;
1334    static final int DISPATCH_PROCESS_DIED = 32;
1335    static final int REPORT_MEM_USAGE_MSG = 33;
1336    static final int REPORT_USER_SWITCH_MSG = 34;
1337    static final int CONTINUE_USER_SWITCH_MSG = 35;
1338    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1339    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1340    static final int PERSIST_URI_GRANTS_MSG = 38;
1341    static final int REQUEST_ALL_PSS_MSG = 39;
1342    static final int START_PROFILES_MSG = 40;
1343    static final int UPDATE_TIME = 41;
1344    static final int SYSTEM_USER_START_MSG = 42;
1345    static final int SYSTEM_USER_CURRENT_MSG = 43;
1346    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1347    static final int FINISH_BOOTING_MSG = 45;
1348    static final int START_USER_SWITCH_MSG = 46;
1349    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1350    static final int DISMISS_DIALOG_MSG = 48;
1351    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1352    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1353    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1354    static final int DELETE_DUMPHEAP_MSG = 52;
1355    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1356    static final int DISPATCH_UIDS_CHANGED_MSG = 54;
1357    static final int REPORT_TIME_TRACKER_MSG = 55;
1358    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1359    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1360
1361    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1362    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1363    static final int FIRST_COMPAT_MODE_MSG = 300;
1364    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1365
1366    CompatModeDialog mCompatModeDialog;
1367    long mLastMemUsageReportTime = 0;
1368
1369    /**
1370     * Flag whether the current user is a "monkey", i.e. whether
1371     * the UI is driven by a UI automation tool.
1372     */
1373    private boolean mUserIsMonkey;
1374
1375    /** Flag whether the device has a Recents UI */
1376    boolean mHasRecents;
1377
1378    /** The dimensions of the thumbnails in the Recents UI. */
1379    int mThumbnailWidth;
1380    int mThumbnailHeight;
1381
1382    final ServiceThread mHandlerThread;
1383    final MainHandler mHandler;
1384    final UiHandler mUiHandler;
1385
1386    final class UiHandler extends Handler {
1387        public UiHandler() {
1388            super(com.android.server.UiThread.get().getLooper(), null, true);
1389        }
1390
1391        @Override
1392        public void handleMessage(Message msg) {
1393            switch (msg.what) {
1394            case SHOW_ERROR_MSG: {
1395                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1396                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1397                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1398                synchronized (ActivityManagerService.this) {
1399                    ProcessRecord proc = (ProcessRecord)data.get("app");
1400                    AppErrorResult res = (AppErrorResult) data.get("result");
1401                    if (proc != null && proc.crashDialog != null) {
1402                        Slog.e(TAG, "App already has crash dialog: " + proc);
1403                        if (res != null) {
1404                            res.set(0);
1405                        }
1406                        return;
1407                    }
1408                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1409                            >= Process.FIRST_APPLICATION_UID
1410                            && proc.pid != MY_PID);
1411                    for (int userId : mCurrentProfileIds) {
1412                        isBackground &= (proc.userId != userId);
1413                    }
1414                    if (isBackground && !showBackground) {
1415                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1416                        if (res != null) {
1417                            res.set(0);
1418                        }
1419                        return;
1420                    }
1421                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1422                        Dialog d = new AppErrorDialog(mContext,
1423                                ActivityManagerService.this, res, proc);
1424                        d.show();
1425                        proc.crashDialog = d;
1426                    } else {
1427                        // The device is asleep, so just pretend that the user
1428                        // saw a crash dialog and hit "force quit".
1429                        if (res != null) {
1430                            res.set(0);
1431                        }
1432                    }
1433                }
1434
1435                ensureBootCompleted();
1436            } break;
1437            case SHOW_NOT_RESPONDING_MSG: {
1438                synchronized (ActivityManagerService.this) {
1439                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1440                    ProcessRecord proc = (ProcessRecord)data.get("app");
1441                    if (proc != null && proc.anrDialog != null) {
1442                        Slog.e(TAG, "App already has anr dialog: " + proc);
1443                        return;
1444                    }
1445
1446                    Intent intent = new Intent("android.intent.action.ANR");
1447                    if (!mProcessesReady) {
1448                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1449                                | Intent.FLAG_RECEIVER_FOREGROUND);
1450                    }
1451                    broadcastIntentLocked(null, null, intent,
1452                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1453                            null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1454
1455                    if (mShowDialogs) {
1456                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1457                                mContext, proc, (ActivityRecord)data.get("activity"),
1458                                msg.arg1 != 0);
1459                        d.show();
1460                        proc.anrDialog = d;
1461                    } else {
1462                        // Just kill the app if there is no dialog to be shown.
1463                        killAppAtUsersRequest(proc, null);
1464                    }
1465                }
1466
1467                ensureBootCompleted();
1468            } break;
1469            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1470                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1471                synchronized (ActivityManagerService.this) {
1472                    ProcessRecord proc = (ProcessRecord) data.get("app");
1473                    if (proc == null) {
1474                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1475                        break;
1476                    }
1477                    if (proc.crashDialog != null) {
1478                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1479                        return;
1480                    }
1481                    AppErrorResult res = (AppErrorResult) data.get("result");
1482                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1483                        Dialog d = new StrictModeViolationDialog(mContext,
1484                                ActivityManagerService.this, res, proc);
1485                        d.show();
1486                        proc.crashDialog = d;
1487                    } else {
1488                        // The device is asleep, so just pretend that the user
1489                        // saw a crash dialog and hit "force quit".
1490                        res.set(0);
1491                    }
1492                }
1493                ensureBootCompleted();
1494            } break;
1495            case SHOW_FACTORY_ERROR_MSG: {
1496                Dialog d = new FactoryErrorDialog(
1497                    mContext, msg.getData().getCharSequence("msg"));
1498                d.show();
1499                ensureBootCompleted();
1500            } break;
1501            case WAIT_FOR_DEBUGGER_MSG: {
1502                synchronized (ActivityManagerService.this) {
1503                    ProcessRecord app = (ProcessRecord)msg.obj;
1504                    if (msg.arg1 != 0) {
1505                        if (!app.waitedForDebugger) {
1506                            Dialog d = new AppWaitingForDebuggerDialog(
1507                                    ActivityManagerService.this,
1508                                    mContext, app);
1509                            app.waitDialog = d;
1510                            app.waitedForDebugger = true;
1511                            d.show();
1512                        }
1513                    } else {
1514                        if (app.waitDialog != null) {
1515                            app.waitDialog.dismiss();
1516                            app.waitDialog = null;
1517                        }
1518                    }
1519                }
1520            } break;
1521            case SHOW_UID_ERROR_MSG: {
1522                if (mShowDialogs) {
1523                    AlertDialog d = new BaseErrorDialog(mContext);
1524                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1525                    d.setCancelable(false);
1526                    d.setTitle(mContext.getText(R.string.android_system_label));
1527                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1528                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1529                            obtainMessage(DISMISS_DIALOG_MSG, d));
1530                    d.show();
1531                }
1532            } break;
1533            case SHOW_FINGERPRINT_ERROR_MSG: {
1534                if (mShowDialogs) {
1535                    AlertDialog d = new BaseErrorDialog(mContext);
1536                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1537                    d.setCancelable(false);
1538                    d.setTitle(mContext.getText(R.string.android_system_label));
1539                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1540                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1541                            obtainMessage(DISMISS_DIALOG_MSG, d));
1542                    d.show();
1543                }
1544            } break;
1545            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1546                synchronized (ActivityManagerService.this) {
1547                    ActivityRecord ar = (ActivityRecord) msg.obj;
1548                    if (mCompatModeDialog != null) {
1549                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1550                                ar.info.applicationInfo.packageName)) {
1551                            return;
1552                        }
1553                        mCompatModeDialog.dismiss();
1554                        mCompatModeDialog = null;
1555                    }
1556                    if (ar != null && false) {
1557                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1558                                ar.packageName)) {
1559                            int mode = mCompatModePackages.computeCompatModeLocked(
1560                                    ar.info.applicationInfo);
1561                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1562                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1563                                mCompatModeDialog = new CompatModeDialog(
1564                                        ActivityManagerService.this, mContext,
1565                                        ar.info.applicationInfo);
1566                                mCompatModeDialog.show();
1567                            }
1568                        }
1569                    }
1570                }
1571                break;
1572            }
1573            case START_USER_SWITCH_MSG: {
1574                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1575                break;
1576            }
1577            case DISMISS_DIALOG_MSG: {
1578                final Dialog d = (Dialog) msg.obj;
1579                d.dismiss();
1580                break;
1581            }
1582            case DISPATCH_PROCESSES_CHANGED: {
1583                dispatchProcessesChanged();
1584                break;
1585            }
1586            case DISPATCH_PROCESS_DIED: {
1587                final int pid = msg.arg1;
1588                final int uid = msg.arg2;
1589                dispatchProcessDied(pid, uid);
1590                break;
1591            }
1592            case DISPATCH_UIDS_CHANGED_MSG: {
1593                dispatchUidsChanged();
1594            } break;
1595            }
1596        }
1597    }
1598
1599    final class MainHandler extends Handler {
1600        public MainHandler(Looper looper) {
1601            super(looper, null, true);
1602        }
1603
1604        @Override
1605        public void handleMessage(Message msg) {
1606            switch (msg.what) {
1607            case UPDATE_CONFIGURATION_MSG: {
1608                final ContentResolver resolver = mContext.getContentResolver();
1609                Settings.System.putConfiguration(resolver, (Configuration) msg.obj);
1610            } break;
1611            case GC_BACKGROUND_PROCESSES_MSG: {
1612                synchronized (ActivityManagerService.this) {
1613                    performAppGcsIfAppropriateLocked();
1614                }
1615            } break;
1616            case SERVICE_TIMEOUT_MSG: {
1617                if (mDidDexOpt) {
1618                    mDidDexOpt = false;
1619                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1620                    nmsg.obj = msg.obj;
1621                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1622                    return;
1623                }
1624                mServices.serviceTimeout((ProcessRecord)msg.obj);
1625            } break;
1626            case UPDATE_TIME_ZONE: {
1627                synchronized (ActivityManagerService.this) {
1628                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1629                        ProcessRecord r = mLruProcesses.get(i);
1630                        if (r.thread != null) {
1631                            try {
1632                                r.thread.updateTimeZone();
1633                            } catch (RemoteException ex) {
1634                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1635                            }
1636                        }
1637                    }
1638                }
1639            } break;
1640            case CLEAR_DNS_CACHE_MSG: {
1641                synchronized (ActivityManagerService.this) {
1642                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1643                        ProcessRecord r = mLruProcesses.get(i);
1644                        if (r.thread != null) {
1645                            try {
1646                                r.thread.clearDnsCache();
1647                            } catch (RemoteException ex) {
1648                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1649                            }
1650                        }
1651                    }
1652                }
1653            } break;
1654            case UPDATE_HTTP_PROXY_MSG: {
1655                ProxyInfo proxy = (ProxyInfo)msg.obj;
1656                String host = "";
1657                String port = "";
1658                String exclList = "";
1659                Uri pacFileUrl = Uri.EMPTY;
1660                if (proxy != null) {
1661                    host = proxy.getHost();
1662                    port = Integer.toString(proxy.getPort());
1663                    exclList = proxy.getExclusionListAsString();
1664                    pacFileUrl = proxy.getPacFileUrl();
1665                }
1666                synchronized (ActivityManagerService.this) {
1667                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1668                        ProcessRecord r = mLruProcesses.get(i);
1669                        if (r.thread != null) {
1670                            try {
1671                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1672                            } catch (RemoteException ex) {
1673                                Slog.w(TAG, "Failed to update http proxy for: " +
1674                                        r.info.processName);
1675                            }
1676                        }
1677                    }
1678                }
1679            } break;
1680            case PROC_START_TIMEOUT_MSG: {
1681                if (mDidDexOpt) {
1682                    mDidDexOpt = false;
1683                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1684                    nmsg.obj = msg.obj;
1685                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1686                    return;
1687                }
1688                ProcessRecord app = (ProcessRecord)msg.obj;
1689                synchronized (ActivityManagerService.this) {
1690                    processStartTimedOutLocked(app);
1691                }
1692            } break;
1693            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1694                synchronized (ActivityManagerService.this) {
1695                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1696                }
1697            } break;
1698            case KILL_APPLICATION_MSG: {
1699                synchronized (ActivityManagerService.this) {
1700                    int appid = msg.arg1;
1701                    boolean restart = (msg.arg2 == 1);
1702                    Bundle bundle = (Bundle)msg.obj;
1703                    String pkg = bundle.getString("pkg");
1704                    String reason = bundle.getString("reason");
1705                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1706                            false, UserHandle.USER_ALL, reason);
1707                }
1708            } break;
1709            case FINALIZE_PENDING_INTENT_MSG: {
1710                ((PendingIntentRecord)msg.obj).completeFinalize();
1711            } break;
1712            case POST_HEAVY_NOTIFICATION_MSG: {
1713                INotificationManager inm = NotificationManager.getService();
1714                if (inm == null) {
1715                    return;
1716                }
1717
1718                ActivityRecord root = (ActivityRecord)msg.obj;
1719                ProcessRecord process = root.app;
1720                if (process == null) {
1721                    return;
1722                }
1723
1724                try {
1725                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1726                    String text = mContext.getString(R.string.heavy_weight_notification,
1727                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1728                    Notification notification = new Notification.Builder(context)
1729                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1730                            .setWhen(0)
1731                            .setOngoing(true)
1732                            .setTicker(text)
1733                            .setColor(mContext.getColor(
1734                                    com.android.internal.R.color.system_notification_accent_color))
1735                            .setContentTitle(text)
1736                            .setContentText(
1737                                    mContext.getText(R.string.heavy_weight_notification_detail))
1738                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1739                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1740                                    new UserHandle(root.userId)))
1741                            .build();
1742                    try {
1743                        int[] outId = new int[1];
1744                        inm.enqueueNotificationWithTag("android", "android", null,
1745                                R.string.heavy_weight_notification,
1746                                notification, outId, root.userId);
1747                    } catch (RuntimeException e) {
1748                        Slog.w(ActivityManagerService.TAG,
1749                                "Error showing notification for heavy-weight app", e);
1750                    } catch (RemoteException e) {
1751                    }
1752                } catch (NameNotFoundException e) {
1753                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1754                }
1755            } break;
1756            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1757                INotificationManager inm = NotificationManager.getService();
1758                if (inm == null) {
1759                    return;
1760                }
1761                try {
1762                    inm.cancelNotificationWithTag("android", null,
1763                            R.string.heavy_weight_notification,  msg.arg1);
1764                } catch (RuntimeException e) {
1765                    Slog.w(ActivityManagerService.TAG,
1766                            "Error canceling notification for service", e);
1767                } catch (RemoteException e) {
1768                }
1769            } break;
1770            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1771                synchronized (ActivityManagerService.this) {
1772                    checkExcessivePowerUsageLocked(true);
1773                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1774                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1775                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1776                }
1777            } break;
1778            case REPORT_MEM_USAGE_MSG: {
1779                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1780                Thread thread = new Thread() {
1781                    @Override public void run() {
1782                        reportMemUsage(memInfos);
1783                    }
1784                };
1785                thread.start();
1786                break;
1787            }
1788            case REPORT_USER_SWITCH_MSG: {
1789                dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1790                break;
1791            }
1792            case CONTINUE_USER_SWITCH_MSG: {
1793                continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1794                break;
1795            }
1796            case USER_SWITCH_TIMEOUT_MSG: {
1797                timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1798                break;
1799            }
1800            case IMMERSIVE_MODE_LOCK_MSG: {
1801                final boolean nextState = (msg.arg1 != 0);
1802                if (mUpdateLock.isHeld() != nextState) {
1803                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1804                            "Applying new update lock state '" + nextState
1805                            + "' for " + (ActivityRecord)msg.obj);
1806                    if (nextState) {
1807                        mUpdateLock.acquire();
1808                    } else {
1809                        mUpdateLock.release();
1810                    }
1811                }
1812                break;
1813            }
1814            case PERSIST_URI_GRANTS_MSG: {
1815                writeGrantedUriPermissions();
1816                break;
1817            }
1818            case REQUEST_ALL_PSS_MSG: {
1819                synchronized (ActivityManagerService.this) {
1820                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1821                }
1822                break;
1823            }
1824            case START_PROFILES_MSG: {
1825                synchronized (ActivityManagerService.this) {
1826                    startProfilesLocked();
1827                }
1828                break;
1829            }
1830            case UPDATE_TIME: {
1831                synchronized (ActivityManagerService.this) {
1832                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1833                        ProcessRecord r = mLruProcesses.get(i);
1834                        if (r.thread != null) {
1835                            try {
1836                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1837                            } catch (RemoteException ex) {
1838                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1839                            }
1840                        }
1841                    }
1842                }
1843                break;
1844            }
1845            case SYSTEM_USER_START_MSG: {
1846                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1847                        Integer.toString(msg.arg1), msg.arg1);
1848                mSystemServiceManager.startUser(msg.arg1);
1849                break;
1850            }
1851            case SYSTEM_USER_CURRENT_MSG: {
1852                mBatteryStatsService.noteEvent(
1853                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1854                        Integer.toString(msg.arg2), msg.arg2);
1855                mBatteryStatsService.noteEvent(
1856                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1857                        Integer.toString(msg.arg1), msg.arg1);
1858                mSystemServiceManager.switchUser(msg.arg1);
1859                break;
1860            }
1861            case ENTER_ANIMATION_COMPLETE_MSG: {
1862                synchronized (ActivityManagerService.this) {
1863                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1864                    if (r != null && r.app != null && r.app.thread != null) {
1865                        try {
1866                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1867                        } catch (RemoteException e) {
1868                        }
1869                    }
1870                }
1871                break;
1872            }
1873            case FINISH_BOOTING_MSG: {
1874                if (msg.arg1 != 0) {
1875                    finishBooting();
1876                }
1877                if (msg.arg2 != 0) {
1878                    enableScreenAfterBoot();
1879                }
1880                break;
1881            }
1882            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1883                try {
1884                    Locale l = (Locale) msg.obj;
1885                    IBinder service = ServiceManager.getService("mount");
1886                    IMountService mountService = IMountService.Stub.asInterface(service);
1887                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1888                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1889                } catch (RemoteException e) {
1890                    Log.e(TAG, "Error storing locale for decryption UI", e);
1891                }
1892                break;
1893            }
1894            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1895                synchronized (ActivityManagerService.this) {
1896                    int i = mTaskStackListeners.beginBroadcast();
1897                    while (i > 0) {
1898                        i--;
1899                        try {
1900                            // Make a one-way callback to the listener
1901                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1902                        } catch (RemoteException e){
1903                            // Handled by the RemoteCallbackList
1904                        }
1905                    }
1906                    mTaskStackListeners.finishBroadcast();
1907                }
1908                break;
1909            }
1910            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1911                final int uid = msg.arg1;
1912                final byte[] firstPacket = (byte[]) msg.obj;
1913
1914                synchronized (mPidsSelfLocked) {
1915                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
1916                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
1917                        if (p.uid == uid) {
1918                            try {
1919                                p.thread.notifyCleartextNetwork(firstPacket);
1920                            } catch (RemoteException ignored) {
1921                            }
1922                        }
1923                    }
1924                }
1925                break;
1926            }
1927            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
1928                final String procName;
1929                final int uid;
1930                final long memLimit;
1931                final String reportPackage;
1932                synchronized (ActivityManagerService.this) {
1933                    procName = mMemWatchDumpProcName;
1934                    uid = mMemWatchDumpUid;
1935                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
1936                    if (val == null) {
1937                        val = mMemWatchProcesses.get(procName, 0);
1938                    }
1939                    if (val != null) {
1940                        memLimit = val.first;
1941                        reportPackage = val.second;
1942                    } else {
1943                        memLimit = 0;
1944                        reportPackage = null;
1945                    }
1946                }
1947                if (procName == null) {
1948                    return;
1949                }
1950
1951                if (DEBUG_PSS) Slog.d(TAG_PSS,
1952                        "Showing dump heap notification from " + procName + "/" + uid);
1953
1954                INotificationManager inm = NotificationManager.getService();
1955                if (inm == null) {
1956                    return;
1957                }
1958
1959                String text = mContext.getString(R.string.dump_heap_notification, procName);
1960
1961
1962                Intent deleteIntent = new Intent();
1963                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
1964                Intent intent = new Intent();
1965                intent.setClassName("android", DumpHeapActivity.class.getName());
1966                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
1967                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
1968                if (reportPackage != null) {
1969                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
1970                }
1971                int userId = UserHandle.getUserId(uid);
1972                Notification notification = new Notification.Builder(mContext)
1973                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1974                        .setWhen(0)
1975                        .setOngoing(true)
1976                        .setAutoCancel(true)
1977                        .setTicker(text)
1978                        .setColor(mContext.getColor(
1979                                com.android.internal.R.color.system_notification_accent_color))
1980                        .setContentTitle(text)
1981                        .setContentText(
1982                                mContext.getText(R.string.dump_heap_notification_detail))
1983                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1984                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1985                                new UserHandle(userId)))
1986                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
1987                                deleteIntent, 0, UserHandle.OWNER))
1988                        .build();
1989
1990                try {
1991                    int[] outId = new int[1];
1992                    inm.enqueueNotificationWithTag("android", "android", null,
1993                            R.string.dump_heap_notification,
1994                            notification, outId, userId);
1995                } catch (RuntimeException e) {
1996                    Slog.w(ActivityManagerService.TAG,
1997                            "Error showing notification for dump heap", e);
1998                } catch (RemoteException e) {
1999                }
2000            } break;
2001            case DELETE_DUMPHEAP_MSG: {
2002                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2003                        DumpHeapActivity.JAVA_URI,
2004                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2005                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2006                        UserHandle.myUserId());
2007                synchronized (ActivityManagerService.this) {
2008                    mMemWatchDumpFile = null;
2009                    mMemWatchDumpProcName = null;
2010                    mMemWatchDumpPid = -1;
2011                    mMemWatchDumpUid = -1;
2012                }
2013            } break;
2014            case FOREGROUND_PROFILE_CHANGED_MSG: {
2015                dispatchForegroundProfileChanged(msg.arg1);
2016            } break;
2017            case REPORT_TIME_TRACKER_MSG: {
2018                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2019                tracker.deliverResult(mContext);
2020            } break;
2021            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2022                dispatchUserSwitchComplete(msg.arg1);
2023            } break;
2024            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2025                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2026                try {
2027                    connection.shutdown();
2028                } catch (RemoteException e) {
2029                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2030                }
2031                // Only a UiAutomation can set this flag and now that
2032                // it is finished we make sure it is reset to its default.
2033                mUserIsMonkey = false;
2034            } break;
2035            }
2036        }
2037    };
2038
2039    static final int COLLECT_PSS_BG_MSG = 1;
2040
2041    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2042        @Override
2043        public void handleMessage(Message msg) {
2044            switch (msg.what) {
2045            case COLLECT_PSS_BG_MSG: {
2046                long start = SystemClock.uptimeMillis();
2047                MemInfoReader memInfo = null;
2048                synchronized (ActivityManagerService.this) {
2049                    if (mFullPssPending) {
2050                        mFullPssPending = false;
2051                        memInfo = new MemInfoReader();
2052                    }
2053                }
2054                if (memInfo != null) {
2055                    updateCpuStatsNow();
2056                    long nativeTotalPss = 0;
2057                    synchronized (mProcessCpuTracker) {
2058                        final int N = mProcessCpuTracker.countStats();
2059                        for (int j=0; j<N; j++) {
2060                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2061                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2062                                // This is definitely an application process; skip it.
2063                                continue;
2064                            }
2065                            synchronized (mPidsSelfLocked) {
2066                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2067                                    // This is one of our own processes; skip it.
2068                                    continue;
2069                                }
2070                            }
2071                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2072                        }
2073                    }
2074                    memInfo.readMemInfo();
2075                    synchronized (ActivityManagerService.this) {
2076                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2077                                + (SystemClock.uptimeMillis()-start) + "ms");
2078                        final long cachedKb = memInfo.getCachedSizeKb();
2079                        final long freeKb = memInfo.getFreeSizeKb();
2080                        final long zramKb = memInfo.getZramTotalSizeKb();
2081                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2082                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2083                                kernelKb*1024, nativeTotalPss*1024);
2084                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2085                                nativeTotalPss);
2086                    }
2087                }
2088
2089                int num = 0;
2090                long[] tmp = new long[1];
2091                do {
2092                    ProcessRecord proc;
2093                    int procState;
2094                    int pid;
2095                    long lastPssTime;
2096                    synchronized (ActivityManagerService.this) {
2097                        if (mPendingPssProcesses.size() <= 0) {
2098                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2099                                    "Collected PSS of " + num + " processes in "
2100                                    + (SystemClock.uptimeMillis() - start) + "ms");
2101                            mPendingPssProcesses.clear();
2102                            return;
2103                        }
2104                        proc = mPendingPssProcesses.remove(0);
2105                        procState = proc.pssProcState;
2106                        lastPssTime = proc.lastPssTime;
2107                        if (proc.thread != null && procState == proc.setProcState
2108                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2109                                        < SystemClock.uptimeMillis()) {
2110                            pid = proc.pid;
2111                        } else {
2112                            proc = null;
2113                            pid = 0;
2114                        }
2115                    }
2116                    if (proc != null) {
2117                        long pss = Debug.getPss(pid, tmp, null);
2118                        synchronized (ActivityManagerService.this) {
2119                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2120                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2121                                num++;
2122                                recordPssSampleLocked(proc, procState, pss, tmp[0],
2123                                        SystemClock.uptimeMillis());
2124                            }
2125                        }
2126                    }
2127                } while (true);
2128            }
2129            }
2130        }
2131    };
2132
2133    public void setSystemProcess() {
2134        try {
2135            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2136            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2137            ServiceManager.addService("meminfo", new MemBinder(this));
2138            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2139            ServiceManager.addService("dbinfo", new DbBinder(this));
2140            if (MONITOR_CPU_USAGE) {
2141                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2142            }
2143            ServiceManager.addService("permission", new PermissionController(this));
2144            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2145
2146            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2147                    "android", STOCK_PM_FLAGS);
2148            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2149
2150            synchronized (this) {
2151                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2152                app.persistent = true;
2153                app.pid = MY_PID;
2154                app.maxAdj = ProcessList.SYSTEM_ADJ;
2155                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2156                synchronized (mPidsSelfLocked) {
2157                    mPidsSelfLocked.put(app.pid, app);
2158                }
2159                updateLruProcessLocked(app, false, null);
2160                updateOomAdjLocked();
2161            }
2162        } catch (PackageManager.NameNotFoundException e) {
2163            throw new RuntimeException(
2164                    "Unable to find android system package", e);
2165        }
2166    }
2167
2168    public void setWindowManager(WindowManagerService wm) {
2169        mWindowManager = wm;
2170        mStackSupervisor.setWindowManager(wm);
2171    }
2172
2173    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2174        mUsageStatsService = usageStatsManager;
2175    }
2176
2177    public void startObservingNativeCrashes() {
2178        final NativeCrashListener ncl = new NativeCrashListener(this);
2179        ncl.start();
2180    }
2181
2182    public IAppOpsService getAppOpsService() {
2183        return mAppOpsService;
2184    }
2185
2186    static class MemBinder extends Binder {
2187        ActivityManagerService mActivityManagerService;
2188        MemBinder(ActivityManagerService activityManagerService) {
2189            mActivityManagerService = activityManagerService;
2190        }
2191
2192        @Override
2193        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2194            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2195                    != PackageManager.PERMISSION_GRANTED) {
2196                pw.println("Permission Denial: can't dump meminfo from from pid="
2197                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2198                        + " without permission " + android.Manifest.permission.DUMP);
2199                return;
2200            }
2201
2202            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2203        }
2204    }
2205
2206    static class GraphicsBinder extends Binder {
2207        ActivityManagerService mActivityManagerService;
2208        GraphicsBinder(ActivityManagerService activityManagerService) {
2209            mActivityManagerService = activityManagerService;
2210        }
2211
2212        @Override
2213        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2214            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2215                    != PackageManager.PERMISSION_GRANTED) {
2216                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2217                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2218                        + " without permission " + android.Manifest.permission.DUMP);
2219                return;
2220            }
2221
2222            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2223        }
2224    }
2225
2226    static class DbBinder extends Binder {
2227        ActivityManagerService mActivityManagerService;
2228        DbBinder(ActivityManagerService activityManagerService) {
2229            mActivityManagerService = activityManagerService;
2230        }
2231
2232        @Override
2233        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2234            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2235                    != PackageManager.PERMISSION_GRANTED) {
2236                pw.println("Permission Denial: can't dump dbinfo from from pid="
2237                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2238                        + " without permission " + android.Manifest.permission.DUMP);
2239                return;
2240            }
2241
2242            mActivityManagerService.dumpDbInfo(fd, pw, args);
2243        }
2244    }
2245
2246    static class CpuBinder extends Binder {
2247        ActivityManagerService mActivityManagerService;
2248        CpuBinder(ActivityManagerService activityManagerService) {
2249            mActivityManagerService = activityManagerService;
2250        }
2251
2252        @Override
2253        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2254            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2255                    != PackageManager.PERMISSION_GRANTED) {
2256                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2257                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2258                        + " without permission " + android.Manifest.permission.DUMP);
2259                return;
2260            }
2261
2262            synchronized (mActivityManagerService.mProcessCpuTracker) {
2263                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2264                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2265                        SystemClock.uptimeMillis()));
2266            }
2267        }
2268    }
2269
2270    public static final class Lifecycle extends SystemService {
2271        private final ActivityManagerService mService;
2272
2273        public Lifecycle(Context context) {
2274            super(context);
2275            mService = new ActivityManagerService(context);
2276        }
2277
2278        @Override
2279        public void onStart() {
2280            mService.start();
2281        }
2282
2283        public ActivityManagerService getService() {
2284            return mService;
2285        }
2286    }
2287
2288    // Note: This method is invoked on the main thread but may need to attach various
2289    // handlers to other threads.  So take care to be explicit about the looper.
2290    public ActivityManagerService(Context systemContext) {
2291        mContext = systemContext;
2292        mFactoryTest = FactoryTest.getMode();
2293        mSystemThread = ActivityThread.currentActivityThread();
2294
2295        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2296
2297        mHandlerThread = new ServiceThread(TAG,
2298                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2299        mHandlerThread.start();
2300        mHandler = new MainHandler(mHandlerThread.getLooper());
2301        mUiHandler = new UiHandler();
2302
2303        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2304                "foreground", BROADCAST_FG_TIMEOUT, false);
2305        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2306                "background", BROADCAST_BG_TIMEOUT, true);
2307        mBroadcastQueues[0] = mFgBroadcastQueue;
2308        mBroadcastQueues[1] = mBgBroadcastQueue;
2309
2310        mServices = new ActiveServices(this);
2311        mProviderMap = new ProviderMap(this);
2312
2313        // TODO: Move creation of battery stats service outside of activity manager service.
2314        File dataDir = Environment.getDataDirectory();
2315        File systemDir = new File(dataDir, "system");
2316        systemDir.mkdirs();
2317        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2318        mBatteryStatsService.getActiveStatistics().readLocked();
2319        mBatteryStatsService.scheduleWriteToDisk();
2320        mOnBattery = DEBUG_POWER ? true
2321                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2322        mBatteryStatsService.getActiveStatistics().setCallback(this);
2323
2324        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2325
2326        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2327
2328        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2329
2330        // User 0 is the first and only user that runs at boot.
2331        mStartedUsers.put(UserHandle.USER_OWNER, new UserState(UserHandle.OWNER, true));
2332        mUserLru.add(UserHandle.USER_OWNER);
2333        updateStartedUserArrayLocked();
2334
2335        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2336            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2337
2338        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2339
2340        mConfiguration.setToDefaults();
2341        mConfiguration.setLocale(Locale.getDefault());
2342
2343        mConfigurationSeq = mConfiguration.seq = 1;
2344        mProcessCpuTracker.init();
2345
2346        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2347        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2348        mRecentTasks = new RecentTasks(this);
2349        mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
2350        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
2351
2352        mProcessCpuThread = new Thread("CpuTracker") {
2353            @Override
2354            public void run() {
2355                while (true) {
2356                    try {
2357                        try {
2358                            synchronized(this) {
2359                                final long now = SystemClock.uptimeMillis();
2360                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2361                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2362                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2363                                //        + ", write delay=" + nextWriteDelay);
2364                                if (nextWriteDelay < nextCpuDelay) {
2365                                    nextCpuDelay = nextWriteDelay;
2366                                }
2367                                if (nextCpuDelay > 0) {
2368                                    mProcessCpuMutexFree.set(true);
2369                                    this.wait(nextCpuDelay);
2370                                }
2371                            }
2372                        } catch (InterruptedException e) {
2373                        }
2374                        updateCpuStatsNow();
2375                    } catch (Exception e) {
2376                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2377                    }
2378                }
2379            }
2380        };
2381
2382        Watchdog.getInstance().addMonitor(this);
2383        Watchdog.getInstance().addThread(mHandler);
2384    }
2385
2386    public void setSystemServiceManager(SystemServiceManager mgr) {
2387        mSystemServiceManager = mgr;
2388    }
2389
2390    public void setInstaller(Installer installer) {
2391        mInstaller = installer;
2392    }
2393
2394    private void start() {
2395        Process.removeAllProcessGroups();
2396        mProcessCpuThread.start();
2397
2398        mBatteryStatsService.publish(mContext);
2399        mAppOpsService.publish(mContext);
2400        Slog.d("AppOps", "AppOpsService published");
2401        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2402    }
2403
2404    public void initPowerManagement() {
2405        mStackSupervisor.initPowerManagement();
2406        mBatteryStatsService.initPowerManagement();
2407        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2408        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2409        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2410        mVoiceWakeLock.setReferenceCounted(false);
2411    }
2412
2413    @Override
2414    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2415            throws RemoteException {
2416        if (code == SYSPROPS_TRANSACTION) {
2417            // We need to tell all apps about the system property change.
2418            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2419            synchronized(this) {
2420                final int NP = mProcessNames.getMap().size();
2421                for (int ip=0; ip<NP; ip++) {
2422                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2423                    final int NA = apps.size();
2424                    for (int ia=0; ia<NA; ia++) {
2425                        ProcessRecord app = apps.valueAt(ia);
2426                        if (app.thread != null) {
2427                            procs.add(app.thread.asBinder());
2428                        }
2429                    }
2430                }
2431            }
2432
2433            int N = procs.size();
2434            for (int i=0; i<N; i++) {
2435                Parcel data2 = Parcel.obtain();
2436                try {
2437                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2438                } catch (RemoteException e) {
2439                }
2440                data2.recycle();
2441            }
2442        }
2443        try {
2444            return super.onTransact(code, data, reply, flags);
2445        } catch (RuntimeException e) {
2446            // The activity manager only throws security exceptions, so let's
2447            // log all others.
2448            if (!(e instanceof SecurityException)) {
2449                Slog.wtf(TAG, "Activity Manager Crash", e);
2450            }
2451            throw e;
2452        }
2453    }
2454
2455    void updateCpuStats() {
2456        final long now = SystemClock.uptimeMillis();
2457        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2458            return;
2459        }
2460        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2461            synchronized (mProcessCpuThread) {
2462                mProcessCpuThread.notify();
2463            }
2464        }
2465    }
2466
2467    void updateCpuStatsNow() {
2468        synchronized (mProcessCpuTracker) {
2469            mProcessCpuMutexFree.set(false);
2470            final long now = SystemClock.uptimeMillis();
2471            boolean haveNewCpuStats = false;
2472
2473            if (MONITOR_CPU_USAGE &&
2474                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2475                mLastCpuTime.set(now);
2476                mProcessCpuTracker.update();
2477                if (mProcessCpuTracker.hasGoodLastStats()) {
2478                    haveNewCpuStats = true;
2479                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2480                    //Slog.i(TAG, "Total CPU usage: "
2481                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2482
2483                    // Slog the cpu usage if the property is set.
2484                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2485                        int user = mProcessCpuTracker.getLastUserTime();
2486                        int system = mProcessCpuTracker.getLastSystemTime();
2487                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2488                        int irq = mProcessCpuTracker.getLastIrqTime();
2489                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2490                        int idle = mProcessCpuTracker.getLastIdleTime();
2491
2492                        int total = user + system + iowait + irq + softIrq + idle;
2493                        if (total == 0) total = 1;
2494
2495                        EventLog.writeEvent(EventLogTags.CPU,
2496                                ((user+system+iowait+irq+softIrq) * 100) / total,
2497                                (user * 100) / total,
2498                                (system * 100) / total,
2499                                (iowait * 100) / total,
2500                                (irq * 100) / total,
2501                                (softIrq * 100) / total);
2502                    }
2503                }
2504            }
2505
2506            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2507            synchronized(bstats) {
2508                synchronized(mPidsSelfLocked) {
2509                    if (haveNewCpuStats) {
2510                        if (bstats.startAddingCpuLocked()) {
2511                            int totalUTime = 0;
2512                            int totalSTime = 0;
2513                            final int N = mProcessCpuTracker.countStats();
2514                            for (int i=0; i<N; i++) {
2515                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2516                                if (!st.working) {
2517                                    continue;
2518                                }
2519                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2520                                totalUTime += st.rel_utime;
2521                                totalSTime += st.rel_stime;
2522                                if (pr != null) {
2523                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2524                                    if (ps == null || !ps.isActive()) {
2525                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2526                                                pr.info.uid, pr.processName);
2527                                    }
2528                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2529                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2530                                } else {
2531                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2532                                    if (ps == null || !ps.isActive()) {
2533                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2534                                                bstats.mapUid(st.uid), st.name);
2535                                    }
2536                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2537                                }
2538                            }
2539                            final int userTime = mProcessCpuTracker.getLastUserTime();
2540                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2541                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2542                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2543                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2544                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2545                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2546                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2547                        }
2548                    }
2549                }
2550
2551                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2552                    mLastWriteTime = now;
2553                    mBatteryStatsService.scheduleWriteToDisk();
2554                }
2555            }
2556        }
2557    }
2558
2559    @Override
2560    public void batteryNeedsCpuUpdate() {
2561        updateCpuStatsNow();
2562    }
2563
2564    @Override
2565    public void batteryPowerChanged(boolean onBattery) {
2566        // When plugging in, update the CPU stats first before changing
2567        // the plug state.
2568        updateCpuStatsNow();
2569        synchronized (this) {
2570            synchronized(mPidsSelfLocked) {
2571                mOnBattery = DEBUG_POWER ? true : onBattery;
2572            }
2573        }
2574    }
2575
2576    @Override
2577    public void batterySendBroadcast(Intent intent) {
2578        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2579                AppOpsManager.OP_NONE, null, false, false,
2580                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2581    }
2582
2583    /**
2584     * Initialize the application bind args. These are passed to each
2585     * process when the bindApplication() IPC is sent to the process. They're
2586     * lazily setup to make sure the services are running when they're asked for.
2587     */
2588    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2589        if (mAppBindArgs == null) {
2590            mAppBindArgs = new HashMap<>();
2591
2592            // Isolated processes won't get this optimization, so that we don't
2593            // violate the rules about which services they have access to.
2594            if (!isolated) {
2595                // Setup the application init args
2596                mAppBindArgs.put("package", ServiceManager.getService("package"));
2597                mAppBindArgs.put("window", ServiceManager.getService("window"));
2598                mAppBindArgs.put(Context.ALARM_SERVICE,
2599                        ServiceManager.getService(Context.ALARM_SERVICE));
2600            }
2601        }
2602        return mAppBindArgs;
2603    }
2604
2605    final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2606        if (r != null && mFocusedActivity != r) {
2607            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2608            ActivityRecord last = mFocusedActivity;
2609            mFocusedActivity = r;
2610            if (r.task.taskType != ActivityRecord.HOME_ACTIVITY_TYPE
2611                    && r.task.taskType != ActivityRecord.RECENTS_ACTIVITY_TYPE) {
2612                if (mCurAppTimeTracker != r.appTimeTracker) {
2613                    // We are switching app tracking.  Complete the current one.
2614                    if (mCurAppTimeTracker != null) {
2615                        mCurAppTimeTracker.stop();
2616                        mHandler.obtainMessage(REPORT_TIME_TRACKER_MSG,
2617                                mCurAppTimeTracker).sendToTarget();
2618                        mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2619                        mCurAppTimeTracker = null;
2620                    }
2621                    if (r.appTimeTracker != null) {
2622                        mCurAppTimeTracker = r.appTimeTracker;
2623                        startTimeTrackingFocusedActivityLocked();
2624                    }
2625                } else {
2626                    startTimeTrackingFocusedActivityLocked();
2627                }
2628            } else {
2629                r.appTimeTracker = null;
2630            }
2631            if (r.task != null && r.task.voiceInteractor != null) {
2632                startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2633            } else {
2634                finishRunningVoiceLocked();
2635                if (last != null && last.task.voiceSession != null) {
2636                    // We had been in a voice interaction session, but now focused has
2637                    // move to something different.  Just finish the session, we can't
2638                    // return to it and retain the proper state and synchronization with
2639                    // the voice interaction service.
2640                    finishVoiceTask(last.task.voiceSession);
2641                }
2642            }
2643            if (mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
2644                mWindowManager.setFocusedApp(r.appToken, true);
2645            }
2646            applyUpdateLockStateLocked(r);
2647            if (mFocusedActivity.userId != mLastFocusedUserId) {
2648                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2649                mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2650                        mFocusedActivity.userId, 0));
2651                mLastFocusedUserId = mFocusedActivity.userId;
2652            }
2653        }
2654        EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY,
2655                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2656                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2657    }
2658
2659    final void clearFocusedActivity(ActivityRecord r) {
2660        if (mFocusedActivity == r) {
2661            ActivityStack stack = mStackSupervisor.getFocusedStack();
2662            if (stack != null) {
2663                ActivityRecord top = stack.topActivity();
2664                if (top != null && top.userId != mLastFocusedUserId) {
2665                    mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2666                    mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2667                                    top.userId, 0));
2668                    mLastFocusedUserId = top.userId;
2669                }
2670            }
2671            mFocusedActivity = null;
2672            EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, -1, "NULL");
2673        }
2674    }
2675
2676    @Override
2677    public void setFocusedStack(int stackId) {
2678        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2679        synchronized (ActivityManagerService.this) {
2680            ActivityStack stack = mStackSupervisor.getStack(stackId);
2681            if (stack != null) {
2682                ActivityRecord r = stack.topRunningActivityLocked(null);
2683                if (r != null) {
2684                    setFocusedActivityLocked(r, "setFocusedStack");
2685                    mStackSupervisor.resumeTopActivitiesLocked(stack, null, null);
2686                }
2687            }
2688        }
2689    }
2690
2691    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2692    @Override
2693    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2694        synchronized (ActivityManagerService.this) {
2695            if (listener != null) {
2696                mTaskStackListeners.register(listener);
2697            }
2698        }
2699    }
2700
2701    @Override
2702    public void notifyActivityDrawn(IBinder token) {
2703        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2704        synchronized (this) {
2705            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2706            if (r != null) {
2707                r.task.stack.notifyActivityDrawnLocked(r);
2708            }
2709        }
2710    }
2711
2712    final void applyUpdateLockStateLocked(ActivityRecord r) {
2713        // Modifications to the UpdateLock state are done on our handler, outside
2714        // the activity manager's locks.  The new state is determined based on the
2715        // state *now* of the relevant activity record.  The object is passed to
2716        // the handler solely for logging detail, not to be consulted/modified.
2717        final boolean nextState = r != null && r.immersive;
2718        mHandler.sendMessage(
2719                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2720    }
2721
2722    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2723        Message msg = Message.obtain();
2724        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2725        msg.obj = r.task.askedCompatMode ? null : r;
2726        mUiHandler.sendMessage(msg);
2727    }
2728
2729    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2730            String what, Object obj, ProcessRecord srcApp) {
2731        app.lastActivityTime = now;
2732
2733        if (app.activities.size() > 0) {
2734            // Don't want to touch dependent processes that are hosting activities.
2735            return index;
2736        }
2737
2738        int lrui = mLruProcesses.lastIndexOf(app);
2739        if (lrui < 0) {
2740            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2741                    + what + " " + obj + " from " + srcApp);
2742            return index;
2743        }
2744
2745        if (lrui >= index) {
2746            // Don't want to cause this to move dependent processes *back* in the
2747            // list as if they were less frequently used.
2748            return index;
2749        }
2750
2751        if (lrui >= mLruProcessActivityStart) {
2752            // Don't want to touch dependent processes that are hosting activities.
2753            return index;
2754        }
2755
2756        mLruProcesses.remove(lrui);
2757        if (index > 0) {
2758            index--;
2759        }
2760        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2761                + " in LRU list: " + app);
2762        mLruProcesses.add(index, app);
2763        return index;
2764    }
2765
2766    private static void killProcessGroup(int uid, int pid) {
2767        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
2768        Process.killProcessGroup(uid, pid);
2769        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2770    }
2771
2772    final void removeLruProcessLocked(ProcessRecord app) {
2773        int lrui = mLruProcesses.lastIndexOf(app);
2774        if (lrui >= 0) {
2775            if (!app.killed) {
2776                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2777                Process.killProcessQuiet(app.pid);
2778                killProcessGroup(app.info.uid, app.pid);
2779            }
2780            if (lrui <= mLruProcessActivityStart) {
2781                mLruProcessActivityStart--;
2782            }
2783            if (lrui <= mLruProcessServiceStart) {
2784                mLruProcessServiceStart--;
2785            }
2786            mLruProcesses.remove(lrui);
2787        }
2788    }
2789
2790    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2791            ProcessRecord client) {
2792        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2793                || app.treatLikeActivity;
2794        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2795        if (!activityChange && hasActivity) {
2796            // The process has activities, so we are only allowing activity-based adjustments
2797            // to move it.  It should be kept in the front of the list with other
2798            // processes that have activities, and we don't want those to change their
2799            // order except due to activity operations.
2800            return;
2801        }
2802
2803        mLruSeq++;
2804        final long now = SystemClock.uptimeMillis();
2805        app.lastActivityTime = now;
2806
2807        // First a quick reject: if the app is already at the position we will
2808        // put it, then there is nothing to do.
2809        if (hasActivity) {
2810            final int N = mLruProcesses.size();
2811            if (N > 0 && mLruProcesses.get(N-1) == app) {
2812                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
2813                return;
2814            }
2815        } else {
2816            if (mLruProcessServiceStart > 0
2817                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2818                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
2819                return;
2820            }
2821        }
2822
2823        int lrui = mLruProcesses.lastIndexOf(app);
2824
2825        if (app.persistent && lrui >= 0) {
2826            // We don't care about the position of persistent processes, as long as
2827            // they are in the list.
2828            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
2829            return;
2830        }
2831
2832        /* In progress: compute new position first, so we can avoid doing work
2833           if the process is not actually going to move.  Not yet working.
2834        int addIndex;
2835        int nextIndex;
2836        boolean inActivity = false, inService = false;
2837        if (hasActivity) {
2838            // Process has activities, put it at the very tipsy-top.
2839            addIndex = mLruProcesses.size();
2840            nextIndex = mLruProcessServiceStart;
2841            inActivity = true;
2842        } else if (hasService) {
2843            // Process has services, put it at the top of the service list.
2844            addIndex = mLruProcessActivityStart;
2845            nextIndex = mLruProcessServiceStart;
2846            inActivity = true;
2847            inService = true;
2848        } else  {
2849            // Process not otherwise of interest, it goes to the top of the non-service area.
2850            addIndex = mLruProcessServiceStart;
2851            if (client != null) {
2852                int clientIndex = mLruProcesses.lastIndexOf(client);
2853                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2854                        + app);
2855                if (clientIndex >= 0 && addIndex > clientIndex) {
2856                    addIndex = clientIndex;
2857                }
2858            }
2859            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2860        }
2861
2862        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2863                + mLruProcessActivityStart + "): " + app);
2864        */
2865
2866        if (lrui >= 0) {
2867            if (lrui < mLruProcessActivityStart) {
2868                mLruProcessActivityStart--;
2869            }
2870            if (lrui < mLruProcessServiceStart) {
2871                mLruProcessServiceStart--;
2872            }
2873            /*
2874            if (addIndex > lrui) {
2875                addIndex--;
2876            }
2877            if (nextIndex > lrui) {
2878                nextIndex--;
2879            }
2880            */
2881            mLruProcesses.remove(lrui);
2882        }
2883
2884        /*
2885        mLruProcesses.add(addIndex, app);
2886        if (inActivity) {
2887            mLruProcessActivityStart++;
2888        }
2889        if (inService) {
2890            mLruProcessActivityStart++;
2891        }
2892        */
2893
2894        int nextIndex;
2895        if (hasActivity) {
2896            final int N = mLruProcesses.size();
2897            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
2898                // Process doesn't have activities, but has clients with
2899                // activities...  move it up, but one below the top (the top
2900                // should always have a real activity).
2901                if (DEBUG_LRU) Slog.d(TAG_LRU,
2902                        "Adding to second-top of LRU activity list: " + app);
2903                mLruProcesses.add(N - 1, app);
2904                // To keep it from spamming the LRU list (by making a bunch of clients),
2905                // we will push down any other entries owned by the app.
2906                final int uid = app.info.uid;
2907                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
2908                    ProcessRecord subProc = mLruProcesses.get(i);
2909                    if (subProc.info.uid == uid) {
2910                        // We want to push this one down the list.  If the process after
2911                        // it is for the same uid, however, don't do so, because we don't
2912                        // want them internally to be re-ordered.
2913                        if (mLruProcesses.get(i - 1).info.uid != uid) {
2914                            if (DEBUG_LRU) Slog.d(TAG_LRU,
2915                                    "Pushing uid " + uid + " swapping at " + i + ": "
2916                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
2917                            ProcessRecord tmp = mLruProcesses.get(i);
2918                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
2919                            mLruProcesses.set(i - 1, tmp);
2920                            i--;
2921                        }
2922                    } else {
2923                        // A gap, we can stop here.
2924                        break;
2925                    }
2926                }
2927            } else {
2928                // Process has activities, put it at the very tipsy-top.
2929                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
2930                mLruProcesses.add(app);
2931            }
2932            nextIndex = mLruProcessServiceStart;
2933        } else if (hasService) {
2934            // Process has services, put it at the top of the service list.
2935            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
2936            mLruProcesses.add(mLruProcessActivityStart, app);
2937            nextIndex = mLruProcessServiceStart;
2938            mLruProcessActivityStart++;
2939        } else  {
2940            // Process not otherwise of interest, it goes to the top of the non-service area.
2941            int index = mLruProcessServiceStart;
2942            if (client != null) {
2943                // If there is a client, don't allow the process to be moved up higher
2944                // in the list than that client.
2945                int clientIndex = mLruProcesses.lastIndexOf(client);
2946                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
2947                        + " when updating " + app);
2948                if (clientIndex <= lrui) {
2949                    // Don't allow the client index restriction to push it down farther in the
2950                    // list than it already is.
2951                    clientIndex = lrui;
2952                }
2953                if (clientIndex >= 0 && index > clientIndex) {
2954                    index = clientIndex;
2955                }
2956            }
2957            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
2958            mLruProcesses.add(index, app);
2959            nextIndex = index-1;
2960            mLruProcessActivityStart++;
2961            mLruProcessServiceStart++;
2962        }
2963
2964        // If the app is currently using a content provider or service,
2965        // bump those processes as well.
2966        for (int j=app.connections.size()-1; j>=0; j--) {
2967            ConnectionRecord cr = app.connections.valueAt(j);
2968            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2969                    && cr.binding.service.app != null
2970                    && cr.binding.service.app.lruSeq != mLruSeq
2971                    && !cr.binding.service.app.persistent) {
2972                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2973                        "service connection", cr, app);
2974            }
2975        }
2976        for (int j=app.conProviders.size()-1; j>=0; j--) {
2977            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2978            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2979                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2980                        "provider reference", cpr, app);
2981            }
2982        }
2983    }
2984
2985    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2986        if (uid == Process.SYSTEM_UID) {
2987            // The system gets to run in any process.  If there are multiple
2988            // processes with the same uid, just pick the first (this
2989            // should never happen).
2990            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2991            if (procs == null) return null;
2992            final int procCount = procs.size();
2993            for (int i = 0; i < procCount; i++) {
2994                final int procUid = procs.keyAt(i);
2995                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
2996                    // Don't use an app process or different user process for system component.
2997                    continue;
2998                }
2999                return procs.valueAt(i);
3000            }
3001        }
3002        ProcessRecord proc = mProcessNames.get(processName, uid);
3003        if (false && proc != null && !keepIfLarge
3004                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3005                && proc.lastCachedPss >= 4000) {
3006            // Turn this condition on to cause killing to happen regularly, for testing.
3007            if (proc.baseProcessTracker != null) {
3008                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3009            }
3010            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3011        } else if (proc != null && !keepIfLarge
3012                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3013                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3014            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3015            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3016                if (proc.baseProcessTracker != null) {
3017                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3018                }
3019                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3020            }
3021        }
3022        return proc;
3023    }
3024
3025    void ensurePackageDexOpt(String packageName) {
3026        IPackageManager pm = AppGlobals.getPackageManager();
3027        try {
3028            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
3029                mDidDexOpt = true;
3030            }
3031        } catch (RemoteException e) {
3032        }
3033    }
3034
3035    boolean isNextTransitionForward() {
3036        int transit = mWindowManager.getPendingAppTransition();
3037        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
3038                || transit == AppTransition.TRANSIT_TASK_OPEN
3039                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
3040    }
3041
3042    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3043            String processName, String abiOverride, int uid, Runnable crashHandler) {
3044        synchronized(this) {
3045            ApplicationInfo info = new ApplicationInfo();
3046            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3047            // For isolated processes, the former contains the parent's uid and the latter the
3048            // actual uid of the isolated process.
3049            // In the special case introduced by this method (which is, starting an isolated
3050            // process directly from the SystemServer without an actual parent app process) the
3051            // closest thing to a parent's uid is SYSTEM_UID.
3052            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3053            // the |isolated| logic in the ProcessRecord constructor.
3054            info.uid = Process.SYSTEM_UID;
3055            info.processName = processName;
3056            info.className = entryPoint;
3057            info.packageName = "android";
3058            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3059                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3060                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3061                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3062                    crashHandler);
3063            return proc != null ? proc.pid : 0;
3064        }
3065    }
3066
3067    final ProcessRecord startProcessLocked(String processName,
3068            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3069            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3070            boolean isolated, boolean keepIfLarge) {
3071        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3072                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3073                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3074                null /* crashHandler */);
3075    }
3076
3077    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3078            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3079            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3080            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3081        long startTime = SystemClock.elapsedRealtime();
3082        ProcessRecord app;
3083        if (!isolated) {
3084            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3085            checkTime(startTime, "startProcess: after getProcessRecord");
3086
3087            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3088                // If we are in the background, then check to see if this process
3089                // is bad.  If so, we will just silently fail.
3090                if (mBadProcesses.get(info.processName, info.uid) != null) {
3091                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3092                            + "/" + info.processName);
3093                    return null;
3094                }
3095            } else {
3096                // When the user is explicitly starting a process, then clear its
3097                // crash count so that we won't make it bad until they see at
3098                // least one crash dialog again, and make the process good again
3099                // if it had been bad.
3100                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3101                        + "/" + info.processName);
3102                mProcessCrashTimes.remove(info.processName, info.uid);
3103                if (mBadProcesses.get(info.processName, info.uid) != null) {
3104                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3105                            UserHandle.getUserId(info.uid), info.uid,
3106                            info.processName);
3107                    mBadProcesses.remove(info.processName, info.uid);
3108                    if (app != null) {
3109                        app.bad = false;
3110                    }
3111                }
3112            }
3113        } else {
3114            // If this is an isolated process, it can't re-use an existing process.
3115            app = null;
3116        }
3117
3118        // We don't have to do anything more if:
3119        // (1) There is an existing application record; and
3120        // (2) The caller doesn't think it is dead, OR there is no thread
3121        //     object attached to it so we know it couldn't have crashed; and
3122        // (3) There is a pid assigned to it, so it is either starting or
3123        //     already running.
3124        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3125                + " app=" + app + " knownToBeDead=" + knownToBeDead
3126                + " thread=" + (app != null ? app.thread : null)
3127                + " pid=" + (app != null ? app.pid : -1));
3128        if (app != null && app.pid > 0) {
3129            if (!knownToBeDead || app.thread == null) {
3130                // We already have the app running, or are waiting for it to
3131                // come up (we have a pid but not yet its thread), so keep it.
3132                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3133                // If this is a new package in the process, add the package to the list
3134                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3135                checkTime(startTime, "startProcess: done, added package to proc");
3136                return app;
3137            }
3138
3139            // An application record is attached to a previous process,
3140            // clean it up now.
3141            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3142            checkTime(startTime, "startProcess: bad proc running, killing");
3143            killProcessGroup(app.info.uid, app.pid);
3144            handleAppDiedLocked(app, true, true);
3145            checkTime(startTime, "startProcess: done killing old proc");
3146        }
3147
3148        String hostingNameStr = hostingName != null
3149                ? hostingName.flattenToShortString() : null;
3150
3151        if (app == null) {
3152            checkTime(startTime, "startProcess: creating new process record");
3153            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3154            if (app == null) {
3155                Slog.w(TAG, "Failed making new process record for "
3156                        + processName + "/" + info.uid + " isolated=" + isolated);
3157                return null;
3158            }
3159            app.crashHandler = crashHandler;
3160            checkTime(startTime, "startProcess: done creating new process record");
3161        } else {
3162            // If this is a new package in the process, add the package to the list
3163            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3164            checkTime(startTime, "startProcess: added package to existing proc");
3165        }
3166
3167        // If the system is not ready yet, then hold off on starting this
3168        // process until it is.
3169        if (!mProcessesReady
3170                && !isAllowedWhileBooting(info)
3171                && !allowWhileBooting) {
3172            if (!mProcessesOnHold.contains(app)) {
3173                mProcessesOnHold.add(app);
3174            }
3175            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3176                    "System not ready, putting on hold: " + app);
3177            checkTime(startTime, "startProcess: returning with proc on hold");
3178            return app;
3179        }
3180
3181        checkTime(startTime, "startProcess: stepping in to startProcess");
3182        startProcessLocked(
3183                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3184        checkTime(startTime, "startProcess: done starting proc!");
3185        return (app.pid != 0) ? app : null;
3186    }
3187
3188    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3189        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3190    }
3191
3192    private final void startProcessLocked(ProcessRecord app,
3193            String hostingType, String hostingNameStr) {
3194        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3195                null /* entryPoint */, null /* entryPointArgs */);
3196    }
3197
3198    private final void startProcessLocked(ProcessRecord app, String hostingType,
3199            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3200        long startTime = SystemClock.elapsedRealtime();
3201        if (app.pid > 0 && app.pid != MY_PID) {
3202            checkTime(startTime, "startProcess: removing from pids map");
3203            synchronized (mPidsSelfLocked) {
3204                mPidsSelfLocked.remove(app.pid);
3205                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3206            }
3207            checkTime(startTime, "startProcess: done removing from pids map");
3208            app.setPid(0);
3209        }
3210
3211        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3212                "startProcessLocked removing on hold: " + app);
3213        mProcessesOnHold.remove(app);
3214
3215        checkTime(startTime, "startProcess: starting to update cpu stats");
3216        updateCpuStats();
3217        checkTime(startTime, "startProcess: done updating cpu stats");
3218
3219        try {
3220            try {
3221                if (AppGlobals.getPackageManager().isPackageFrozen(app.info.packageName)) {
3222                    // This is caught below as if we had failed to fork zygote
3223                    throw new RuntimeException("Package " + app.info.packageName + " is frozen!");
3224                }
3225            } catch (RemoteException e) {
3226                throw e.rethrowAsRuntimeException();
3227            }
3228
3229            int uid = app.uid;
3230            int[] gids = null;
3231            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3232            if (!app.isolated) {
3233                int[] permGids = null;
3234                try {
3235                    checkTime(startTime, "startProcess: getting gids from package manager");
3236                    final IPackageManager pm = AppGlobals.getPackageManager();
3237                    permGids = pm.getPackageGids(app.info.packageName, app.userId);
3238                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3239                            MountServiceInternal.class);
3240                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3241                            app.info.packageName);
3242                } catch (RemoteException e) {
3243                    throw e.rethrowAsRuntimeException();
3244                }
3245
3246                /*
3247                 * Add shared application and profile GIDs so applications can share some
3248                 * resources like shared libraries and access user-wide resources
3249                 */
3250                if (ArrayUtils.isEmpty(permGids)) {
3251                    gids = new int[2];
3252                } else {
3253                    gids = new int[permGids.length + 2];
3254                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3255                }
3256                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3257                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3258            }
3259            checkTime(startTime, "startProcess: building args");
3260            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3261                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3262                        && mTopComponent != null
3263                        && app.processName.equals(mTopComponent.getPackageName())) {
3264                    uid = 0;
3265                }
3266                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3267                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3268                    uid = 0;
3269                }
3270            }
3271            int debugFlags = 0;
3272            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3273                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3274                // Also turn on CheckJNI for debuggable apps. It's quite
3275                // awkward to turn on otherwise.
3276                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3277            }
3278            // Run the app in safe mode if its manifest requests so or the
3279            // system is booted in safe mode.
3280            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3281                mSafeMode == true) {
3282                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3283            }
3284            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3285                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3286            }
3287            String jitDebugProperty = SystemProperties.get("debug.usejit");
3288            if ("true".equals(jitDebugProperty)) {
3289                debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3290            } else if (!"false".equals(jitDebugProperty)) {
3291                // If we didn't force disable by setting false, defer to the dalvik vm options.
3292                if ("true".equals(SystemProperties.get("dalvik.vm.usejit"))) {
3293                    debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3294                }
3295            }
3296            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3297            if ("true".equals(genDebugInfoProperty)) {
3298                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3299            }
3300            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3301                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3302            }
3303            if ("1".equals(SystemProperties.get("debug.assert"))) {
3304                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3305            }
3306
3307            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3308            if (requiredAbi == null) {
3309                requiredAbi = Build.SUPPORTED_ABIS[0];
3310            }
3311
3312            String instructionSet = null;
3313            if (app.info.primaryCpuAbi != null) {
3314                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3315            }
3316
3317            app.gids = gids;
3318            app.requiredAbi = requiredAbi;
3319            app.instructionSet = instructionSet;
3320
3321            // Start the process.  It will either succeed and return a result containing
3322            // the PID of the new process, or else throw a RuntimeException.
3323            boolean isActivityProcess = (entryPoint == null);
3324            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3325            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3326                    app.processName);
3327            checkTime(startTime, "startProcess: asking zygote to start proc");
3328            Process.ProcessStartResult startResult = Process.start(entryPoint,
3329                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3330                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3331                    app.info.dataDir, entryPointArgs);
3332            checkTime(startTime, "startProcess: returned from zygote!");
3333            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3334
3335            if (app.isolated) {
3336                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3337            }
3338            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3339            checkTime(startTime, "startProcess: done updating battery stats");
3340
3341            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3342                    UserHandle.getUserId(uid), startResult.pid, uid,
3343                    app.processName, hostingType,
3344                    hostingNameStr != null ? hostingNameStr : "");
3345
3346            if (app.persistent) {
3347                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3348            }
3349
3350            checkTime(startTime, "startProcess: building log message");
3351            StringBuilder buf = mStringBuilder;
3352            buf.setLength(0);
3353            buf.append("Start proc ");
3354            buf.append(startResult.pid);
3355            buf.append(':');
3356            buf.append(app.processName);
3357            buf.append('/');
3358            UserHandle.formatUid(buf, uid);
3359            if (!isActivityProcess) {
3360                buf.append(" [");
3361                buf.append(entryPoint);
3362                buf.append("]");
3363            }
3364            buf.append(" for ");
3365            buf.append(hostingType);
3366            if (hostingNameStr != null) {
3367                buf.append(" ");
3368                buf.append(hostingNameStr);
3369            }
3370            Slog.i(TAG, buf.toString());
3371            app.setPid(startResult.pid);
3372            app.usingWrapper = startResult.usingWrapper;
3373            app.removed = false;
3374            app.killed = false;
3375            app.killedByAm = false;
3376            checkTime(startTime, "startProcess: starting to update pids map");
3377            synchronized (mPidsSelfLocked) {
3378                this.mPidsSelfLocked.put(startResult.pid, app);
3379                if (isActivityProcess) {
3380                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3381                    msg.obj = app;
3382                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3383                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3384                }
3385            }
3386            checkTime(startTime, "startProcess: done updating pids map");
3387        } catch (RuntimeException e) {
3388            // XXX do better error recovery.
3389            app.setPid(0);
3390            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3391            if (app.isolated) {
3392                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3393            }
3394            Slog.e(TAG, "Failure starting process " + app.processName, e);
3395        }
3396    }
3397
3398    void updateUsageStats(ActivityRecord component, boolean resumed) {
3399        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3400                "updateUsageStats: comp=" + component + "res=" + resumed);
3401        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3402        if (resumed) {
3403            if (mUsageStatsService != null) {
3404                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3405                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3406            }
3407            synchronized (stats) {
3408                stats.noteActivityResumedLocked(component.app.uid);
3409            }
3410        } else {
3411            if (mUsageStatsService != null) {
3412                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3413                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3414            }
3415            synchronized (stats) {
3416                stats.noteActivityPausedLocked(component.app.uid);
3417            }
3418        }
3419    }
3420
3421    Intent getHomeIntent() {
3422        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3423        intent.setComponent(mTopComponent);
3424        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3425            intent.addCategory(Intent.CATEGORY_HOME);
3426        }
3427        return intent;
3428    }
3429
3430    boolean startHomeActivityLocked(int userId, String reason) {
3431        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3432                && mTopAction == null) {
3433            // We are running in factory test mode, but unable to find
3434            // the factory test app, so just sit around displaying the
3435            // error message and don't try to start anything.
3436            return false;
3437        }
3438        Intent intent = getHomeIntent();
3439        ActivityInfo aInfo =
3440            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3441        if (aInfo != null) {
3442            intent.setComponent(new ComponentName(
3443                    aInfo.applicationInfo.packageName, aInfo.name));
3444            // Don't do this if the home app is currently being
3445            // instrumented.
3446            aInfo = new ActivityInfo(aInfo);
3447            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3448            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3449                    aInfo.applicationInfo.uid, true);
3450            if (app == null || app.instrumentationClass == null) {
3451                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3452                mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3453            }
3454        }
3455
3456        return true;
3457    }
3458
3459    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3460        ActivityInfo ai = null;
3461        ComponentName comp = intent.getComponent();
3462        try {
3463            if (comp != null) {
3464                // Factory test.
3465                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3466            } else {
3467                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3468                        intent,
3469                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3470                        flags, userId);
3471
3472                if (info != null) {
3473                    ai = info.activityInfo;
3474                }
3475            }
3476        } catch (RemoteException e) {
3477            // ignore
3478        }
3479
3480        return ai;
3481    }
3482
3483    /**
3484     * Starts the "new version setup screen" if appropriate.
3485     */
3486    void startSetupActivityLocked() {
3487        // Only do this once per boot.
3488        if (mCheckedForSetup) {
3489            return;
3490        }
3491
3492        // We will show this screen if the current one is a different
3493        // version than the last one shown, and we are not running in
3494        // low-level factory test mode.
3495        final ContentResolver resolver = mContext.getContentResolver();
3496        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3497                Settings.Global.getInt(resolver,
3498                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3499            mCheckedForSetup = true;
3500
3501            // See if we should be showing the platform update setup UI.
3502            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3503            List<ResolveInfo> ris = mContext.getPackageManager()
3504                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3505
3506            // We don't allow third party apps to replace this.
3507            ResolveInfo ri = null;
3508            for (int i=0; ris != null && i<ris.size(); i++) {
3509                if ((ris.get(i).activityInfo.applicationInfo.flags
3510                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3511                    ri = ris.get(i);
3512                    break;
3513                }
3514            }
3515
3516            if (ri != null) {
3517                String vers = ri.activityInfo.metaData != null
3518                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3519                        : null;
3520                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3521                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3522                            Intent.METADATA_SETUP_VERSION);
3523                }
3524                String lastVers = Settings.Secure.getString(
3525                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3526                if (vers != null && !vers.equals(lastVers)) {
3527                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3528                    intent.setComponent(new ComponentName(
3529                            ri.activityInfo.packageName, ri.activityInfo.name));
3530                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3531                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, false,
3532                            null, null, null);
3533                }
3534            }
3535        }
3536    }
3537
3538    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3539        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3540    }
3541
3542    void enforceNotIsolatedCaller(String caller) {
3543        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3544            throw new SecurityException("Isolated process not allowed to call " + caller);
3545        }
3546    }
3547
3548    void enforceShellRestriction(String restriction, int userHandle) {
3549        if (Binder.getCallingUid() == Process.SHELL_UID) {
3550            if (userHandle < 0
3551                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3552                throw new SecurityException("Shell does not have permission to access user "
3553                        + userHandle);
3554            }
3555        }
3556    }
3557
3558    @Override
3559    public int getFrontActivityScreenCompatMode() {
3560        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3561        synchronized (this) {
3562            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3563        }
3564    }
3565
3566    @Override
3567    public void setFrontActivityScreenCompatMode(int mode) {
3568        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3569                "setFrontActivityScreenCompatMode");
3570        synchronized (this) {
3571            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3572        }
3573    }
3574
3575    @Override
3576    public int getPackageScreenCompatMode(String packageName) {
3577        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3578        synchronized (this) {
3579            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3580        }
3581    }
3582
3583    @Override
3584    public void setPackageScreenCompatMode(String packageName, int mode) {
3585        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3586                "setPackageScreenCompatMode");
3587        synchronized (this) {
3588            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3589        }
3590    }
3591
3592    @Override
3593    public boolean getPackageAskScreenCompat(String packageName) {
3594        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3595        synchronized (this) {
3596            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3597        }
3598    }
3599
3600    @Override
3601    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3602        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3603                "setPackageAskScreenCompat");
3604        synchronized (this) {
3605            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3606        }
3607    }
3608
3609    private boolean hasUsageStatsPermission(String callingPackage) {
3610        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3611                Binder.getCallingUid(), callingPackage);
3612        if (mode == AppOpsManager.MODE_DEFAULT) {
3613            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3614                    == PackageManager.PERMISSION_GRANTED;
3615        }
3616        return mode == AppOpsManager.MODE_ALLOWED;
3617    }
3618
3619    @Override
3620    public int getPackageProcessState(String packageName, String callingPackage) {
3621        if (!hasUsageStatsPermission(callingPackage)) {
3622            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3623                    "getPackageProcessState");
3624        }
3625
3626        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3627        synchronized (this) {
3628            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3629                final ProcessRecord proc = mLruProcesses.get(i);
3630                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3631                        || procState > proc.setProcState) {
3632                    boolean found = false;
3633                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3634                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3635                            procState = proc.setProcState;
3636                            found = true;
3637                        }
3638                    }
3639                    if (proc.pkgDeps != null && !found) {
3640                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3641                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3642                                procState = proc.setProcState;
3643                                break;
3644                            }
3645                        }
3646                    }
3647                }
3648            }
3649        }
3650        return procState;
3651    }
3652
3653    @Override
3654    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3655        synchronized (this) {
3656            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3657            if (app == null) {
3658                return false;
3659            }
3660            if (app.trimMemoryLevel < level && app.thread != null &&
3661                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3662                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3663                try {
3664                    app.thread.scheduleTrimMemory(level);
3665                    app.trimMemoryLevel = level;
3666                    return true;
3667                } catch (RemoteException e) {
3668                    // Fallthrough to failure case.
3669                }
3670            }
3671        }
3672        return false;
3673    }
3674
3675    private void dispatchProcessesChanged() {
3676        int N;
3677        synchronized (this) {
3678            N = mPendingProcessChanges.size();
3679            if (mActiveProcessChanges.length < N) {
3680                mActiveProcessChanges = new ProcessChangeItem[N];
3681            }
3682            mPendingProcessChanges.toArray(mActiveProcessChanges);
3683            mPendingProcessChanges.clear();
3684            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3685                    "*** Delivering " + N + " process changes");
3686        }
3687
3688        int i = mProcessObservers.beginBroadcast();
3689        while (i > 0) {
3690            i--;
3691            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3692            if (observer != null) {
3693                try {
3694                    for (int j=0; j<N; j++) {
3695                        ProcessChangeItem item = mActiveProcessChanges[j];
3696                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3697                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3698                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3699                                    + item.uid + ": " + item.foregroundActivities);
3700                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3701                                    item.foregroundActivities);
3702                        }
3703                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3704                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3705                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3706                                    + ": " + item.processState);
3707                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3708                        }
3709                    }
3710                } catch (RemoteException e) {
3711                }
3712            }
3713        }
3714        mProcessObservers.finishBroadcast();
3715
3716        synchronized (this) {
3717            for (int j=0; j<N; j++) {
3718                mAvailProcessChanges.add(mActiveProcessChanges[j]);
3719            }
3720        }
3721    }
3722
3723    private void dispatchProcessDied(int pid, int uid) {
3724        int i = mProcessObservers.beginBroadcast();
3725        while (i > 0) {
3726            i--;
3727            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3728            if (observer != null) {
3729                try {
3730                    observer.onProcessDied(pid, uid);
3731                } catch (RemoteException e) {
3732                }
3733            }
3734        }
3735        mProcessObservers.finishBroadcast();
3736    }
3737
3738    private void dispatchUidsChanged() {
3739        int N;
3740        synchronized (this) {
3741            N = mPendingUidChanges.size();
3742            if (mActiveUidChanges.length < N) {
3743                mActiveUidChanges = new UidRecord.ChangeItem[N];
3744            }
3745            for (int i=0; i<N; i++) {
3746                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3747                mActiveUidChanges[i] = change;
3748                change.uidRecord.pendingChange = null;
3749                change.uidRecord = null;
3750            }
3751            mPendingUidChanges.clear();
3752            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3753                    "*** Delivering " + N + " uid changes");
3754        }
3755
3756        if (mLocalPowerManager != null) {
3757            for (int j=0; j<N; j++) {
3758                UidRecord.ChangeItem item = mActiveUidChanges[j];
3759                if (item.gone) {
3760                    mLocalPowerManager.uidGone(item.uid);
3761                } else {
3762                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
3763                }
3764            }
3765        }
3766
3767        int i = mUidObservers.beginBroadcast();
3768        while (i > 0) {
3769            i--;
3770            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
3771            if (observer != null) {
3772                try {
3773                    for (int j=0; j<N; j++) {
3774                        UidRecord.ChangeItem item = mActiveUidChanges[j];
3775                        if (item.gone) {
3776                            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3777                                    "UID gone uid=" + item.uid);
3778                            observer.onUidGone(item.uid);
3779                        } else {
3780                            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3781                                    "UID CHANGED uid=" + item.uid
3782                                    + ": " + item.processState);
3783                            observer.onUidStateChanged(item.uid, item.processState);
3784                        }
3785                    }
3786                } catch (RemoteException e) {
3787                }
3788            }
3789        }
3790        mUidObservers.finishBroadcast();
3791
3792        synchronized (this) {
3793            for (int j=0; j<N; j++) {
3794                mAvailUidChanges.add(mActiveUidChanges[j]);
3795            }
3796        }
3797    }
3798
3799    @Override
3800    public final int startActivity(IApplicationThread caller, String callingPackage,
3801            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3802            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3803        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3804            resultWho, requestCode, startFlags, profilerInfo, options,
3805            UserHandle.getCallingUserId());
3806    }
3807
3808    @Override
3809    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3810            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3811            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3812        enforceNotIsolatedCaller("startActivity");
3813        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3814                false, ALLOW_FULL_ONLY, "startActivity", null);
3815        // TODO: Switch to user app stacks here.
3816        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3817                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3818                profilerInfo, null, null, options, false, userId, null, null);
3819    }
3820
3821    @Override
3822    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3823            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3824            int startFlags, ProfilerInfo profilerInfo, Bundle options, boolean ignoreTargetSecurity,
3825            int userId) {
3826
3827        // This is very dangerous -- it allows you to perform a start activity (including
3828        // permission grants) as any app that may launch one of your own activities.  So
3829        // we will only allow this to be done from activities that are part of the core framework,
3830        // and then only when they are running as the system.
3831        final ActivityRecord sourceRecord;
3832        final int targetUid;
3833        final String targetPackage;
3834        synchronized (this) {
3835            if (resultTo == null) {
3836                throw new SecurityException("Must be called from an activity");
3837            }
3838            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3839            if (sourceRecord == null) {
3840                throw new SecurityException("Called with bad activity token: " + resultTo);
3841            }
3842            if (!sourceRecord.info.packageName.equals("android")) {
3843                throw new SecurityException(
3844                        "Must be called from an activity that is declared in the android package");
3845            }
3846            if (sourceRecord.app == null) {
3847                throw new SecurityException("Called without a process attached to activity");
3848            }
3849            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3850                // This is still okay, as long as this activity is running under the
3851                // uid of the original calling activity.
3852                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3853                    throw new SecurityException(
3854                            "Calling activity in uid " + sourceRecord.app.uid
3855                                    + " must be system uid or original calling uid "
3856                                    + sourceRecord.launchedFromUid);
3857                }
3858            }
3859            if (ignoreTargetSecurity) {
3860                if (intent.getComponent() == null) {
3861                    throw new SecurityException(
3862                            "Component must be specified with ignoreTargetSecurity");
3863                }
3864                if (intent.getSelector() != null) {
3865                    throw new SecurityException(
3866                            "Selector not allowed with ignoreTargetSecurity");
3867                }
3868            }
3869            targetUid = sourceRecord.launchedFromUid;
3870            targetPackage = sourceRecord.launchedFromPackage;
3871        }
3872
3873        if (userId == UserHandle.USER_NULL) {
3874            userId = UserHandle.getUserId(sourceRecord.app.uid);
3875        }
3876
3877        // TODO: Switch to user app stacks here.
3878        try {
3879            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3880                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3881                    null, null, options, ignoreTargetSecurity, userId, null, null);
3882            return ret;
3883        } catch (SecurityException e) {
3884            // XXX need to figure out how to propagate to original app.
3885            // A SecurityException here is generally actually a fault of the original
3886            // calling activity (such as a fairly granting permissions), so propagate it
3887            // back to them.
3888            /*
3889            StringBuilder msg = new StringBuilder();
3890            msg.append("While launching");
3891            msg.append(intent.toString());
3892            msg.append(": ");
3893            msg.append(e.getMessage());
3894            */
3895            throw e;
3896        }
3897    }
3898
3899    @Override
3900    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3901            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3902            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3903        enforceNotIsolatedCaller("startActivityAndWait");
3904        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3905                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3906        WaitResult res = new WaitResult();
3907        // TODO: Switch to user app stacks here.
3908        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3909                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3910                options, false, userId, null, null);
3911        return res;
3912    }
3913
3914    @Override
3915    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3916            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3917            int startFlags, Configuration config, Bundle options, int userId) {
3918        enforceNotIsolatedCaller("startActivityWithConfig");
3919        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3920                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3921        // TODO: Switch to user app stacks here.
3922        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3923                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3924                null, null, config, options, false, userId, null, null);
3925        return ret;
3926    }
3927
3928    @Override
3929    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
3930            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
3931            int requestCode, int flagsMask, int flagsValues, Bundle options)
3932            throws TransactionTooLargeException {
3933        enforceNotIsolatedCaller("startActivityIntentSender");
3934        // Refuse possible leaked file descriptors
3935        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3936            throw new IllegalArgumentException("File descriptors passed in Intent");
3937        }
3938
3939        IIntentSender sender = intent.getTarget();
3940        if (!(sender instanceof PendingIntentRecord)) {
3941            throw new IllegalArgumentException("Bad PendingIntent object");
3942        }
3943
3944        PendingIntentRecord pir = (PendingIntentRecord)sender;
3945
3946        synchronized (this) {
3947            // If this is coming from the currently resumed activity, it is
3948            // effectively saying that app switches are allowed at this point.
3949            final ActivityStack stack = getFocusedStack();
3950            if (stack.mResumedActivity != null &&
3951                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3952                mAppSwitchesAllowedTime = 0;
3953            }
3954        }
3955        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3956                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3957        return ret;
3958    }
3959
3960    @Override
3961    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3962            Intent intent, String resolvedType, IVoiceInteractionSession session,
3963            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3964            Bundle options, int userId) {
3965        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3966                != PackageManager.PERMISSION_GRANTED) {
3967            String msg = "Permission Denial: startVoiceActivity() from pid="
3968                    + Binder.getCallingPid()
3969                    + ", uid=" + Binder.getCallingUid()
3970                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3971            Slog.w(TAG, msg);
3972            throw new SecurityException(msg);
3973        }
3974        if (session == null || interactor == null) {
3975            throw new NullPointerException("null session or interactor");
3976        }
3977        userId = handleIncomingUser(callingPid, callingUid, userId,
3978                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3979        // TODO: Switch to user app stacks here.
3980        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3981                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3982                null, options, false, userId, null, null);
3983    }
3984
3985    @Override
3986    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
3987        synchronized (this) {
3988            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
3989                if (keepAwake) {
3990                    mVoiceWakeLock.acquire();
3991                } else {
3992                    mVoiceWakeLock.release();
3993                }
3994            }
3995        }
3996    }
3997
3998    @Override
3999    public boolean startNextMatchingActivity(IBinder callingActivity,
4000            Intent intent, Bundle options) {
4001        // Refuse possible leaked file descriptors
4002        if (intent != null && intent.hasFileDescriptors() == true) {
4003            throw new IllegalArgumentException("File descriptors passed in Intent");
4004        }
4005
4006        synchronized (this) {
4007            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4008            if (r == null) {
4009                ActivityOptions.abort(options);
4010                return false;
4011            }
4012            if (r.app == null || r.app.thread == null) {
4013                // The caller is not running...  d'oh!
4014                ActivityOptions.abort(options);
4015                return false;
4016            }
4017            intent = new Intent(intent);
4018            // The caller is not allowed to change the data.
4019            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4020            // And we are resetting to find the next component...
4021            intent.setComponent(null);
4022
4023            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4024
4025            ActivityInfo aInfo = null;
4026            try {
4027                List<ResolveInfo> resolves =
4028                    AppGlobals.getPackageManager().queryIntentActivities(
4029                            intent, r.resolvedType,
4030                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4031                            UserHandle.getCallingUserId());
4032
4033                // Look for the original activity in the list...
4034                final int N = resolves != null ? resolves.size() : 0;
4035                for (int i=0; i<N; i++) {
4036                    ResolveInfo rInfo = resolves.get(i);
4037                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4038                            && rInfo.activityInfo.name.equals(r.info.name)) {
4039                        // We found the current one...  the next matching is
4040                        // after it.
4041                        i++;
4042                        if (i<N) {
4043                            aInfo = resolves.get(i).activityInfo;
4044                        }
4045                        if (debug) {
4046                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4047                                    + "/" + r.info.name);
4048                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
4049                                    + "/" + aInfo.name);
4050                        }
4051                        break;
4052                    }
4053                }
4054            } catch (RemoteException e) {
4055            }
4056
4057            if (aInfo == null) {
4058                // Nobody who is next!
4059                ActivityOptions.abort(options);
4060                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4061                return false;
4062            }
4063
4064            intent.setComponent(new ComponentName(
4065                    aInfo.applicationInfo.packageName, aInfo.name));
4066            intent.setFlags(intent.getFlags()&~(
4067                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4068                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4069                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4070                    Intent.FLAG_ACTIVITY_NEW_TASK));
4071
4072            // Okay now we need to start the new activity, replacing the
4073            // currently running activity.  This is a little tricky because
4074            // we want to start the new one as if the current one is finished,
4075            // but not finish the current one first so that there is no flicker.
4076            // And thus...
4077            final boolean wasFinishing = r.finishing;
4078            r.finishing = true;
4079
4080            // Propagate reply information over to the new activity.
4081            final ActivityRecord resultTo = r.resultTo;
4082            final String resultWho = r.resultWho;
4083            final int requestCode = r.requestCode;
4084            r.resultTo = null;
4085            if (resultTo != null) {
4086                resultTo.removeResultsLocked(r, resultWho, requestCode);
4087            }
4088
4089            final long origId = Binder.clearCallingIdentity();
4090            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
4091                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
4092                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
4093                    -1, r.launchedFromUid, 0, options, false, false, null, null, null);
4094            Binder.restoreCallingIdentity(origId);
4095
4096            r.finishing = wasFinishing;
4097            if (res != ActivityManager.START_SUCCESS) {
4098                return false;
4099            }
4100            return true;
4101        }
4102    }
4103
4104    @Override
4105    public final int startActivityFromRecents(int taskId, Bundle options) {
4106        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4107            String msg = "Permission Denial: startActivityFromRecents called without " +
4108                    START_TASKS_FROM_RECENTS;
4109            Slog.w(TAG, msg);
4110            throw new SecurityException(msg);
4111        }
4112        return startActivityFromRecentsInner(taskId, options);
4113    }
4114
4115    final int startActivityFromRecentsInner(int taskId, Bundle options) {
4116        final TaskRecord task;
4117        final int callingUid;
4118        final String callingPackage;
4119        final Intent intent;
4120        final int userId;
4121        synchronized (this) {
4122            task = mStackSupervisor.anyTaskForIdLocked(taskId);
4123            if (task == null) {
4124                throw new IllegalArgumentException("Task " + taskId + " not found.");
4125            }
4126            if (task.getRootActivity() != null) {
4127                moveTaskToFrontLocked(task.taskId, 0, null);
4128                return ActivityManager.START_TASK_TO_FRONT;
4129            }
4130            callingUid = task.mCallingUid;
4131            callingPackage = task.mCallingPackage;
4132            intent = task.intent;
4133            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4134            userId = task.userId;
4135        }
4136        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4137                options, userId, null, task);
4138    }
4139
4140    final int startActivityInPackage(int uid, String callingPackage,
4141            Intent intent, String resolvedType, IBinder resultTo,
4142            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
4143            IActivityContainer container, TaskRecord inTask) {
4144
4145        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4146                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4147
4148        // TODO: Switch to user app stacks here.
4149        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
4150                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4151                null, null, null, options, false, userId, container, inTask);
4152        return ret;
4153    }
4154
4155    @Override
4156    public final int startActivities(IApplicationThread caller, String callingPackage,
4157            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
4158            int userId) {
4159        enforceNotIsolatedCaller("startActivities");
4160        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4161                false, ALLOW_FULL_ONLY, "startActivity", null);
4162        // TODO: Switch to user app stacks here.
4163        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
4164                resolvedTypes, resultTo, options, userId);
4165        return ret;
4166    }
4167
4168    final int startActivitiesInPackage(int uid, String callingPackage,
4169            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4170            Bundle options, int userId) {
4171
4172        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4173                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4174        // TODO: Switch to user app stacks here.
4175        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4176                resultTo, options, userId);
4177        return ret;
4178    }
4179
4180    @Override
4181    public void reportActivityFullyDrawn(IBinder token) {
4182        synchronized (this) {
4183            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4184            if (r == null) {
4185                return;
4186            }
4187            r.reportFullyDrawnLocked();
4188        }
4189    }
4190
4191    @Override
4192    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4193        synchronized (this) {
4194            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4195            if (r == null) {
4196                return;
4197            }
4198            if (r.task != null && r.task.mResizeable) {
4199                // Fixed screen orientation isn't supported with resizeable activities.
4200                return;
4201            }
4202            final long origId = Binder.clearCallingIdentity();
4203            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4204            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4205                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4206            if (config != null) {
4207                r.frozenBeforeDestroy = true;
4208                if (!updateConfigurationLocked(config, r, false, false)) {
4209                    mStackSupervisor.resumeTopActivitiesLocked();
4210                }
4211            }
4212            Binder.restoreCallingIdentity(origId);
4213        }
4214    }
4215
4216    @Override
4217    public int getRequestedOrientation(IBinder token) {
4218        synchronized (this) {
4219            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4220            if (r == null) {
4221                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4222            }
4223            return mWindowManager.getAppOrientation(r.appToken);
4224        }
4225    }
4226
4227    /**
4228     * This is the internal entry point for handling Activity.finish().
4229     *
4230     * @param token The Binder token referencing the Activity we want to finish.
4231     * @param resultCode Result code, if any, from this Activity.
4232     * @param resultData Result data (Intent), if any, from this Activity.
4233     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4234     *            the root Activity in the task.
4235     *
4236     * @return Returns true if the activity successfully finished, or false if it is still running.
4237     */
4238    @Override
4239    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4240            boolean finishTask) {
4241        // Refuse possible leaked file descriptors
4242        if (resultData != null && resultData.hasFileDescriptors() == true) {
4243            throw new IllegalArgumentException("File descriptors passed in Intent");
4244        }
4245
4246        synchronized(this) {
4247            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4248            if (r == null) {
4249                return true;
4250            }
4251            // Keep track of the root activity of the task before we finish it
4252            TaskRecord tr = r.task;
4253            ActivityRecord rootR = tr.getRootActivity();
4254            if (rootR == null) {
4255                Slog.w(TAG, "Finishing task with all activities already finished");
4256            }
4257            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4258            // finish.
4259            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4260                    mStackSupervisor.isLastLockedTask(tr)) {
4261                Slog.i(TAG, "Not finishing task in lock task mode");
4262                mStackSupervisor.showLockTaskToast();
4263                return false;
4264            }
4265            if (mController != null) {
4266                // Find the first activity that is not finishing.
4267                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4268                if (next != null) {
4269                    // ask watcher if this is allowed
4270                    boolean resumeOK = true;
4271                    try {
4272                        resumeOK = mController.activityResuming(next.packageName);
4273                    } catch (RemoteException e) {
4274                        mController = null;
4275                        Watchdog.getInstance().setActivityController(null);
4276                    }
4277
4278                    if (!resumeOK) {
4279                        Slog.i(TAG, "Not finishing activity because controller resumed");
4280                        return false;
4281                    }
4282                }
4283            }
4284            final long origId = Binder.clearCallingIdentity();
4285            try {
4286                boolean res;
4287                if (finishTask && r == rootR) {
4288                    // If requested, remove the task that is associated to this activity only if it
4289                    // was the root activity in the task. The result code and data is ignored
4290                    // because we don't support returning them across task boundaries.
4291                    res = removeTaskByIdLocked(tr.taskId, false);
4292                    if (!res) {
4293                        Slog.i(TAG, "Removing task failed to finish activity");
4294                    }
4295                } else {
4296                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4297                            resultData, "app-request", true);
4298                    if (!res) {
4299                        Slog.i(TAG, "Failed to finish by app-request");
4300                    }
4301                }
4302                return res;
4303            } finally {
4304                Binder.restoreCallingIdentity(origId);
4305            }
4306        }
4307    }
4308
4309    @Override
4310    public final void finishHeavyWeightApp() {
4311        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4312                != PackageManager.PERMISSION_GRANTED) {
4313            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4314                    + Binder.getCallingPid()
4315                    + ", uid=" + Binder.getCallingUid()
4316                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4317            Slog.w(TAG, msg);
4318            throw new SecurityException(msg);
4319        }
4320
4321        synchronized(this) {
4322            if (mHeavyWeightProcess == null) {
4323                return;
4324            }
4325
4326            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4327            for (int i = 0; i < activities.size(); i++) {
4328                ActivityRecord r = activities.get(i);
4329                if (!r.finishing && r.isInStackLocked()) {
4330                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4331                            null, "finish-heavy", true);
4332                }
4333            }
4334
4335            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4336                    mHeavyWeightProcess.userId, 0));
4337            mHeavyWeightProcess = null;
4338        }
4339    }
4340
4341    @Override
4342    public void crashApplication(int uid, int initialPid, String packageName,
4343            String message) {
4344        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4345                != PackageManager.PERMISSION_GRANTED) {
4346            String msg = "Permission Denial: crashApplication() from pid="
4347                    + Binder.getCallingPid()
4348                    + ", uid=" + Binder.getCallingUid()
4349                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4350            Slog.w(TAG, msg);
4351            throw new SecurityException(msg);
4352        }
4353
4354        synchronized(this) {
4355            ProcessRecord proc = null;
4356
4357            // Figure out which process to kill.  We don't trust that initialPid
4358            // still has any relation to current pids, so must scan through the
4359            // list.
4360            synchronized (mPidsSelfLocked) {
4361                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4362                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4363                    if (p.uid != uid) {
4364                        continue;
4365                    }
4366                    if (p.pid == initialPid) {
4367                        proc = p;
4368                        break;
4369                    }
4370                    if (p.pkgList.containsKey(packageName)) {
4371                        proc = p;
4372                    }
4373                }
4374            }
4375
4376            if (proc == null) {
4377                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4378                        + " initialPid=" + initialPid
4379                        + " packageName=" + packageName);
4380                return;
4381            }
4382
4383            if (proc.thread != null) {
4384                if (proc.pid == Process.myPid()) {
4385                    Log.w(TAG, "crashApplication: trying to crash self!");
4386                    return;
4387                }
4388                long ident = Binder.clearCallingIdentity();
4389                try {
4390                    proc.thread.scheduleCrash(message);
4391                } catch (RemoteException e) {
4392                }
4393                Binder.restoreCallingIdentity(ident);
4394            }
4395        }
4396    }
4397
4398    @Override
4399    public final void finishSubActivity(IBinder token, String resultWho,
4400            int requestCode) {
4401        synchronized(this) {
4402            final long origId = Binder.clearCallingIdentity();
4403            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4404            if (r != null) {
4405                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4406            }
4407            Binder.restoreCallingIdentity(origId);
4408        }
4409    }
4410
4411    @Override
4412    public boolean finishActivityAffinity(IBinder token) {
4413        synchronized(this) {
4414            final long origId = Binder.clearCallingIdentity();
4415            try {
4416                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4417                if (r == null) {
4418                    return false;
4419                }
4420
4421                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4422                // can finish.
4423                final TaskRecord task = r.task;
4424                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4425                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4426                    mStackSupervisor.showLockTaskToast();
4427                    return false;
4428                }
4429                return task.stack.finishActivityAffinityLocked(r);
4430            } finally {
4431                Binder.restoreCallingIdentity(origId);
4432            }
4433        }
4434    }
4435
4436    @Override
4437    public void finishVoiceTask(IVoiceInteractionSession session) {
4438        synchronized(this) {
4439            final long origId = Binder.clearCallingIdentity();
4440            try {
4441                mStackSupervisor.finishVoiceTask(session);
4442            } finally {
4443                Binder.restoreCallingIdentity(origId);
4444            }
4445        }
4446
4447    }
4448
4449    @Override
4450    public boolean releaseActivityInstance(IBinder token) {
4451        synchronized(this) {
4452            final long origId = Binder.clearCallingIdentity();
4453            try {
4454                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4455                if (r == null) {
4456                    return false;
4457                }
4458                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4459            } finally {
4460                Binder.restoreCallingIdentity(origId);
4461            }
4462        }
4463    }
4464
4465    @Override
4466    public void releaseSomeActivities(IApplicationThread appInt) {
4467        synchronized(this) {
4468            final long origId = Binder.clearCallingIdentity();
4469            try {
4470                ProcessRecord app = getRecordForAppLocked(appInt);
4471                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4472            } finally {
4473                Binder.restoreCallingIdentity(origId);
4474            }
4475        }
4476    }
4477
4478    @Override
4479    public boolean willActivityBeVisible(IBinder token) {
4480        synchronized(this) {
4481            ActivityStack stack = ActivityRecord.getStackLocked(token);
4482            if (stack != null) {
4483                return stack.willActivityBeVisibleLocked(token);
4484            }
4485            return false;
4486        }
4487    }
4488
4489    @Override
4490    public void overridePendingTransition(IBinder token, String packageName,
4491            int enterAnim, int exitAnim) {
4492        synchronized(this) {
4493            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4494            if (self == null) {
4495                return;
4496            }
4497
4498            final long origId = Binder.clearCallingIdentity();
4499
4500            if (self.state == ActivityState.RESUMED
4501                    || self.state == ActivityState.PAUSING) {
4502                mWindowManager.overridePendingAppTransition(packageName,
4503                        enterAnim, exitAnim, null);
4504            }
4505
4506            Binder.restoreCallingIdentity(origId);
4507        }
4508    }
4509
4510    /**
4511     * Main function for removing an existing process from the activity manager
4512     * as a result of that process going away.  Clears out all connections
4513     * to the process.
4514     */
4515    private final void handleAppDiedLocked(ProcessRecord app,
4516            boolean restarting, boolean allowRestart) {
4517        int pid = app.pid;
4518        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4519        if (!kept && !restarting) {
4520            removeLruProcessLocked(app);
4521            if (pid > 0) {
4522                ProcessList.remove(pid);
4523            }
4524        }
4525
4526        if (mProfileProc == app) {
4527            clearProfilerLocked();
4528        }
4529
4530        // Remove this application's activities from active lists.
4531        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4532
4533        app.activities.clear();
4534
4535        if (app.instrumentationClass != null) {
4536            Slog.w(TAG, "Crash of app " + app.processName
4537                  + " running instrumentation " + app.instrumentationClass);
4538            Bundle info = new Bundle();
4539            info.putString("shortMsg", "Process crashed.");
4540            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4541        }
4542
4543        if (!restarting && hasVisibleActivities && !mStackSupervisor.resumeTopActivitiesLocked()) {
4544            // If there was nothing to resume, and we are not already
4545            // restarting this process, but there is a visible activity that
4546            // is hosted by the process...  then make sure all visible
4547            // activities are running, taking care of restarting this
4548            // process.
4549            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4550        }
4551    }
4552
4553    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4554        IBinder threadBinder = thread.asBinder();
4555        // Find the application record.
4556        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4557            ProcessRecord rec = mLruProcesses.get(i);
4558            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4559                return i;
4560            }
4561        }
4562        return -1;
4563    }
4564
4565    final ProcessRecord getRecordForAppLocked(
4566            IApplicationThread thread) {
4567        if (thread == null) {
4568            return null;
4569        }
4570
4571        int appIndex = getLRURecordIndexForAppLocked(thread);
4572        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4573    }
4574
4575    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4576        // If there are no longer any background processes running,
4577        // and the app that died was not running instrumentation,
4578        // then tell everyone we are now low on memory.
4579        boolean haveBg = false;
4580        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4581            ProcessRecord rec = mLruProcesses.get(i);
4582            if (rec.thread != null
4583                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4584                haveBg = true;
4585                break;
4586            }
4587        }
4588
4589        if (!haveBg) {
4590            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4591            if (doReport) {
4592                long now = SystemClock.uptimeMillis();
4593                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4594                    doReport = false;
4595                } else {
4596                    mLastMemUsageReportTime = now;
4597                }
4598            }
4599            final ArrayList<ProcessMemInfo> memInfos
4600                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4601            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4602            long now = SystemClock.uptimeMillis();
4603            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4604                ProcessRecord rec = mLruProcesses.get(i);
4605                if (rec == dyingProc || rec.thread == null) {
4606                    continue;
4607                }
4608                if (doReport) {
4609                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4610                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4611                }
4612                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4613                    // The low memory report is overriding any current
4614                    // state for a GC request.  Make sure to do
4615                    // heavy/important/visible/foreground processes first.
4616                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4617                        rec.lastRequestedGc = 0;
4618                    } else {
4619                        rec.lastRequestedGc = rec.lastLowMemory;
4620                    }
4621                    rec.reportLowMemory = true;
4622                    rec.lastLowMemory = now;
4623                    mProcessesToGc.remove(rec);
4624                    addProcessToGcListLocked(rec);
4625                }
4626            }
4627            if (doReport) {
4628                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4629                mHandler.sendMessage(msg);
4630            }
4631            scheduleAppGcsLocked();
4632        }
4633    }
4634
4635    final void appDiedLocked(ProcessRecord app) {
4636       appDiedLocked(app, app.pid, app.thread, false);
4637    }
4638
4639    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4640            boolean fromBinderDied) {
4641        // First check if this ProcessRecord is actually active for the pid.
4642        synchronized (mPidsSelfLocked) {
4643            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4644            if (curProc != app) {
4645                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4646                return;
4647            }
4648        }
4649
4650        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4651        synchronized (stats) {
4652            stats.noteProcessDiedLocked(app.info.uid, pid);
4653        }
4654
4655        if (!app.killed) {
4656            if (!fromBinderDied) {
4657                Process.killProcessQuiet(pid);
4658            }
4659            killProcessGroup(app.info.uid, pid);
4660            app.killed = true;
4661        }
4662
4663        // Clean up already done if the process has been re-started.
4664        if (app.pid == pid && app.thread != null &&
4665                app.thread.asBinder() == thread.asBinder()) {
4666            boolean doLowMem = app.instrumentationClass == null;
4667            boolean doOomAdj = doLowMem;
4668            if (!app.killedByAm) {
4669                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4670                        + ") has died");
4671                mAllowLowerMemLevel = true;
4672            } else {
4673                // Note that we always want to do oom adj to update our state with the
4674                // new number of procs.
4675                mAllowLowerMemLevel = false;
4676                doLowMem = false;
4677            }
4678            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4679            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4680                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
4681            handleAppDiedLocked(app, false, true);
4682
4683            if (doOomAdj) {
4684                updateOomAdjLocked();
4685            }
4686            if (doLowMem) {
4687                doLowMemReportIfNeededLocked(app);
4688            }
4689        } else if (app.pid != pid) {
4690            // A new process has already been started.
4691            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4692                    + ") has died and restarted (pid " + app.pid + ").");
4693            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4694        } else if (DEBUG_PROCESSES) {
4695            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
4696                    + thread.asBinder());
4697        }
4698    }
4699
4700    /**
4701     * If a stack trace dump file is configured, dump process stack traces.
4702     * @param clearTraces causes the dump file to be erased prior to the new
4703     *    traces being written, if true; when false, the new traces will be
4704     *    appended to any existing file content.
4705     * @param firstPids of dalvik VM processes to dump stack traces for first
4706     * @param lastPids of dalvik VM processes to dump stack traces for last
4707     * @param nativeProcs optional list of native process names to dump stack crawls
4708     * @return file containing stack traces, or null if no dump file is configured
4709     */
4710    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4711            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4712        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4713        if (tracesPath == null || tracesPath.length() == 0) {
4714            return null;
4715        }
4716
4717        File tracesFile = new File(tracesPath);
4718        try {
4719            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4720            tracesFile.createNewFile();
4721            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4722        } catch (IOException e) {
4723            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4724            return null;
4725        }
4726
4727        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4728        return tracesFile;
4729    }
4730
4731    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4732            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4733        // Use a FileObserver to detect when traces finish writing.
4734        // The order of traces is considered important to maintain for legibility.
4735        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4736            @Override
4737            public synchronized void onEvent(int event, String path) { notify(); }
4738        };
4739
4740        try {
4741            observer.startWatching();
4742
4743            // First collect all of the stacks of the most important pids.
4744            if (firstPids != null) {
4745                try {
4746                    int num = firstPids.size();
4747                    for (int i = 0; i < num; i++) {
4748                        synchronized (observer) {
4749                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4750                            observer.wait(200);  // Wait for write-close, give up after 200msec
4751                        }
4752                    }
4753                } catch (InterruptedException e) {
4754                    Slog.wtf(TAG, e);
4755                }
4756            }
4757
4758            // Next collect the stacks of the native pids
4759            if (nativeProcs != null) {
4760                int[] pids = Process.getPidsForCommands(nativeProcs);
4761                if (pids != null) {
4762                    for (int pid : pids) {
4763                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4764                    }
4765                }
4766            }
4767
4768            // Lastly, measure CPU usage.
4769            if (processCpuTracker != null) {
4770                processCpuTracker.init();
4771                System.gc();
4772                processCpuTracker.update();
4773                try {
4774                    synchronized (processCpuTracker) {
4775                        processCpuTracker.wait(500); // measure over 1/2 second.
4776                    }
4777                } catch (InterruptedException e) {
4778                }
4779                processCpuTracker.update();
4780
4781                // We'll take the stack crawls of just the top apps using CPU.
4782                final int N = processCpuTracker.countWorkingStats();
4783                int numProcs = 0;
4784                for (int i=0; i<N && numProcs<5; i++) {
4785                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4786                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4787                        numProcs++;
4788                        try {
4789                            synchronized (observer) {
4790                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4791                                observer.wait(200);  // Wait for write-close, give up after 200msec
4792                            }
4793                        } catch (InterruptedException e) {
4794                            Slog.wtf(TAG, e);
4795                        }
4796
4797                    }
4798                }
4799            }
4800        } finally {
4801            observer.stopWatching();
4802        }
4803    }
4804
4805    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4806        if (true || IS_USER_BUILD) {
4807            return;
4808        }
4809        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4810        if (tracesPath == null || tracesPath.length() == 0) {
4811            return;
4812        }
4813
4814        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4815        StrictMode.allowThreadDiskWrites();
4816        try {
4817            final File tracesFile = new File(tracesPath);
4818            final File tracesDir = tracesFile.getParentFile();
4819            final File tracesTmp = new File(tracesDir, "__tmp__");
4820            try {
4821                if (tracesFile.exists()) {
4822                    tracesTmp.delete();
4823                    tracesFile.renameTo(tracesTmp);
4824                }
4825                StringBuilder sb = new StringBuilder();
4826                Time tobj = new Time();
4827                tobj.set(System.currentTimeMillis());
4828                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4829                sb.append(": ");
4830                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4831                sb.append(" since ");
4832                sb.append(msg);
4833                FileOutputStream fos = new FileOutputStream(tracesFile);
4834                fos.write(sb.toString().getBytes());
4835                if (app == null) {
4836                    fos.write("\n*** No application process!".getBytes());
4837                }
4838                fos.close();
4839                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4840            } catch (IOException e) {
4841                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4842                return;
4843            }
4844
4845            if (app != null) {
4846                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4847                firstPids.add(app.pid);
4848                dumpStackTraces(tracesPath, firstPids, null, null, null);
4849            }
4850
4851            File lastTracesFile = null;
4852            File curTracesFile = null;
4853            for (int i=9; i>=0; i--) {
4854                String name = String.format(Locale.US, "slow%02d.txt", i);
4855                curTracesFile = new File(tracesDir, name);
4856                if (curTracesFile.exists()) {
4857                    if (lastTracesFile != null) {
4858                        curTracesFile.renameTo(lastTracesFile);
4859                    } else {
4860                        curTracesFile.delete();
4861                    }
4862                }
4863                lastTracesFile = curTracesFile;
4864            }
4865            tracesFile.renameTo(curTracesFile);
4866            if (tracesTmp.exists()) {
4867                tracesTmp.renameTo(tracesFile);
4868            }
4869        } finally {
4870            StrictMode.setThreadPolicy(oldPolicy);
4871        }
4872    }
4873
4874    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4875            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4876        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4877        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4878
4879        if (mController != null) {
4880            try {
4881                // 0 == continue, -1 = kill process immediately
4882                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4883                if (res < 0 && app.pid != MY_PID) {
4884                    app.kill("anr", true);
4885                }
4886            } catch (RemoteException e) {
4887                mController = null;
4888                Watchdog.getInstance().setActivityController(null);
4889            }
4890        }
4891
4892        long anrTime = SystemClock.uptimeMillis();
4893        if (MONITOR_CPU_USAGE) {
4894            updateCpuStatsNow();
4895        }
4896
4897        synchronized (this) {
4898            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4899            if (mShuttingDown) {
4900                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4901                return;
4902            } else if (app.notResponding) {
4903                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4904                return;
4905            } else if (app.crashing) {
4906                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4907                return;
4908            }
4909
4910            // In case we come through here for the same app before completing
4911            // this one, mark as anring now so we will bail out.
4912            app.notResponding = true;
4913
4914            // Log the ANR to the event log.
4915            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4916                    app.processName, app.info.flags, annotation);
4917
4918            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4919            firstPids.add(app.pid);
4920
4921            int parentPid = app.pid;
4922            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4923            if (parentPid != app.pid) firstPids.add(parentPid);
4924
4925            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4926
4927            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4928                ProcessRecord r = mLruProcesses.get(i);
4929                if (r != null && r.thread != null) {
4930                    int pid = r.pid;
4931                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4932                        if (r.persistent) {
4933                            firstPids.add(pid);
4934                        } else {
4935                            lastPids.put(pid, Boolean.TRUE);
4936                        }
4937                    }
4938                }
4939            }
4940        }
4941
4942        // Log the ANR to the main log.
4943        StringBuilder info = new StringBuilder();
4944        info.setLength(0);
4945        info.append("ANR in ").append(app.processName);
4946        if (activity != null && activity.shortComponentName != null) {
4947            info.append(" (").append(activity.shortComponentName).append(")");
4948        }
4949        info.append("\n");
4950        info.append("PID: ").append(app.pid).append("\n");
4951        if (annotation != null) {
4952            info.append("Reason: ").append(annotation).append("\n");
4953        }
4954        if (parent != null && parent != activity) {
4955            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4956        }
4957
4958        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4959
4960        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4961                NATIVE_STACKS_OF_INTEREST);
4962
4963        String cpuInfo = null;
4964        if (MONITOR_CPU_USAGE) {
4965            updateCpuStatsNow();
4966            synchronized (mProcessCpuTracker) {
4967                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4968            }
4969            info.append(processCpuTracker.printCurrentLoad());
4970            info.append(cpuInfo);
4971        }
4972
4973        info.append(processCpuTracker.printCurrentState(anrTime));
4974
4975        Slog.e(TAG, info.toString());
4976        if (tracesFile == null) {
4977            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4978            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4979        }
4980
4981        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4982                cpuInfo, tracesFile, null);
4983
4984        if (mController != null) {
4985            try {
4986                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4987                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4988                if (res != 0) {
4989                    if (res < 0 && app.pid != MY_PID) {
4990                        app.kill("anr", true);
4991                    } else {
4992                        synchronized (this) {
4993                            mServices.scheduleServiceTimeoutLocked(app);
4994                        }
4995                    }
4996                    return;
4997                }
4998            } catch (RemoteException e) {
4999                mController = null;
5000                Watchdog.getInstance().setActivityController(null);
5001            }
5002        }
5003
5004        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5005        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5006                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5007
5008        synchronized (this) {
5009            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5010
5011            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5012                app.kill("bg anr", true);
5013                return;
5014            }
5015
5016            // Set the app's notResponding state, and look up the errorReportReceiver
5017            makeAppNotRespondingLocked(app,
5018                    activity != null ? activity.shortComponentName : null,
5019                    annotation != null ? "ANR " + annotation : "ANR",
5020                    info.toString());
5021
5022            // Bring up the infamous App Not Responding dialog
5023            Message msg = Message.obtain();
5024            HashMap<String, Object> map = new HashMap<String, Object>();
5025            msg.what = SHOW_NOT_RESPONDING_MSG;
5026            msg.obj = map;
5027            msg.arg1 = aboveSystem ? 1 : 0;
5028            map.put("app", app);
5029            if (activity != null) {
5030                map.put("activity", activity);
5031            }
5032
5033            mUiHandler.sendMessage(msg);
5034        }
5035    }
5036
5037    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5038        if (!mLaunchWarningShown) {
5039            mLaunchWarningShown = true;
5040            mUiHandler.post(new Runnable() {
5041                @Override
5042                public void run() {
5043                    synchronized (ActivityManagerService.this) {
5044                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5045                        d.show();
5046                        mUiHandler.postDelayed(new Runnable() {
5047                            @Override
5048                            public void run() {
5049                                synchronized (ActivityManagerService.this) {
5050                                    d.dismiss();
5051                                    mLaunchWarningShown = false;
5052                                }
5053                            }
5054                        }, 4000);
5055                    }
5056                }
5057            });
5058        }
5059    }
5060
5061    @Override
5062    public boolean clearApplicationUserData(final String packageName,
5063            final IPackageDataObserver observer, int userId) {
5064        enforceNotIsolatedCaller("clearApplicationUserData");
5065        if (packageName != null && packageName.equals(mDeviceOwnerName)) {
5066            throw new SecurityException("Clearing DeviceOwner data is forbidden.");
5067        }
5068        int uid = Binder.getCallingUid();
5069        int pid = Binder.getCallingPid();
5070        userId = handleIncomingUser(pid, uid,
5071                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5072        long callingId = Binder.clearCallingIdentity();
5073        try {
5074            IPackageManager pm = AppGlobals.getPackageManager();
5075            int pkgUid = -1;
5076            synchronized(this) {
5077                try {
5078                    pkgUid = pm.getPackageUid(packageName, userId);
5079                } catch (RemoteException e) {
5080                }
5081                if (pkgUid == -1) {
5082                    Slog.w(TAG, "Invalid packageName: " + packageName);
5083                    if (observer != null) {
5084                        try {
5085                            observer.onRemoveCompleted(packageName, false);
5086                        } catch (RemoteException e) {
5087                            Slog.i(TAG, "Observer no longer exists.");
5088                        }
5089                    }
5090                    return false;
5091                }
5092                if (uid == pkgUid || checkComponentPermission(
5093                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5094                        pid, uid, -1, true)
5095                        == PackageManager.PERMISSION_GRANTED) {
5096                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5097                } else {
5098                    throw new SecurityException("PID " + pid + " does not have permission "
5099                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5100                                    + " of package " + packageName);
5101                }
5102
5103                // Remove all tasks match the cleared application package and user
5104                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5105                    final TaskRecord tr = mRecentTasks.get(i);
5106                    final String taskPackageName =
5107                            tr.getBaseIntent().getComponent().getPackageName();
5108                    if (tr.userId != userId) continue;
5109                    if (!taskPackageName.equals(packageName)) continue;
5110                    removeTaskByIdLocked(tr.taskId, false);
5111                }
5112            }
5113
5114            try {
5115                // Clear application user data
5116                pm.clearApplicationUserData(packageName, observer, userId);
5117
5118                synchronized(this) {
5119                    // Remove all permissions granted from/to this package
5120                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5121                }
5122
5123                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5124                        Uri.fromParts("package", packageName, null));
5125                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5126                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5127                        null, null, 0, null, null, null, null, false, false, userId);
5128            } catch (RemoteException e) {
5129            }
5130        } finally {
5131            Binder.restoreCallingIdentity(callingId);
5132        }
5133        return true;
5134    }
5135
5136    @Override
5137    public void killBackgroundProcesses(final String packageName, int userId) {
5138        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5139                != PackageManager.PERMISSION_GRANTED &&
5140                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5141                        != PackageManager.PERMISSION_GRANTED) {
5142            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5143                    + Binder.getCallingPid()
5144                    + ", uid=" + Binder.getCallingUid()
5145                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5146            Slog.w(TAG, msg);
5147            throw new SecurityException(msg);
5148        }
5149
5150        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5151                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5152        long callingId = Binder.clearCallingIdentity();
5153        try {
5154            IPackageManager pm = AppGlobals.getPackageManager();
5155            synchronized(this) {
5156                int appId = -1;
5157                try {
5158                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5159                } catch (RemoteException e) {
5160                }
5161                if (appId == -1) {
5162                    Slog.w(TAG, "Invalid packageName: " + packageName);
5163                    return;
5164                }
5165                killPackageProcessesLocked(packageName, appId, userId,
5166                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5167            }
5168        } finally {
5169            Binder.restoreCallingIdentity(callingId);
5170        }
5171    }
5172
5173    @Override
5174    public void killAllBackgroundProcesses() {
5175        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5176                != PackageManager.PERMISSION_GRANTED) {
5177            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5178                    + Binder.getCallingPid()
5179                    + ", uid=" + Binder.getCallingUid()
5180                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5181            Slog.w(TAG, msg);
5182            throw new SecurityException(msg);
5183        }
5184
5185        long callingId = Binder.clearCallingIdentity();
5186        try {
5187            synchronized(this) {
5188                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5189                final int NP = mProcessNames.getMap().size();
5190                for (int ip=0; ip<NP; ip++) {
5191                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5192                    final int NA = apps.size();
5193                    for (int ia=0; ia<NA; ia++) {
5194                        ProcessRecord app = apps.valueAt(ia);
5195                        if (app.persistent) {
5196                            // we don't kill persistent processes
5197                            continue;
5198                        }
5199                        if (app.removed) {
5200                            procs.add(app);
5201                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5202                            app.removed = true;
5203                            procs.add(app);
5204                        }
5205                    }
5206                }
5207
5208                int N = procs.size();
5209                for (int i=0; i<N; i++) {
5210                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5211                }
5212                mAllowLowerMemLevel = true;
5213                updateOomAdjLocked();
5214                doLowMemReportIfNeededLocked(null);
5215            }
5216        } finally {
5217            Binder.restoreCallingIdentity(callingId);
5218        }
5219    }
5220
5221    @Override
5222    public void forceStopPackage(final String packageName, int userId) {
5223        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5224                != PackageManager.PERMISSION_GRANTED) {
5225            String msg = "Permission Denial: forceStopPackage() from pid="
5226                    + Binder.getCallingPid()
5227                    + ", uid=" + Binder.getCallingUid()
5228                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5229            Slog.w(TAG, msg);
5230            throw new SecurityException(msg);
5231        }
5232        final int callingPid = Binder.getCallingPid();
5233        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5234                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5235        long callingId = Binder.clearCallingIdentity();
5236        try {
5237            IPackageManager pm = AppGlobals.getPackageManager();
5238            synchronized(this) {
5239                int[] users = userId == UserHandle.USER_ALL
5240                        ? getUsersLocked() : new int[] { userId };
5241                for (int user : users) {
5242                    int pkgUid = -1;
5243                    try {
5244                        pkgUid = pm.getPackageUid(packageName, user);
5245                    } catch (RemoteException e) {
5246                    }
5247                    if (pkgUid == -1) {
5248                        Slog.w(TAG, "Invalid packageName: " + packageName);
5249                        continue;
5250                    }
5251                    try {
5252                        pm.setPackageStoppedState(packageName, true, user);
5253                    } catch (RemoteException e) {
5254                    } catch (IllegalArgumentException e) {
5255                        Slog.w(TAG, "Failed trying to unstop package "
5256                                + packageName + ": " + e);
5257                    }
5258                    if (isUserRunningLocked(user, false)) {
5259                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5260                    }
5261                }
5262            }
5263        } finally {
5264            Binder.restoreCallingIdentity(callingId);
5265        }
5266    }
5267
5268    @Override
5269    public void addPackageDependency(String packageName) {
5270        synchronized (this) {
5271            int callingPid = Binder.getCallingPid();
5272            if (callingPid == Process.myPid()) {
5273                //  Yeah, um, no.
5274                return;
5275            }
5276            ProcessRecord proc;
5277            synchronized (mPidsSelfLocked) {
5278                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5279            }
5280            if (proc != null) {
5281                if (proc.pkgDeps == null) {
5282                    proc.pkgDeps = new ArraySet<String>(1);
5283                }
5284                proc.pkgDeps.add(packageName);
5285            }
5286        }
5287    }
5288
5289    /*
5290     * The pkg name and app id have to be specified.
5291     */
5292    @Override
5293    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5294        if (pkg == null) {
5295            return;
5296        }
5297        // Make sure the uid is valid.
5298        if (appid < 0) {
5299            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5300            return;
5301        }
5302        int callerUid = Binder.getCallingUid();
5303        // Only the system server can kill an application
5304        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5305            // Post an aysnc message to kill the application
5306            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5307            msg.arg1 = appid;
5308            msg.arg2 = 0;
5309            Bundle bundle = new Bundle();
5310            bundle.putString("pkg", pkg);
5311            bundle.putString("reason", reason);
5312            msg.obj = bundle;
5313            mHandler.sendMessage(msg);
5314        } else {
5315            throw new SecurityException(callerUid + " cannot kill pkg: " +
5316                    pkg);
5317        }
5318    }
5319
5320    @Override
5321    public void closeSystemDialogs(String reason) {
5322        enforceNotIsolatedCaller("closeSystemDialogs");
5323
5324        final int pid = Binder.getCallingPid();
5325        final int uid = Binder.getCallingUid();
5326        final long origId = Binder.clearCallingIdentity();
5327        try {
5328            synchronized (this) {
5329                // Only allow this from foreground processes, so that background
5330                // applications can't abuse it to prevent system UI from being shown.
5331                if (uid >= Process.FIRST_APPLICATION_UID) {
5332                    ProcessRecord proc;
5333                    synchronized (mPidsSelfLocked) {
5334                        proc = mPidsSelfLocked.get(pid);
5335                    }
5336                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5337                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5338                                + " from background process " + proc);
5339                        return;
5340                    }
5341                }
5342                closeSystemDialogsLocked(reason);
5343            }
5344        } finally {
5345            Binder.restoreCallingIdentity(origId);
5346        }
5347    }
5348
5349    void closeSystemDialogsLocked(String reason) {
5350        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5351        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5352                | Intent.FLAG_RECEIVER_FOREGROUND);
5353        if (reason != null) {
5354            intent.putExtra("reason", reason);
5355        }
5356        mWindowManager.closeSystemDialogs(reason);
5357
5358        mStackSupervisor.closeSystemDialogsLocked();
5359
5360        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5361                AppOpsManager.OP_NONE, null, false, false,
5362                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5363    }
5364
5365    @Override
5366    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5367        enforceNotIsolatedCaller("getProcessMemoryInfo");
5368        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5369        for (int i=pids.length-1; i>=0; i--) {
5370            ProcessRecord proc;
5371            int oomAdj;
5372            synchronized (this) {
5373                synchronized (mPidsSelfLocked) {
5374                    proc = mPidsSelfLocked.get(pids[i]);
5375                    oomAdj = proc != null ? proc.setAdj : 0;
5376                }
5377            }
5378            infos[i] = new Debug.MemoryInfo();
5379            Debug.getMemoryInfo(pids[i], infos[i]);
5380            if (proc != null) {
5381                synchronized (this) {
5382                    if (proc.thread != null && proc.setAdj == oomAdj) {
5383                        // Record this for posterity if the process has been stable.
5384                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5385                                infos[i].getTotalUss(), false, proc.pkgList);
5386                    }
5387                }
5388            }
5389        }
5390        return infos;
5391    }
5392
5393    @Override
5394    public long[] getProcessPss(int[] pids) {
5395        enforceNotIsolatedCaller("getProcessPss");
5396        long[] pss = new long[pids.length];
5397        for (int i=pids.length-1; i>=0; i--) {
5398            ProcessRecord proc;
5399            int oomAdj;
5400            synchronized (this) {
5401                synchronized (mPidsSelfLocked) {
5402                    proc = mPidsSelfLocked.get(pids[i]);
5403                    oomAdj = proc != null ? proc.setAdj : 0;
5404                }
5405            }
5406            long[] tmpUss = new long[1];
5407            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5408            if (proc != null) {
5409                synchronized (this) {
5410                    if (proc.thread != null && proc.setAdj == oomAdj) {
5411                        // Record this for posterity if the process has been stable.
5412                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5413                    }
5414                }
5415            }
5416        }
5417        return pss;
5418    }
5419
5420    @Override
5421    public void killApplicationProcess(String processName, int uid) {
5422        if (processName == null) {
5423            return;
5424        }
5425
5426        int callerUid = Binder.getCallingUid();
5427        // Only the system server can kill an application
5428        if (callerUid == Process.SYSTEM_UID) {
5429            synchronized (this) {
5430                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5431                if (app != null && app.thread != null) {
5432                    try {
5433                        app.thread.scheduleSuicide();
5434                    } catch (RemoteException e) {
5435                        // If the other end already died, then our work here is done.
5436                    }
5437                } else {
5438                    Slog.w(TAG, "Process/uid not found attempting kill of "
5439                            + processName + " / " + uid);
5440                }
5441            }
5442        } else {
5443            throw new SecurityException(callerUid + " cannot kill app process: " +
5444                    processName);
5445        }
5446    }
5447
5448    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5449        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5450                false, true, false, false, UserHandle.getUserId(uid), reason);
5451        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5452                Uri.fromParts("package", packageName, null));
5453        if (!mProcessesReady) {
5454            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5455                    | Intent.FLAG_RECEIVER_FOREGROUND);
5456        }
5457        intent.putExtra(Intent.EXTRA_UID, uid);
5458        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5459        broadcastIntentLocked(null, null, intent,
5460                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5461                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5462    }
5463
5464    private void forceStopUserLocked(int userId, String reason) {
5465        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5466        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5467        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5468                | Intent.FLAG_RECEIVER_FOREGROUND);
5469        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5470        broadcastIntentLocked(null, null, intent,
5471                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5472                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5473    }
5474
5475    private final boolean killPackageProcessesLocked(String packageName, int appId,
5476            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5477            boolean doit, boolean evenPersistent, String reason) {
5478        ArrayList<ProcessRecord> procs = new ArrayList<>();
5479
5480        // Remove all processes this package may have touched: all with the
5481        // same UID (except for the system or root user), and all whose name
5482        // matches the package name.
5483        final int NP = mProcessNames.getMap().size();
5484        for (int ip=0; ip<NP; ip++) {
5485            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5486            final int NA = apps.size();
5487            for (int ia=0; ia<NA; ia++) {
5488                ProcessRecord app = apps.valueAt(ia);
5489                if (app.persistent && !evenPersistent) {
5490                    // we don't kill persistent processes
5491                    continue;
5492                }
5493                if (app.removed) {
5494                    if (doit) {
5495                        procs.add(app);
5496                    }
5497                    continue;
5498                }
5499
5500                // Skip process if it doesn't meet our oom adj requirement.
5501                if (app.setAdj < minOomAdj) {
5502                    continue;
5503                }
5504
5505                // If no package is specified, we call all processes under the
5506                // give user id.
5507                if (packageName == null) {
5508                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5509                        continue;
5510                    }
5511                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5512                        continue;
5513                    }
5514                // Package has been specified, we want to hit all processes
5515                // that match it.  We need to qualify this by the processes
5516                // that are running under the specified app and user ID.
5517                } else {
5518                    final boolean isDep = app.pkgDeps != null
5519                            && app.pkgDeps.contains(packageName);
5520                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5521                        continue;
5522                    }
5523                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5524                        continue;
5525                    }
5526                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5527                        continue;
5528                    }
5529                }
5530
5531                // Process has passed all conditions, kill it!
5532                if (!doit) {
5533                    return true;
5534                }
5535                app.removed = true;
5536                procs.add(app);
5537            }
5538        }
5539
5540        int N = procs.size();
5541        for (int i=0; i<N; i++) {
5542            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5543        }
5544        updateOomAdjLocked();
5545        return N > 0;
5546    }
5547
5548    private void cleanupDisabledPackageComponentsLocked(
5549            String packageName, int userId, String[] changedClasses) {
5550
5551        Set<String> disabledClasses = null;
5552        boolean packageDisabled = false;
5553        IPackageManager pm = AppGlobals.getPackageManager();
5554
5555        if (changedClasses == null) {
5556            // Nothing changed...
5557            return;
5558        }
5559
5560        // Determine enable/disable state of the package and its components.
5561        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5562        for (int i = changedClasses.length - 1; i >= 0; i--) {
5563            final String changedClass = changedClasses[i];
5564
5565            if (changedClass.equals(packageName)) {
5566                try {
5567                    // Entire package setting changed
5568                    enabled = pm.getApplicationEnabledSetting(packageName,
5569                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5570                } catch (Exception e) {
5571                    // No such package/component; probably racing with uninstall.  In any
5572                    // event it means we have nothing further to do here.
5573                    return;
5574                }
5575                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5576                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5577                if (packageDisabled) {
5578                    // Entire package is disabled.
5579                    // No need to continue to check component states.
5580                    disabledClasses = null;
5581                    break;
5582                }
5583            } else {
5584                try {
5585                    enabled = pm.getComponentEnabledSetting(
5586                            new ComponentName(packageName, changedClass),
5587                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5588                } catch (Exception e) {
5589                    // As above, probably racing with uninstall.
5590                    return;
5591                }
5592                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5593                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5594                    if (disabledClasses == null) {
5595                        disabledClasses = new ArraySet<>(changedClasses.length);
5596                    }
5597                    disabledClasses.add(changedClass);
5598                }
5599            }
5600        }
5601
5602        if (!packageDisabled && disabledClasses == null) {
5603            // Nothing to do here...
5604            return;
5605        }
5606
5607        // Clean-up disabled activities.
5608        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5609                packageName, disabledClasses, true, false, userId) && mBooted) {
5610            mStackSupervisor.resumeTopActivitiesLocked();
5611            mStackSupervisor.scheduleIdleLocked();
5612        }
5613
5614        // Clean-up disabled tasks
5615        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5616
5617        // Clean-up disabled services.
5618        mServices.bringDownDisabledPackageServicesLocked(
5619                packageName, disabledClasses, userId, false, true);
5620
5621        // Clean-up disabled providers.
5622        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5623        mProviderMap.collectPackageProvidersLocked(
5624                packageName, disabledClasses, true, false, userId, providers);
5625        for (int i = providers.size() - 1; i >= 0; i--) {
5626            removeDyingProviderLocked(null, providers.get(i), true);
5627        }
5628
5629        // Clean-up disabled broadcast receivers.
5630        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5631            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5632                    packageName, disabledClasses, userId, true);
5633        }
5634
5635    }
5636
5637    private final boolean forceStopPackageLocked(String packageName, int appId,
5638            boolean callerWillRestart, boolean purgeCache, boolean doit,
5639            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5640        int i;
5641
5642        if (userId == UserHandle.USER_ALL && packageName == null) {
5643            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5644        }
5645
5646        if (appId < 0 && packageName != null) {
5647            try {
5648                appId = UserHandle.getAppId(
5649                        AppGlobals.getPackageManager().getPackageUid(packageName, 0));
5650            } catch (RemoteException e) {
5651            }
5652        }
5653
5654        if (doit) {
5655            if (packageName != null) {
5656                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5657                        + " user=" + userId + ": " + reason);
5658            } else {
5659                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5660            }
5661
5662            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5663            for (int ip = pmap.size() - 1; ip >= 0; ip--) {
5664                SparseArray<Long> ba = pmap.valueAt(ip);
5665                for (i = ba.size() - 1; i >= 0; i--) {
5666                    boolean remove = false;
5667                    final int entUid = ba.keyAt(i);
5668                    if (packageName != null) {
5669                        if (userId == UserHandle.USER_ALL) {
5670                            if (UserHandle.getAppId(entUid) == appId) {
5671                                remove = true;
5672                            }
5673                        } else {
5674                            if (entUid == UserHandle.getUid(userId, appId)) {
5675                                remove = true;
5676                            }
5677                        }
5678                    } else if (UserHandle.getUserId(entUid) == userId) {
5679                        remove = true;
5680                    }
5681                    if (remove) {
5682                        ba.removeAt(i);
5683                    }
5684                }
5685                if (ba.size() == 0) {
5686                    pmap.removeAt(ip);
5687                }
5688            }
5689        }
5690
5691        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5692                -100, callerWillRestart, true, doit, evenPersistent,
5693                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5694
5695        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5696                packageName, null, doit, evenPersistent, userId)) {
5697            if (!doit) {
5698                return true;
5699            }
5700            didSomething = true;
5701        }
5702
5703        if (mServices.bringDownDisabledPackageServicesLocked(
5704                packageName, null, userId, evenPersistent, doit)) {
5705            if (!doit) {
5706                return true;
5707            }
5708            didSomething = true;
5709        }
5710
5711        if (packageName == null) {
5712            // Remove all sticky broadcasts from this user.
5713            mStickyBroadcasts.remove(userId);
5714        }
5715
5716        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5717        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5718                userId, providers)) {
5719            if (!doit) {
5720                return true;
5721            }
5722            didSomething = true;
5723        }
5724        for (i = providers.size() - 1; i >= 0; i--) {
5725            removeDyingProviderLocked(null, providers.get(i), true);
5726        }
5727
5728        // Remove transient permissions granted from/to this package/user
5729        removeUriPermissionsForPackageLocked(packageName, userId, false);
5730
5731        if (doit) {
5732            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
5733                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5734                        packageName, null, userId, doit);
5735            }
5736        }
5737
5738        if (packageName == null || uninstalling) {
5739            // Remove pending intents.  For now we only do this when force
5740            // stopping users, because we have some problems when doing this
5741            // for packages -- app widgets are not currently cleaned up for
5742            // such packages, so they can be left with bad pending intents.
5743            if (mIntentSenderRecords.size() > 0) {
5744                Iterator<WeakReference<PendingIntentRecord>> it
5745                        = mIntentSenderRecords.values().iterator();
5746                while (it.hasNext()) {
5747                    WeakReference<PendingIntentRecord> wpir = it.next();
5748                    if (wpir == null) {
5749                        it.remove();
5750                        continue;
5751                    }
5752                    PendingIntentRecord pir = wpir.get();
5753                    if (pir == null) {
5754                        it.remove();
5755                        continue;
5756                    }
5757                    if (packageName == null) {
5758                        // Stopping user, remove all objects for the user.
5759                        if (pir.key.userId != userId) {
5760                            // Not the same user, skip it.
5761                            continue;
5762                        }
5763                    } else {
5764                        if (UserHandle.getAppId(pir.uid) != appId) {
5765                            // Different app id, skip it.
5766                            continue;
5767                        }
5768                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5769                            // Different user, skip it.
5770                            continue;
5771                        }
5772                        if (!pir.key.packageName.equals(packageName)) {
5773                            // Different package, skip it.
5774                            continue;
5775                        }
5776                    }
5777                    if (!doit) {
5778                        return true;
5779                    }
5780                    didSomething = true;
5781                    it.remove();
5782                    pir.canceled = true;
5783                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5784                        pir.key.activity.pendingResults.remove(pir.ref);
5785                    }
5786                }
5787            }
5788        }
5789
5790        if (doit) {
5791            if (purgeCache && packageName != null) {
5792                AttributeCache ac = AttributeCache.instance();
5793                if (ac != null) {
5794                    ac.removePackage(packageName);
5795                }
5796            }
5797            if (mBooted) {
5798                mStackSupervisor.resumeTopActivitiesLocked();
5799                mStackSupervisor.scheduleIdleLocked();
5800            }
5801        }
5802
5803        return didSomething;
5804    }
5805
5806    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
5807        ProcessRecord old = mProcessNames.remove(name, uid);
5808        if (old != null) {
5809            old.uidRecord.numProcs--;
5810            if (old.uidRecord.numProcs == 0) {
5811                // No more processes using this uid, tell clients it is gone.
5812                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5813                        "No more processes in " + old.uidRecord);
5814                enqueueUidChangeLocked(old.uidRecord, true);
5815                mActiveUids.remove(uid);
5816            }
5817            old.uidRecord = null;
5818        }
5819        mIsolatedProcesses.remove(uid);
5820        return old;
5821    }
5822
5823    private final void addProcessNameLocked(ProcessRecord proc) {
5824        // We shouldn't already have a process under this name, but just in case we
5825        // need to clean up whatever may be there now.
5826        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
5827        if (old == proc && proc.persistent) {
5828            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
5829            Slog.w(TAG, "Re-adding persistent process " + proc);
5830        } else if (old != null) {
5831            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
5832        }
5833        UidRecord uidRec = mActiveUids.get(proc.uid);
5834        if (uidRec == null) {
5835            uidRec = new UidRecord(proc.uid);
5836            // This is the first appearance of the uid, report it now!
5837            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5838                    "Creating new process uid: " + uidRec);
5839            mActiveUids.put(proc.uid, uidRec);
5840            enqueueUidChangeLocked(uidRec, false);
5841        }
5842        proc.uidRecord = uidRec;
5843        uidRec.numProcs++;
5844        mProcessNames.put(proc.processName, proc.uid, proc);
5845        if (proc.isolated) {
5846            mIsolatedProcesses.put(proc.uid, proc);
5847        }
5848    }
5849
5850    private final boolean removeProcessLocked(ProcessRecord app,
5851            boolean callerWillRestart, boolean allowRestart, String reason) {
5852        final String name = app.processName;
5853        final int uid = app.uid;
5854        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
5855            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
5856
5857        removeProcessNameLocked(name, uid);
5858        if (mHeavyWeightProcess == app) {
5859            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5860                    mHeavyWeightProcess.userId, 0));
5861            mHeavyWeightProcess = null;
5862        }
5863        boolean needRestart = false;
5864        if (app.pid > 0 && app.pid != MY_PID) {
5865            int pid = app.pid;
5866            synchronized (mPidsSelfLocked) {
5867                mPidsSelfLocked.remove(pid);
5868                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5869            }
5870            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5871            if (app.isolated) {
5872                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5873            }
5874            boolean willRestart = false;
5875            if (app.persistent && !app.isolated) {
5876                if (!callerWillRestart) {
5877                    willRestart = true;
5878                } else {
5879                    needRestart = true;
5880                }
5881            }
5882            app.kill(reason, true);
5883            handleAppDiedLocked(app, willRestart, allowRestart);
5884            if (willRestart) {
5885                removeLruProcessLocked(app);
5886                addAppLocked(app.info, false, null /* ABI override */);
5887            }
5888        } else {
5889            mRemovedProcesses.add(app);
5890        }
5891
5892        return needRestart;
5893    }
5894
5895    private final void processStartTimedOutLocked(ProcessRecord app) {
5896        final int pid = app.pid;
5897        boolean gone = false;
5898        synchronized (mPidsSelfLocked) {
5899            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5900            if (knownApp != null && knownApp.thread == null) {
5901                mPidsSelfLocked.remove(pid);
5902                gone = true;
5903            }
5904        }
5905
5906        if (gone) {
5907            Slog.w(TAG, "Process " + app + " failed to attach");
5908            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5909                    pid, app.uid, app.processName);
5910            removeProcessNameLocked(app.processName, app.uid);
5911            if (mHeavyWeightProcess == app) {
5912                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5913                        mHeavyWeightProcess.userId, 0));
5914                mHeavyWeightProcess = null;
5915            }
5916            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5917            if (app.isolated) {
5918                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5919            }
5920            // Take care of any launching providers waiting for this process.
5921            checkAppInLaunchingProvidersLocked(app, true);
5922            // Take care of any services that are waiting for the process.
5923            mServices.processStartTimedOutLocked(app);
5924            app.kill("start timeout", true);
5925            removeLruProcessLocked(app);
5926            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5927                Slog.w(TAG, "Unattached app died before backup, skipping");
5928                try {
5929                    IBackupManager bm = IBackupManager.Stub.asInterface(
5930                            ServiceManager.getService(Context.BACKUP_SERVICE));
5931                    bm.agentDisconnected(app.info.packageName);
5932                } catch (RemoteException e) {
5933                    // Can't happen; the backup manager is local
5934                }
5935            }
5936            if (isPendingBroadcastProcessLocked(pid)) {
5937                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5938                skipPendingBroadcastLocked(pid);
5939            }
5940        } else {
5941            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5942        }
5943    }
5944
5945    private final boolean attachApplicationLocked(IApplicationThread thread,
5946            int pid) {
5947
5948        // Find the application record that is being attached...  either via
5949        // the pid if we are running in multiple processes, or just pull the
5950        // next app record if we are emulating process with anonymous threads.
5951        ProcessRecord app;
5952        if (pid != MY_PID && pid >= 0) {
5953            synchronized (mPidsSelfLocked) {
5954                app = mPidsSelfLocked.get(pid);
5955            }
5956        } else {
5957            app = null;
5958        }
5959
5960        if (app == null) {
5961            Slog.w(TAG, "No pending application record for pid " + pid
5962                    + " (IApplicationThread " + thread + "); dropping process");
5963            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5964            if (pid > 0 && pid != MY_PID) {
5965                Process.killProcessQuiet(pid);
5966                //TODO: killProcessGroup(app.info.uid, pid);
5967            } else {
5968                try {
5969                    thread.scheduleExit();
5970                } catch (Exception e) {
5971                    // Ignore exceptions.
5972                }
5973            }
5974            return false;
5975        }
5976
5977        // If this application record is still attached to a previous
5978        // process, clean it up now.
5979        if (app.thread != null) {
5980            handleAppDiedLocked(app, true, true);
5981        }
5982
5983        // Tell the process all about itself.
5984
5985        if (DEBUG_ALL) Slog.v(
5986                TAG, "Binding process pid " + pid + " to record " + app);
5987
5988        final String processName = app.processName;
5989        try {
5990            AppDeathRecipient adr = new AppDeathRecipient(
5991                    app, pid, thread);
5992            thread.asBinder().linkToDeath(adr, 0);
5993            app.deathRecipient = adr;
5994        } catch (RemoteException e) {
5995            app.resetPackageList(mProcessStats);
5996            startProcessLocked(app, "link fail", processName);
5997            return false;
5998        }
5999
6000        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6001
6002        app.makeActive(thread, mProcessStats);
6003        app.curAdj = app.setAdj = -100;
6004        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6005        app.forcingToForeground = null;
6006        updateProcessForegroundLocked(app, false, false);
6007        app.hasShownUi = false;
6008        app.debugging = false;
6009        app.cached = false;
6010        app.killedByAm = false;
6011
6012        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6013
6014        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6015        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6016
6017        if (!normalMode) {
6018            Slog.i(TAG, "Launching preboot mode app: " + app);
6019        }
6020
6021        if (DEBUG_ALL) Slog.v(
6022            TAG, "New app record " + app
6023            + " thread=" + thread.asBinder() + " pid=" + pid);
6024        try {
6025            int testMode = IApplicationThread.DEBUG_OFF;
6026            if (mDebugApp != null && mDebugApp.equals(processName)) {
6027                testMode = mWaitForDebugger
6028                    ? IApplicationThread.DEBUG_WAIT
6029                    : IApplicationThread.DEBUG_ON;
6030                app.debugging = true;
6031                if (mDebugTransient) {
6032                    mDebugApp = mOrigDebugApp;
6033                    mWaitForDebugger = mOrigWaitForDebugger;
6034                }
6035            }
6036            String profileFile = app.instrumentationProfileFile;
6037            ParcelFileDescriptor profileFd = null;
6038            int samplingInterval = 0;
6039            boolean profileAutoStop = false;
6040            if (mProfileApp != null && mProfileApp.equals(processName)) {
6041                mProfileProc = app;
6042                profileFile = mProfileFile;
6043                profileFd = mProfileFd;
6044                samplingInterval = mSamplingInterval;
6045                profileAutoStop = mAutoStopProfiler;
6046            }
6047            boolean enableOpenGlTrace = false;
6048            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6049                enableOpenGlTrace = true;
6050                mOpenGlTraceApp = null;
6051            }
6052            boolean enableTrackAllocation = false;
6053            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6054                enableTrackAllocation = true;
6055                mTrackAllocationApp = null;
6056            }
6057
6058            // If the app is being launched for restore or full backup, set it up specially
6059            boolean isRestrictedBackupMode = false;
6060            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6061                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6062                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6063                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6064            }
6065
6066            ensurePackageDexOpt(app.instrumentationInfo != null
6067                    ? app.instrumentationInfo.packageName
6068                    : app.info.packageName);
6069            if (app.instrumentationClass != null) {
6070                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6071            }
6072            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6073                    + processName + " with config " + mConfiguration);
6074            ApplicationInfo appInfo = app.instrumentationInfo != null
6075                    ? app.instrumentationInfo : app.info;
6076            app.compat = compatibilityInfoForPackageLocked(appInfo);
6077            if (profileFd != null) {
6078                profileFd = profileFd.dup();
6079            }
6080            ProfilerInfo profilerInfo = profileFile == null ? null
6081                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6082            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6083                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6084                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6085                    enableTrackAllocation, isRestrictedBackupMode || !normalMode, app.persistent,
6086                    new Configuration(mConfiguration), app.compat,
6087                    getCommonServicesLocked(app.isolated),
6088                    mCoreSettingsObserver.getCoreSettingsLocked());
6089            updateLruProcessLocked(app, false, null);
6090            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6091        } catch (Exception e) {
6092            // todo: Yikes!  What should we do?  For now we will try to
6093            // start another process, but that could easily get us in
6094            // an infinite loop of restarting processes...
6095            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6096
6097            app.resetPackageList(mProcessStats);
6098            app.unlinkDeathRecipient();
6099            startProcessLocked(app, "bind fail", processName);
6100            return false;
6101        }
6102
6103        // Remove this record from the list of starting applications.
6104        mPersistentStartingProcesses.remove(app);
6105        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6106                "Attach application locked removing on hold: " + app);
6107        mProcessesOnHold.remove(app);
6108
6109        boolean badApp = false;
6110        boolean didSomething = false;
6111
6112        // See if the top visible activity is waiting to run in this process...
6113        if (normalMode) {
6114            try {
6115                if (mStackSupervisor.attachApplicationLocked(app)) {
6116                    didSomething = true;
6117                }
6118            } catch (Exception e) {
6119                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6120                badApp = true;
6121            }
6122        }
6123
6124        // Find any services that should be running in this process...
6125        if (!badApp) {
6126            try {
6127                didSomething |= mServices.attachApplicationLocked(app, processName);
6128            } catch (Exception e) {
6129                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6130                badApp = true;
6131            }
6132        }
6133
6134        // Check if a next-broadcast receiver is in this process...
6135        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6136            try {
6137                didSomething |= sendPendingBroadcastsLocked(app);
6138            } catch (Exception e) {
6139                // If the app died trying to launch the receiver we declare it 'bad'
6140                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6141                badApp = true;
6142            }
6143        }
6144
6145        // Check whether the next backup agent is in this process...
6146        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6147            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6148                    "New app is backup target, launching agent for " + app);
6149            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6150            try {
6151                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6152                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6153                        mBackupTarget.backupMode);
6154            } catch (Exception e) {
6155                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6156                badApp = true;
6157            }
6158        }
6159
6160        if (badApp) {
6161            app.kill("error during init", true);
6162            handleAppDiedLocked(app, false, true);
6163            return false;
6164        }
6165
6166        if (!didSomething) {
6167            updateOomAdjLocked();
6168        }
6169
6170        return true;
6171    }
6172
6173    @Override
6174    public final void attachApplication(IApplicationThread thread) {
6175        synchronized (this) {
6176            int callingPid = Binder.getCallingPid();
6177            final long origId = Binder.clearCallingIdentity();
6178            attachApplicationLocked(thread, callingPid);
6179            Binder.restoreCallingIdentity(origId);
6180        }
6181    }
6182
6183    @Override
6184    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6185        final long origId = Binder.clearCallingIdentity();
6186        synchronized (this) {
6187            ActivityStack stack = ActivityRecord.getStackLocked(token);
6188            if (stack != null) {
6189                ActivityRecord r =
6190                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6191                if (stopProfiling) {
6192                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6193                        try {
6194                            mProfileFd.close();
6195                        } catch (IOException e) {
6196                        }
6197                        clearProfilerLocked();
6198                    }
6199                }
6200            }
6201        }
6202        Binder.restoreCallingIdentity(origId);
6203    }
6204
6205    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6206        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6207                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6208    }
6209
6210    void enableScreenAfterBoot() {
6211        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6212                SystemClock.uptimeMillis());
6213        mWindowManager.enableScreenAfterBoot();
6214
6215        synchronized (this) {
6216            updateEventDispatchingLocked();
6217        }
6218    }
6219
6220    @Override
6221    public void showBootMessage(final CharSequence msg, final boolean always) {
6222        if (Binder.getCallingUid() != Process.myUid()) {
6223            // These days only the core system can call this, so apps can't get in
6224            // the way of what we show about running them.
6225        }
6226        mWindowManager.showBootMessage(msg, always);
6227    }
6228
6229    @Override
6230    public void keyguardWaitingForActivityDrawn() {
6231        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6232        final long token = Binder.clearCallingIdentity();
6233        try {
6234            synchronized (this) {
6235                if (DEBUG_LOCKSCREEN) logLockScreen("");
6236                mWindowManager.keyguardWaitingForActivityDrawn();
6237                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6238                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6239                    updateSleepIfNeededLocked();
6240                }
6241            }
6242        } finally {
6243            Binder.restoreCallingIdentity(token);
6244        }
6245    }
6246
6247    @Override
6248    public void keyguardGoingAway(boolean disableWindowAnimations,
6249            boolean keyguardGoingToNotificationShade) {
6250        enforceNotIsolatedCaller("keyguardGoingAway");
6251        final long token = Binder.clearCallingIdentity();
6252        try {
6253            synchronized (this) {
6254                if (DEBUG_LOCKSCREEN) logLockScreen("");
6255                mWindowManager.keyguardGoingAway(disableWindowAnimations,
6256                        keyguardGoingToNotificationShade);
6257                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6258                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6259                    updateSleepIfNeededLocked();
6260                }
6261            }
6262        } finally {
6263            Binder.restoreCallingIdentity(token);
6264        }
6265    }
6266
6267    final void finishBooting() {
6268        synchronized (this) {
6269            if (!mBootAnimationComplete) {
6270                mCallFinishBooting = true;
6271                return;
6272            }
6273            mCallFinishBooting = false;
6274        }
6275
6276        ArraySet<String> completedIsas = new ArraySet<String>();
6277        for (String abi : Build.SUPPORTED_ABIS) {
6278            Process.establishZygoteConnectionForAbi(abi);
6279            final String instructionSet = VMRuntime.getInstructionSet(abi);
6280            if (!completedIsas.contains(instructionSet)) {
6281                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6282                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6283                }
6284                completedIsas.add(instructionSet);
6285            }
6286        }
6287
6288        IntentFilter pkgFilter = new IntentFilter();
6289        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6290        pkgFilter.addDataScheme("package");
6291        mContext.registerReceiver(new BroadcastReceiver() {
6292            @Override
6293            public void onReceive(Context context, Intent intent) {
6294                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6295                if (pkgs != null) {
6296                    for (String pkg : pkgs) {
6297                        synchronized (ActivityManagerService.this) {
6298                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6299                                    0, "query restart")) {
6300                                setResultCode(Activity.RESULT_OK);
6301                                return;
6302                            }
6303                        }
6304                    }
6305                }
6306            }
6307        }, pkgFilter);
6308
6309        IntentFilter dumpheapFilter = new IntentFilter();
6310        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6311        mContext.registerReceiver(new BroadcastReceiver() {
6312            @Override
6313            public void onReceive(Context context, Intent intent) {
6314                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6315                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6316                } else {
6317                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6318                }
6319            }
6320        }, dumpheapFilter);
6321
6322        // Let system services know.
6323        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6324
6325        synchronized (this) {
6326            // Ensure that any processes we had put on hold are now started
6327            // up.
6328            final int NP = mProcessesOnHold.size();
6329            if (NP > 0) {
6330                ArrayList<ProcessRecord> procs =
6331                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6332                for (int ip=0; ip<NP; ip++) {
6333                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6334                            + procs.get(ip));
6335                    startProcessLocked(procs.get(ip), "on-hold", null);
6336                }
6337            }
6338
6339            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6340                // Start looking for apps that are abusing wake locks.
6341                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6342                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6343                // Tell anyone interested that we are done booting!
6344                SystemProperties.set("sys.boot_completed", "1");
6345
6346                // And trigger dev.bootcomplete if we are not showing encryption progress
6347                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6348                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6349                    SystemProperties.set("dev.bootcomplete", "1");
6350                }
6351                for (int i=0; i<mStartedUsers.size(); i++) {
6352                    UserState uss = mStartedUsers.valueAt(i);
6353                    if (uss.mState == UserState.STATE_BOOTING) {
6354                        uss.mState = UserState.STATE_RUNNING;
6355                        final int userId = mStartedUsers.keyAt(i);
6356                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6357                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6358                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6359                        broadcastIntentLocked(null, null, intent, null,
6360                                new IIntentReceiver.Stub() {
6361                                    @Override
6362                                    public void performReceive(Intent intent, int resultCode,
6363                                            String data, Bundle extras, boolean ordered,
6364                                            boolean sticky, int sendingUser) {
6365                                        synchronized (ActivityManagerService.this) {
6366                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6367                                                    true, false);
6368                                        }
6369                                    }
6370                                },
6371                                0, null, null,
6372                                new String[] {android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
6373                                AppOpsManager.OP_NONE, null, true, false,
6374                                MY_PID, Process.SYSTEM_UID, userId);
6375                    }
6376                }
6377                scheduleStartProfilesLocked();
6378            }
6379        }
6380    }
6381
6382    @Override
6383    public void bootAnimationComplete() {
6384        final boolean callFinishBooting;
6385        synchronized (this) {
6386            callFinishBooting = mCallFinishBooting;
6387            mBootAnimationComplete = true;
6388        }
6389        if (callFinishBooting) {
6390            finishBooting();
6391        }
6392    }
6393
6394    final void ensureBootCompleted() {
6395        boolean booting;
6396        boolean enableScreen;
6397        synchronized (this) {
6398            booting = mBooting;
6399            mBooting = false;
6400            enableScreen = !mBooted;
6401            mBooted = true;
6402        }
6403
6404        if (booting) {
6405            finishBooting();
6406        }
6407
6408        if (enableScreen) {
6409            enableScreenAfterBoot();
6410        }
6411    }
6412
6413    @Override
6414    public final void activityResumed(IBinder token) {
6415        final long origId = Binder.clearCallingIdentity();
6416        synchronized(this) {
6417            ActivityStack stack = ActivityRecord.getStackLocked(token);
6418            if (stack != null) {
6419                ActivityRecord.activityResumedLocked(token);
6420            }
6421        }
6422        Binder.restoreCallingIdentity(origId);
6423    }
6424
6425    @Override
6426    public final void activityPaused(IBinder token) {
6427        final long origId = Binder.clearCallingIdentity();
6428        synchronized(this) {
6429            ActivityStack stack = ActivityRecord.getStackLocked(token);
6430            if (stack != null) {
6431                stack.activityPausedLocked(token, false);
6432            }
6433        }
6434        Binder.restoreCallingIdentity(origId);
6435    }
6436
6437    @Override
6438    public final void activityStopped(IBinder token, Bundle icicle,
6439            PersistableBundle persistentState, CharSequence description) {
6440        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6441
6442        // Refuse possible leaked file descriptors
6443        if (icicle != null && icicle.hasFileDescriptors()) {
6444            throw new IllegalArgumentException("File descriptors passed in Bundle");
6445        }
6446
6447        final long origId = Binder.clearCallingIdentity();
6448
6449        synchronized (this) {
6450            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6451            if (r != null) {
6452                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6453            }
6454        }
6455
6456        trimApplications();
6457
6458        Binder.restoreCallingIdentity(origId);
6459    }
6460
6461    @Override
6462    public final void activityDestroyed(IBinder token) {
6463        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6464        synchronized (this) {
6465            ActivityStack stack = ActivityRecord.getStackLocked(token);
6466            if (stack != null) {
6467                stack.activityDestroyedLocked(token, "activityDestroyed");
6468            }
6469        }
6470    }
6471
6472    @Override
6473    public final void backgroundResourcesReleased(IBinder token) {
6474        final long origId = Binder.clearCallingIdentity();
6475        try {
6476            synchronized (this) {
6477                ActivityStack stack = ActivityRecord.getStackLocked(token);
6478                if (stack != null) {
6479                    stack.backgroundResourcesReleased();
6480                }
6481            }
6482        } finally {
6483            Binder.restoreCallingIdentity(origId);
6484        }
6485    }
6486
6487    @Override
6488    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6489        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6490    }
6491
6492    @Override
6493    public final void notifyEnterAnimationComplete(IBinder token) {
6494        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6495    }
6496
6497    @Override
6498    public String getCallingPackage(IBinder token) {
6499        synchronized (this) {
6500            ActivityRecord r = getCallingRecordLocked(token);
6501            return r != null ? r.info.packageName : null;
6502        }
6503    }
6504
6505    @Override
6506    public ComponentName getCallingActivity(IBinder token) {
6507        synchronized (this) {
6508            ActivityRecord r = getCallingRecordLocked(token);
6509            return r != null ? r.intent.getComponent() : null;
6510        }
6511    }
6512
6513    private ActivityRecord getCallingRecordLocked(IBinder token) {
6514        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6515        if (r == null) {
6516            return null;
6517        }
6518        return r.resultTo;
6519    }
6520
6521    @Override
6522    public ComponentName getActivityClassForToken(IBinder token) {
6523        synchronized(this) {
6524            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6525            if (r == null) {
6526                return null;
6527            }
6528            return r.intent.getComponent();
6529        }
6530    }
6531
6532    @Override
6533    public String getPackageForToken(IBinder token) {
6534        synchronized(this) {
6535            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6536            if (r == null) {
6537                return null;
6538            }
6539            return r.packageName;
6540        }
6541    }
6542
6543    @Override
6544    public boolean isRootVoiceInteraction(IBinder token) {
6545        synchronized(this) {
6546            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6547            if (r == null) {
6548                return false;
6549            }
6550            return r.rootVoiceInteraction;
6551        }
6552    }
6553
6554    @Override
6555    public IIntentSender getIntentSender(int type,
6556            String packageName, IBinder token, String resultWho,
6557            int requestCode, Intent[] intents, String[] resolvedTypes,
6558            int flags, Bundle options, int userId) {
6559        enforceNotIsolatedCaller("getIntentSender");
6560        // Refuse possible leaked file descriptors
6561        if (intents != null) {
6562            if (intents.length < 1) {
6563                throw new IllegalArgumentException("Intents array length must be >= 1");
6564            }
6565            for (int i=0; i<intents.length; i++) {
6566                Intent intent = intents[i];
6567                if (intent != null) {
6568                    if (intent.hasFileDescriptors()) {
6569                        throw new IllegalArgumentException("File descriptors passed in Intent");
6570                    }
6571                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6572                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6573                        throw new IllegalArgumentException(
6574                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6575                    }
6576                    intents[i] = new Intent(intent);
6577                }
6578            }
6579            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6580                throw new IllegalArgumentException(
6581                        "Intent array length does not match resolvedTypes length");
6582            }
6583        }
6584        if (options != null) {
6585            if (options.hasFileDescriptors()) {
6586                throw new IllegalArgumentException("File descriptors passed in options");
6587            }
6588        }
6589
6590        synchronized(this) {
6591            int callingUid = Binder.getCallingUid();
6592            int origUserId = userId;
6593            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6594                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6595                    ALLOW_NON_FULL, "getIntentSender", null);
6596            if (origUserId == UserHandle.USER_CURRENT) {
6597                // We don't want to evaluate this until the pending intent is
6598                // actually executed.  However, we do want to always do the
6599                // security checking for it above.
6600                userId = UserHandle.USER_CURRENT;
6601            }
6602            try {
6603                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6604                    int uid = AppGlobals.getPackageManager()
6605                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6606                    if (!UserHandle.isSameApp(callingUid, uid)) {
6607                        String msg = "Permission Denial: getIntentSender() from pid="
6608                            + Binder.getCallingPid()
6609                            + ", uid=" + Binder.getCallingUid()
6610                            + ", (need uid=" + uid + ")"
6611                            + " is not allowed to send as package " + packageName;
6612                        Slog.w(TAG, msg);
6613                        throw new SecurityException(msg);
6614                    }
6615                }
6616
6617                return getIntentSenderLocked(type, packageName, callingUid, userId,
6618                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6619
6620            } catch (RemoteException e) {
6621                throw new SecurityException(e);
6622            }
6623        }
6624    }
6625
6626    IIntentSender getIntentSenderLocked(int type, String packageName,
6627            int callingUid, int userId, IBinder token, String resultWho,
6628            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6629            Bundle options) {
6630        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6631        ActivityRecord activity = null;
6632        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6633            activity = ActivityRecord.isInStackLocked(token);
6634            if (activity == null) {
6635                return null;
6636            }
6637            if (activity.finishing) {
6638                return null;
6639            }
6640        }
6641
6642        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6643        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6644        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6645        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6646                |PendingIntent.FLAG_UPDATE_CURRENT);
6647
6648        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6649                type, packageName, activity, resultWho,
6650                requestCode, intents, resolvedTypes, flags, options, userId);
6651        WeakReference<PendingIntentRecord> ref;
6652        ref = mIntentSenderRecords.get(key);
6653        PendingIntentRecord rec = ref != null ? ref.get() : null;
6654        if (rec != null) {
6655            if (!cancelCurrent) {
6656                if (updateCurrent) {
6657                    if (rec.key.requestIntent != null) {
6658                        rec.key.requestIntent.replaceExtras(intents != null ?
6659                                intents[intents.length - 1] : null);
6660                    }
6661                    if (intents != null) {
6662                        intents[intents.length-1] = rec.key.requestIntent;
6663                        rec.key.allIntents = intents;
6664                        rec.key.allResolvedTypes = resolvedTypes;
6665                    } else {
6666                        rec.key.allIntents = null;
6667                        rec.key.allResolvedTypes = null;
6668                    }
6669                }
6670                return rec;
6671            }
6672            rec.canceled = true;
6673            mIntentSenderRecords.remove(key);
6674        }
6675        if (noCreate) {
6676            return rec;
6677        }
6678        rec = new PendingIntentRecord(this, key, callingUid);
6679        mIntentSenderRecords.put(key, rec.ref);
6680        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6681            if (activity.pendingResults == null) {
6682                activity.pendingResults
6683                        = new HashSet<WeakReference<PendingIntentRecord>>();
6684            }
6685            activity.pendingResults.add(rec.ref);
6686        }
6687        return rec;
6688    }
6689
6690    @Override
6691    public void cancelIntentSender(IIntentSender sender) {
6692        if (!(sender instanceof PendingIntentRecord)) {
6693            return;
6694        }
6695        synchronized(this) {
6696            PendingIntentRecord rec = (PendingIntentRecord)sender;
6697            try {
6698                int uid = AppGlobals.getPackageManager()
6699                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6700                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6701                    String msg = "Permission Denial: cancelIntentSender() from pid="
6702                        + Binder.getCallingPid()
6703                        + ", uid=" + Binder.getCallingUid()
6704                        + " is not allowed to cancel packges "
6705                        + rec.key.packageName;
6706                    Slog.w(TAG, msg);
6707                    throw new SecurityException(msg);
6708                }
6709            } catch (RemoteException e) {
6710                throw new SecurityException(e);
6711            }
6712            cancelIntentSenderLocked(rec, true);
6713        }
6714    }
6715
6716    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6717        rec.canceled = true;
6718        mIntentSenderRecords.remove(rec.key);
6719        if (cleanActivity && rec.key.activity != null) {
6720            rec.key.activity.pendingResults.remove(rec.ref);
6721        }
6722    }
6723
6724    @Override
6725    public String getPackageForIntentSender(IIntentSender pendingResult) {
6726        if (!(pendingResult instanceof PendingIntentRecord)) {
6727            return null;
6728        }
6729        try {
6730            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6731            return res.key.packageName;
6732        } catch (ClassCastException e) {
6733        }
6734        return null;
6735    }
6736
6737    @Override
6738    public int getUidForIntentSender(IIntentSender sender) {
6739        if (sender instanceof PendingIntentRecord) {
6740            try {
6741                PendingIntentRecord res = (PendingIntentRecord)sender;
6742                return res.uid;
6743            } catch (ClassCastException e) {
6744            }
6745        }
6746        return -1;
6747    }
6748
6749    @Override
6750    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6751        if (!(pendingResult instanceof PendingIntentRecord)) {
6752            return false;
6753        }
6754        try {
6755            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6756            if (res.key.allIntents == null) {
6757                return false;
6758            }
6759            for (int i=0; i<res.key.allIntents.length; i++) {
6760                Intent intent = res.key.allIntents[i];
6761                if (intent.getPackage() != null && intent.getComponent() != null) {
6762                    return false;
6763                }
6764            }
6765            return true;
6766        } catch (ClassCastException e) {
6767        }
6768        return false;
6769    }
6770
6771    @Override
6772    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6773        if (!(pendingResult instanceof PendingIntentRecord)) {
6774            return false;
6775        }
6776        try {
6777            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6778            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6779                return true;
6780            }
6781            return false;
6782        } catch (ClassCastException e) {
6783        }
6784        return false;
6785    }
6786
6787    @Override
6788    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6789        if (!(pendingResult instanceof PendingIntentRecord)) {
6790            return null;
6791        }
6792        try {
6793            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6794            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6795        } catch (ClassCastException e) {
6796        }
6797        return null;
6798    }
6799
6800    @Override
6801    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6802        if (!(pendingResult instanceof PendingIntentRecord)) {
6803            return null;
6804        }
6805        try {
6806            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6807            synchronized (this) {
6808                return getTagForIntentSenderLocked(res, prefix);
6809            }
6810        } catch (ClassCastException e) {
6811        }
6812        return null;
6813    }
6814
6815    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
6816        final Intent intent = res.key.requestIntent;
6817        if (intent != null) {
6818            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6819                    || res.lastTagPrefix.equals(prefix))) {
6820                return res.lastTag;
6821            }
6822            res.lastTagPrefix = prefix;
6823            final StringBuilder sb = new StringBuilder(128);
6824            if (prefix != null) {
6825                sb.append(prefix);
6826            }
6827            if (intent.getAction() != null) {
6828                sb.append(intent.getAction());
6829            } else if (intent.getComponent() != null) {
6830                intent.getComponent().appendShortString(sb);
6831            } else {
6832                sb.append("?");
6833            }
6834            return res.lastTag = sb.toString();
6835        }
6836        return null;
6837    }
6838
6839    @Override
6840    public void setProcessLimit(int max) {
6841        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6842                "setProcessLimit()");
6843        synchronized (this) {
6844            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6845            mProcessLimitOverride = max;
6846        }
6847        trimApplications();
6848    }
6849
6850    @Override
6851    public int getProcessLimit() {
6852        synchronized (this) {
6853            return mProcessLimitOverride;
6854        }
6855    }
6856
6857    void foregroundTokenDied(ForegroundToken token) {
6858        synchronized (ActivityManagerService.this) {
6859            synchronized (mPidsSelfLocked) {
6860                ForegroundToken cur
6861                    = mForegroundProcesses.get(token.pid);
6862                if (cur != token) {
6863                    return;
6864                }
6865                mForegroundProcesses.remove(token.pid);
6866                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6867                if (pr == null) {
6868                    return;
6869                }
6870                pr.forcingToForeground = null;
6871                updateProcessForegroundLocked(pr, false, false);
6872            }
6873            updateOomAdjLocked();
6874        }
6875    }
6876
6877    @Override
6878    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6879        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6880                "setProcessForeground()");
6881        synchronized(this) {
6882            boolean changed = false;
6883
6884            synchronized (mPidsSelfLocked) {
6885                ProcessRecord pr = mPidsSelfLocked.get(pid);
6886                if (pr == null && isForeground) {
6887                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6888                    return;
6889                }
6890                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6891                if (oldToken != null) {
6892                    oldToken.token.unlinkToDeath(oldToken, 0);
6893                    mForegroundProcesses.remove(pid);
6894                    if (pr != null) {
6895                        pr.forcingToForeground = null;
6896                    }
6897                    changed = true;
6898                }
6899                if (isForeground && token != null) {
6900                    ForegroundToken newToken = new ForegroundToken() {
6901                        @Override
6902                        public void binderDied() {
6903                            foregroundTokenDied(this);
6904                        }
6905                    };
6906                    newToken.pid = pid;
6907                    newToken.token = token;
6908                    try {
6909                        token.linkToDeath(newToken, 0);
6910                        mForegroundProcesses.put(pid, newToken);
6911                        pr.forcingToForeground = token;
6912                        changed = true;
6913                    } catch (RemoteException e) {
6914                        // If the process died while doing this, we will later
6915                        // do the cleanup with the process death link.
6916                    }
6917                }
6918            }
6919
6920            if (changed) {
6921                updateOomAdjLocked();
6922            }
6923        }
6924    }
6925
6926    // =========================================================
6927    // PROCESS INFO
6928    // =========================================================
6929
6930    static class ProcessInfoService extends IProcessInfoService.Stub {
6931        final ActivityManagerService mActivityManagerService;
6932        ProcessInfoService(ActivityManagerService activityManagerService) {
6933            mActivityManagerService = activityManagerService;
6934        }
6935
6936        @Override
6937        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
6938            mActivityManagerService.getProcessStatesForPIDs(/*in*/ pids, /*out*/ states);
6939        }
6940    }
6941
6942    /**
6943     * For each PID in the given input array, write the current process state
6944     * for that process into the output array, or -1 to indicate that no
6945     * process with the given PID exists.
6946     */
6947    public void getProcessStatesForPIDs(/*in*/ int[] pids, /*out*/ int[] states) {
6948        if (pids == null) {
6949            throw new NullPointerException("pids");
6950        } else if (states == null) {
6951            throw new NullPointerException("states");
6952        } else if (pids.length != states.length) {
6953            throw new IllegalArgumentException("input and output arrays have different lengths!");
6954        }
6955
6956        synchronized (mPidsSelfLocked) {
6957            for (int i = 0; i < pids.length; i++) {
6958                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
6959                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
6960                        pr.curProcState;
6961            }
6962        }
6963    }
6964
6965    // =========================================================
6966    // PERMISSIONS
6967    // =========================================================
6968
6969    static class PermissionController extends IPermissionController.Stub {
6970        ActivityManagerService mActivityManagerService;
6971        PermissionController(ActivityManagerService activityManagerService) {
6972            mActivityManagerService = activityManagerService;
6973        }
6974
6975        @Override
6976        public boolean checkPermission(String permission, int pid, int uid) {
6977            return mActivityManagerService.checkPermission(permission, pid,
6978                    uid) == PackageManager.PERMISSION_GRANTED;
6979        }
6980
6981        @Override
6982        public String[] getPackagesForUid(int uid) {
6983            return mActivityManagerService.mContext.getPackageManager()
6984                    .getPackagesForUid(uid);
6985        }
6986
6987        @Override
6988        public boolean isRuntimePermission(String permission) {
6989            try {
6990                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
6991                        .getPermissionInfo(permission, 0);
6992                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
6993            } catch (NameNotFoundException nnfe) {
6994                Slog.e(TAG, "No such permission: "+ permission, nnfe);
6995            }
6996            return false;
6997        }
6998    }
6999
7000    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7001        @Override
7002        public int checkComponentPermission(String permission, int pid, int uid,
7003                int owningUid, boolean exported) {
7004            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7005                    owningUid, exported);
7006        }
7007
7008        @Override
7009        public Object getAMSLock() {
7010            return ActivityManagerService.this;
7011        }
7012    }
7013
7014    /**
7015     * This can be called with or without the global lock held.
7016     */
7017    int checkComponentPermission(String permission, int pid, int uid,
7018            int owningUid, boolean exported) {
7019        if (pid == MY_PID) {
7020            return PackageManager.PERMISSION_GRANTED;
7021        }
7022        return ActivityManager.checkComponentPermission(permission, uid,
7023                owningUid, exported);
7024    }
7025
7026    /**
7027     * As the only public entry point for permissions checking, this method
7028     * can enforce the semantic that requesting a check on a null global
7029     * permission is automatically denied.  (Internally a null permission
7030     * string is used when calling {@link #checkComponentPermission} in cases
7031     * when only uid-based security is needed.)
7032     *
7033     * This can be called with or without the global lock held.
7034     */
7035    @Override
7036    public int checkPermission(String permission, int pid, int uid) {
7037        if (permission == null) {
7038            return PackageManager.PERMISSION_DENIED;
7039        }
7040        return checkComponentPermission(permission, pid, uid, -1, true);
7041    }
7042
7043    @Override
7044    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7045        if (permission == null) {
7046            return PackageManager.PERMISSION_DENIED;
7047        }
7048
7049        // We might be performing an operation on behalf of an indirect binder
7050        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7051        // client identity accordingly before proceeding.
7052        Identity tlsIdentity = sCallerIdentity.get();
7053        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7054            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7055                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7056            uid = tlsIdentity.uid;
7057            pid = tlsIdentity.pid;
7058        }
7059
7060        return checkComponentPermission(permission, pid, uid, -1, true);
7061    }
7062
7063    /**
7064     * Binder IPC calls go through the public entry point.
7065     * This can be called with or without the global lock held.
7066     */
7067    int checkCallingPermission(String permission) {
7068        return checkPermission(permission,
7069                Binder.getCallingPid(),
7070                UserHandle.getAppId(Binder.getCallingUid()));
7071    }
7072
7073    /**
7074     * This can be called with or without the global lock held.
7075     */
7076    void enforceCallingPermission(String permission, String func) {
7077        if (checkCallingPermission(permission)
7078                == PackageManager.PERMISSION_GRANTED) {
7079            return;
7080        }
7081
7082        String msg = "Permission Denial: " + func + " from pid="
7083                + Binder.getCallingPid()
7084                + ", uid=" + Binder.getCallingUid()
7085                + " requires " + permission;
7086        Slog.w(TAG, msg);
7087        throw new SecurityException(msg);
7088    }
7089
7090    /**
7091     * Determine if UID is holding permissions required to access {@link Uri} in
7092     * the given {@link ProviderInfo}. Final permission checking is always done
7093     * in {@link ContentProvider}.
7094     */
7095    private final boolean checkHoldingPermissionsLocked(
7096            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7097        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7098                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7099        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7100            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7101                    != PERMISSION_GRANTED) {
7102                return false;
7103            }
7104        }
7105        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7106    }
7107
7108    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7109            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7110        if (pi.applicationInfo.uid == uid) {
7111            return true;
7112        } else if (!pi.exported) {
7113            return false;
7114        }
7115
7116        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7117        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7118        try {
7119            // check if target holds top-level <provider> permissions
7120            if (!readMet && pi.readPermission != null && considerUidPermissions
7121                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7122                readMet = true;
7123            }
7124            if (!writeMet && pi.writePermission != null && considerUidPermissions
7125                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7126                writeMet = true;
7127            }
7128
7129            // track if unprotected read/write is allowed; any denied
7130            // <path-permission> below removes this ability
7131            boolean allowDefaultRead = pi.readPermission == null;
7132            boolean allowDefaultWrite = pi.writePermission == null;
7133
7134            // check if target holds any <path-permission> that match uri
7135            final PathPermission[] pps = pi.pathPermissions;
7136            if (pps != null) {
7137                final String path = grantUri.uri.getPath();
7138                int i = pps.length;
7139                while (i > 0 && (!readMet || !writeMet)) {
7140                    i--;
7141                    PathPermission pp = pps[i];
7142                    if (pp.match(path)) {
7143                        if (!readMet) {
7144                            final String pprperm = pp.getReadPermission();
7145                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7146                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7147                                    + ": match=" + pp.match(path)
7148                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7149                            if (pprperm != null) {
7150                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7151                                        == PERMISSION_GRANTED) {
7152                                    readMet = true;
7153                                } else {
7154                                    allowDefaultRead = false;
7155                                }
7156                            }
7157                        }
7158                        if (!writeMet) {
7159                            final String ppwperm = pp.getWritePermission();
7160                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7161                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7162                                    + ": match=" + pp.match(path)
7163                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7164                            if (ppwperm != null) {
7165                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7166                                        == PERMISSION_GRANTED) {
7167                                    writeMet = true;
7168                                } else {
7169                                    allowDefaultWrite = false;
7170                                }
7171                            }
7172                        }
7173                    }
7174                }
7175            }
7176
7177            // grant unprotected <provider> read/write, if not blocked by
7178            // <path-permission> above
7179            if (allowDefaultRead) readMet = true;
7180            if (allowDefaultWrite) writeMet = true;
7181
7182        } catch (RemoteException e) {
7183            return false;
7184        }
7185
7186        return readMet && writeMet;
7187    }
7188
7189    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7190        ProviderInfo pi = null;
7191        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7192        if (cpr != null) {
7193            pi = cpr.info;
7194        } else {
7195            try {
7196                pi = AppGlobals.getPackageManager().resolveContentProvider(
7197                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7198            } catch (RemoteException ex) {
7199            }
7200        }
7201        return pi;
7202    }
7203
7204    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7205        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7206        if (targetUris != null) {
7207            return targetUris.get(grantUri);
7208        }
7209        return null;
7210    }
7211
7212    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7213            String targetPkg, int targetUid, GrantUri grantUri) {
7214        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7215        if (targetUris == null) {
7216            targetUris = Maps.newArrayMap();
7217            mGrantedUriPermissions.put(targetUid, targetUris);
7218        }
7219
7220        UriPermission perm = targetUris.get(grantUri);
7221        if (perm == null) {
7222            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7223            targetUris.put(grantUri, perm);
7224        }
7225
7226        return perm;
7227    }
7228
7229    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7230            final int modeFlags) {
7231        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7232        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7233                : UriPermission.STRENGTH_OWNED;
7234
7235        // Root gets to do everything.
7236        if (uid == 0) {
7237            return true;
7238        }
7239
7240        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7241        if (perms == null) return false;
7242
7243        // First look for exact match
7244        final UriPermission exactPerm = perms.get(grantUri);
7245        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7246            return true;
7247        }
7248
7249        // No exact match, look for prefixes
7250        final int N = perms.size();
7251        for (int i = 0; i < N; i++) {
7252            final UriPermission perm = perms.valueAt(i);
7253            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7254                    && perm.getStrength(modeFlags) >= minStrength) {
7255                return true;
7256            }
7257        }
7258
7259        return false;
7260    }
7261
7262    /**
7263     * @param uri This uri must NOT contain an embedded userId.
7264     * @param userId The userId in which the uri is to be resolved.
7265     */
7266    @Override
7267    public int checkUriPermission(Uri uri, int pid, int uid,
7268            final int modeFlags, int userId, IBinder callerToken) {
7269        enforceNotIsolatedCaller("checkUriPermission");
7270
7271        // Another redirected-binder-call permissions check as in
7272        // {@link checkPermissionWithToken}.
7273        Identity tlsIdentity = sCallerIdentity.get();
7274        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7275            uid = tlsIdentity.uid;
7276            pid = tlsIdentity.pid;
7277        }
7278
7279        // Our own process gets to do everything.
7280        if (pid == MY_PID) {
7281            return PackageManager.PERMISSION_GRANTED;
7282        }
7283        synchronized (this) {
7284            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7285                    ? PackageManager.PERMISSION_GRANTED
7286                    : PackageManager.PERMISSION_DENIED;
7287        }
7288    }
7289
7290    /**
7291     * Check if the targetPkg can be granted permission to access uri by
7292     * the callingUid using the given modeFlags.  Throws a security exception
7293     * if callingUid is not allowed to do this.  Returns the uid of the target
7294     * if the URI permission grant should be performed; returns -1 if it is not
7295     * needed (for example targetPkg already has permission to access the URI).
7296     * If you already know the uid of the target, you can supply it in
7297     * lastTargetUid else set that to -1.
7298     */
7299    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7300            final int modeFlags, int lastTargetUid) {
7301        if (!Intent.isAccessUriMode(modeFlags)) {
7302            return -1;
7303        }
7304
7305        if (targetPkg != null) {
7306            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7307                    "Checking grant " + targetPkg + " permission to " + grantUri);
7308        }
7309
7310        final IPackageManager pm = AppGlobals.getPackageManager();
7311
7312        // If this is not a content: uri, we can't do anything with it.
7313        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7314            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7315                    "Can't grant URI permission for non-content URI: " + grantUri);
7316            return -1;
7317        }
7318
7319        final String authority = grantUri.uri.getAuthority();
7320        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7321        if (pi == null) {
7322            Slog.w(TAG, "No content provider found for permission check: " +
7323                    grantUri.uri.toSafeString());
7324            return -1;
7325        }
7326
7327        int targetUid = lastTargetUid;
7328        if (targetUid < 0 && targetPkg != null) {
7329            try {
7330                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7331                if (targetUid < 0) {
7332                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7333                            "Can't grant URI permission no uid for: " + targetPkg);
7334                    return -1;
7335                }
7336            } catch (RemoteException ex) {
7337                return -1;
7338            }
7339        }
7340
7341        if (targetUid >= 0) {
7342            // First...  does the target actually need this permission?
7343            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7344                // No need to grant the target this permission.
7345                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7346                        "Target " + targetPkg + " already has full permission to " + grantUri);
7347                return -1;
7348            }
7349        } else {
7350            // First...  there is no target package, so can anyone access it?
7351            boolean allowed = pi.exported;
7352            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7353                if (pi.readPermission != null) {
7354                    allowed = false;
7355                }
7356            }
7357            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7358                if (pi.writePermission != null) {
7359                    allowed = false;
7360                }
7361            }
7362            if (allowed) {
7363                return -1;
7364            }
7365        }
7366
7367        /* There is a special cross user grant if:
7368         * - The target is on another user.
7369         * - Apps on the current user can access the uri without any uid permissions.
7370         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7371         * grant uri permissions.
7372         */
7373        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7374                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7375                modeFlags, false /*without considering the uid permissions*/);
7376
7377        // Second...  is the provider allowing granting of URI permissions?
7378        if (!specialCrossUserGrant) {
7379            if (!pi.grantUriPermissions) {
7380                throw new SecurityException("Provider " + pi.packageName
7381                        + "/" + pi.name
7382                        + " does not allow granting of Uri permissions (uri "
7383                        + grantUri + ")");
7384            }
7385            if (pi.uriPermissionPatterns != null) {
7386                final int N = pi.uriPermissionPatterns.length;
7387                boolean allowed = false;
7388                for (int i=0; i<N; i++) {
7389                    if (pi.uriPermissionPatterns[i] != null
7390                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7391                        allowed = true;
7392                        break;
7393                    }
7394                }
7395                if (!allowed) {
7396                    throw new SecurityException("Provider " + pi.packageName
7397                            + "/" + pi.name
7398                            + " does not allow granting of permission to path of Uri "
7399                            + grantUri);
7400                }
7401            }
7402        }
7403
7404        // Third...  does the caller itself have permission to access
7405        // this uri?
7406        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7407            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7408                // Require they hold a strong enough Uri permission
7409                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7410                    throw new SecurityException("Uid " + callingUid
7411                            + " does not have permission to uri " + grantUri);
7412                }
7413            }
7414        }
7415        return targetUid;
7416    }
7417
7418    /**
7419     * @param uri This uri must NOT contain an embedded userId.
7420     * @param userId The userId in which the uri is to be resolved.
7421     */
7422    @Override
7423    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7424            final int modeFlags, int userId) {
7425        enforceNotIsolatedCaller("checkGrantUriPermission");
7426        synchronized(this) {
7427            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7428                    new GrantUri(userId, uri, false), modeFlags, -1);
7429        }
7430    }
7431
7432    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7433            final int modeFlags, UriPermissionOwner owner) {
7434        if (!Intent.isAccessUriMode(modeFlags)) {
7435            return;
7436        }
7437
7438        // So here we are: the caller has the assumed permission
7439        // to the uri, and the target doesn't.  Let's now give this to
7440        // the target.
7441
7442        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7443                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7444
7445        final String authority = grantUri.uri.getAuthority();
7446        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7447        if (pi == null) {
7448            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7449            return;
7450        }
7451
7452        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7453            grantUri.prefix = true;
7454        }
7455        final UriPermission perm = findOrCreateUriPermissionLocked(
7456                pi.packageName, targetPkg, targetUid, grantUri);
7457        perm.grantModes(modeFlags, owner);
7458    }
7459
7460    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7461            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7462        if (targetPkg == null) {
7463            throw new NullPointerException("targetPkg");
7464        }
7465        int targetUid;
7466        final IPackageManager pm = AppGlobals.getPackageManager();
7467        try {
7468            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7469        } catch (RemoteException ex) {
7470            return;
7471        }
7472
7473        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7474                targetUid);
7475        if (targetUid < 0) {
7476            return;
7477        }
7478
7479        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7480                owner);
7481    }
7482
7483    static class NeededUriGrants extends ArrayList<GrantUri> {
7484        final String targetPkg;
7485        final int targetUid;
7486        final int flags;
7487
7488        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7489            this.targetPkg = targetPkg;
7490            this.targetUid = targetUid;
7491            this.flags = flags;
7492        }
7493    }
7494
7495    /**
7496     * Like checkGrantUriPermissionLocked, but takes an Intent.
7497     */
7498    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7499            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7500        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7501                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7502                + " clip=" + (intent != null ? intent.getClipData() : null)
7503                + " from " + intent + "; flags=0x"
7504                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7505
7506        if (targetPkg == null) {
7507            throw new NullPointerException("targetPkg");
7508        }
7509
7510        if (intent == null) {
7511            return null;
7512        }
7513        Uri data = intent.getData();
7514        ClipData clip = intent.getClipData();
7515        if (data == null && clip == null) {
7516            return null;
7517        }
7518        // Default userId for uris in the intent (if they don't specify it themselves)
7519        int contentUserHint = intent.getContentUserHint();
7520        if (contentUserHint == UserHandle.USER_CURRENT) {
7521            contentUserHint = UserHandle.getUserId(callingUid);
7522        }
7523        final IPackageManager pm = AppGlobals.getPackageManager();
7524        int targetUid;
7525        if (needed != null) {
7526            targetUid = needed.targetUid;
7527        } else {
7528            try {
7529                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7530            } catch (RemoteException ex) {
7531                return null;
7532            }
7533            if (targetUid < 0) {
7534                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7535                        "Can't grant URI permission no uid for: " + targetPkg
7536                        + " on user " + targetUserId);
7537                return null;
7538            }
7539        }
7540        if (data != null) {
7541            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7542            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7543                    targetUid);
7544            if (targetUid > 0) {
7545                if (needed == null) {
7546                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7547                }
7548                needed.add(grantUri);
7549            }
7550        }
7551        if (clip != null) {
7552            for (int i=0; i<clip.getItemCount(); i++) {
7553                Uri uri = clip.getItemAt(i).getUri();
7554                if (uri != null) {
7555                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7556                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7557                            targetUid);
7558                    if (targetUid > 0) {
7559                        if (needed == null) {
7560                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7561                        }
7562                        needed.add(grantUri);
7563                    }
7564                } else {
7565                    Intent clipIntent = clip.getItemAt(i).getIntent();
7566                    if (clipIntent != null) {
7567                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7568                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7569                        if (newNeeded != null) {
7570                            needed = newNeeded;
7571                        }
7572                    }
7573                }
7574            }
7575        }
7576
7577        return needed;
7578    }
7579
7580    /**
7581     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7582     */
7583    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7584            UriPermissionOwner owner) {
7585        if (needed != null) {
7586            for (int i=0; i<needed.size(); i++) {
7587                GrantUri grantUri = needed.get(i);
7588                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7589                        grantUri, needed.flags, owner);
7590            }
7591        }
7592    }
7593
7594    void grantUriPermissionFromIntentLocked(int callingUid,
7595            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7596        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7597                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7598        if (needed == null) {
7599            return;
7600        }
7601
7602        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7603    }
7604
7605    /**
7606     * @param uri This uri must NOT contain an embedded userId.
7607     * @param userId The userId in which the uri is to be resolved.
7608     */
7609    @Override
7610    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7611            final int modeFlags, int userId) {
7612        enforceNotIsolatedCaller("grantUriPermission");
7613        GrantUri grantUri = new GrantUri(userId, uri, false);
7614        synchronized(this) {
7615            final ProcessRecord r = getRecordForAppLocked(caller);
7616            if (r == null) {
7617                throw new SecurityException("Unable to find app for caller "
7618                        + caller
7619                        + " when granting permission to uri " + grantUri);
7620            }
7621            if (targetPkg == null) {
7622                throw new IllegalArgumentException("null target");
7623            }
7624            if (grantUri == null) {
7625                throw new IllegalArgumentException("null uri");
7626            }
7627
7628            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7629                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7630                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7631                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7632
7633            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7634                    UserHandle.getUserId(r.uid));
7635        }
7636    }
7637
7638    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7639        if (perm.modeFlags == 0) {
7640            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7641                    perm.targetUid);
7642            if (perms != null) {
7643                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7644                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7645
7646                perms.remove(perm.uri);
7647                if (perms.isEmpty()) {
7648                    mGrantedUriPermissions.remove(perm.targetUid);
7649                }
7650            }
7651        }
7652    }
7653
7654    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7655        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7656                "Revoking all granted permissions to " + grantUri);
7657
7658        final IPackageManager pm = AppGlobals.getPackageManager();
7659        final String authority = grantUri.uri.getAuthority();
7660        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7661        if (pi == null) {
7662            Slog.w(TAG, "No content provider found for permission revoke: "
7663                    + grantUri.toSafeString());
7664            return;
7665        }
7666
7667        // Does the caller have this permission on the URI?
7668        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7669            // If they don't have direct access to the URI, then revoke any
7670            // ownerless URI permissions that have been granted to them.
7671            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7672            if (perms != null) {
7673                boolean persistChanged = false;
7674                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7675                    final UriPermission perm = it.next();
7676                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7677                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7678                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7679                                "Revoking non-owned " + perm.targetUid
7680                                + " permission to " + perm.uri);
7681                        persistChanged |= perm.revokeModes(
7682                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7683                        if (perm.modeFlags == 0) {
7684                            it.remove();
7685                        }
7686                    }
7687                }
7688                if (perms.isEmpty()) {
7689                    mGrantedUriPermissions.remove(callingUid);
7690                }
7691                if (persistChanged) {
7692                    schedulePersistUriGrants();
7693                }
7694            }
7695            return;
7696        }
7697
7698        boolean persistChanged = false;
7699
7700        // Go through all of the permissions and remove any that match.
7701        int N = mGrantedUriPermissions.size();
7702        for (int i = 0; i < N; i++) {
7703            final int targetUid = mGrantedUriPermissions.keyAt(i);
7704            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7705
7706            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7707                final UriPermission perm = it.next();
7708                if (perm.uri.sourceUserId == grantUri.sourceUserId
7709                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7710                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7711                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7712                    persistChanged |= perm.revokeModes(
7713                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7714                    if (perm.modeFlags == 0) {
7715                        it.remove();
7716                    }
7717                }
7718            }
7719
7720            if (perms.isEmpty()) {
7721                mGrantedUriPermissions.remove(targetUid);
7722                N--;
7723                i--;
7724            }
7725        }
7726
7727        if (persistChanged) {
7728            schedulePersistUriGrants();
7729        }
7730    }
7731
7732    /**
7733     * @param uri This uri must NOT contain an embedded userId.
7734     * @param userId The userId in which the uri is to be resolved.
7735     */
7736    @Override
7737    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7738            int userId) {
7739        enforceNotIsolatedCaller("revokeUriPermission");
7740        synchronized(this) {
7741            final ProcessRecord r = getRecordForAppLocked(caller);
7742            if (r == null) {
7743                throw new SecurityException("Unable to find app for caller "
7744                        + caller
7745                        + " when revoking permission to uri " + uri);
7746            }
7747            if (uri == null) {
7748                Slog.w(TAG, "revokeUriPermission: null uri");
7749                return;
7750            }
7751
7752            if (!Intent.isAccessUriMode(modeFlags)) {
7753                return;
7754            }
7755
7756            final String authority = uri.getAuthority();
7757            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7758            if (pi == null) {
7759                Slog.w(TAG, "No content provider found for permission revoke: "
7760                        + uri.toSafeString());
7761                return;
7762            }
7763
7764            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7765        }
7766    }
7767
7768    /**
7769     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7770     * given package.
7771     *
7772     * @param packageName Package name to match, or {@code null} to apply to all
7773     *            packages.
7774     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7775     *            to all users.
7776     * @param persistable If persistable grants should be removed.
7777     */
7778    private void removeUriPermissionsForPackageLocked(
7779            String packageName, int userHandle, boolean persistable) {
7780        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7781            throw new IllegalArgumentException("Must narrow by either package or user");
7782        }
7783
7784        boolean persistChanged = false;
7785
7786        int N = mGrantedUriPermissions.size();
7787        for (int i = 0; i < N; i++) {
7788            final int targetUid = mGrantedUriPermissions.keyAt(i);
7789            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7790
7791            // Only inspect grants matching user
7792            if (userHandle == UserHandle.USER_ALL
7793                    || userHandle == UserHandle.getUserId(targetUid)) {
7794                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7795                    final UriPermission perm = it.next();
7796
7797                    // Only inspect grants matching package
7798                    if (packageName == null || perm.sourcePkg.equals(packageName)
7799                            || perm.targetPkg.equals(packageName)) {
7800                        persistChanged |= perm.revokeModes(persistable
7801                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7802
7803                        // Only remove when no modes remain; any persisted grants
7804                        // will keep this alive.
7805                        if (perm.modeFlags == 0) {
7806                            it.remove();
7807                        }
7808                    }
7809                }
7810
7811                if (perms.isEmpty()) {
7812                    mGrantedUriPermissions.remove(targetUid);
7813                    N--;
7814                    i--;
7815                }
7816            }
7817        }
7818
7819        if (persistChanged) {
7820            schedulePersistUriGrants();
7821        }
7822    }
7823
7824    @Override
7825    public IBinder newUriPermissionOwner(String name) {
7826        enforceNotIsolatedCaller("newUriPermissionOwner");
7827        synchronized(this) {
7828            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7829            return owner.getExternalTokenLocked();
7830        }
7831    }
7832
7833    /**
7834     * @param uri This uri must NOT contain an embedded userId.
7835     * @param sourceUserId The userId in which the uri is to be resolved.
7836     * @param targetUserId The userId of the app that receives the grant.
7837     */
7838    @Override
7839    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7840            final int modeFlags, int sourceUserId, int targetUserId) {
7841        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7842                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7843        synchronized(this) {
7844            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7845            if (owner == null) {
7846                throw new IllegalArgumentException("Unknown owner: " + token);
7847            }
7848            if (fromUid != Binder.getCallingUid()) {
7849                if (Binder.getCallingUid() != Process.myUid()) {
7850                    // Only system code can grant URI permissions on behalf
7851                    // of other users.
7852                    throw new SecurityException("nice try");
7853                }
7854            }
7855            if (targetPkg == null) {
7856                throw new IllegalArgumentException("null target");
7857            }
7858            if (uri == null) {
7859                throw new IllegalArgumentException("null uri");
7860            }
7861
7862            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7863                    modeFlags, owner, targetUserId);
7864        }
7865    }
7866
7867    /**
7868     * @param uri This uri must NOT contain an embedded userId.
7869     * @param userId The userId in which the uri is to be resolved.
7870     */
7871    @Override
7872    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7873        synchronized(this) {
7874            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7875            if (owner == null) {
7876                throw new IllegalArgumentException("Unknown owner: " + token);
7877            }
7878
7879            if (uri == null) {
7880                owner.removeUriPermissionsLocked(mode);
7881            } else {
7882                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7883            }
7884        }
7885    }
7886
7887    private void schedulePersistUriGrants() {
7888        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7889            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7890                    10 * DateUtils.SECOND_IN_MILLIS);
7891        }
7892    }
7893
7894    private void writeGrantedUriPermissions() {
7895        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
7896
7897        // Snapshot permissions so we can persist without lock
7898        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7899        synchronized (this) {
7900            final int size = mGrantedUriPermissions.size();
7901            for (int i = 0; i < size; i++) {
7902                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7903                for (UriPermission perm : perms.values()) {
7904                    if (perm.persistedModeFlags != 0) {
7905                        persist.add(perm.snapshot());
7906                    }
7907                }
7908            }
7909        }
7910
7911        FileOutputStream fos = null;
7912        try {
7913            fos = mGrantFile.startWrite();
7914
7915            XmlSerializer out = new FastXmlSerializer();
7916            out.setOutput(fos, StandardCharsets.UTF_8.name());
7917            out.startDocument(null, true);
7918            out.startTag(null, TAG_URI_GRANTS);
7919            for (UriPermission.Snapshot perm : persist) {
7920                out.startTag(null, TAG_URI_GRANT);
7921                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7922                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7923                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7924                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7925                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7926                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7927                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7928                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7929                out.endTag(null, TAG_URI_GRANT);
7930            }
7931            out.endTag(null, TAG_URI_GRANTS);
7932            out.endDocument();
7933
7934            mGrantFile.finishWrite(fos);
7935        } catch (IOException e) {
7936            if (fos != null) {
7937                mGrantFile.failWrite(fos);
7938            }
7939        }
7940    }
7941
7942    private void readGrantedUriPermissionsLocked() {
7943        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
7944
7945        final long now = System.currentTimeMillis();
7946
7947        FileInputStream fis = null;
7948        try {
7949            fis = mGrantFile.openRead();
7950            final XmlPullParser in = Xml.newPullParser();
7951            in.setInput(fis, StandardCharsets.UTF_8.name());
7952
7953            int type;
7954            while ((type = in.next()) != END_DOCUMENT) {
7955                final String tag = in.getName();
7956                if (type == START_TAG) {
7957                    if (TAG_URI_GRANT.equals(tag)) {
7958                        final int sourceUserId;
7959                        final int targetUserId;
7960                        final int userHandle = readIntAttribute(in,
7961                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7962                        if (userHandle != UserHandle.USER_NULL) {
7963                            // For backwards compatibility.
7964                            sourceUserId = userHandle;
7965                            targetUserId = userHandle;
7966                        } else {
7967                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7968                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7969                        }
7970                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7971                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7972                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7973                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7974                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7975                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7976
7977                        // Sanity check that provider still belongs to source package
7978                        final ProviderInfo pi = getProviderInfoLocked(
7979                                uri.getAuthority(), sourceUserId);
7980                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7981                            int targetUid = -1;
7982                            try {
7983                                targetUid = AppGlobals.getPackageManager()
7984                                        .getPackageUid(targetPkg, targetUserId);
7985                            } catch (RemoteException e) {
7986                            }
7987                            if (targetUid != -1) {
7988                                final UriPermission perm = findOrCreateUriPermissionLocked(
7989                                        sourcePkg, targetPkg, targetUid,
7990                                        new GrantUri(sourceUserId, uri, prefix));
7991                                perm.initPersistedModes(modeFlags, createdTime);
7992                            }
7993                        } else {
7994                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7995                                    + " but instead found " + pi);
7996                        }
7997                    }
7998                }
7999            }
8000        } catch (FileNotFoundException e) {
8001            // Missing grants is okay
8002        } catch (IOException e) {
8003            Slog.wtf(TAG, "Failed reading Uri grants", e);
8004        } catch (XmlPullParserException e) {
8005            Slog.wtf(TAG, "Failed reading Uri grants", e);
8006        } finally {
8007            IoUtils.closeQuietly(fis);
8008        }
8009    }
8010
8011    /**
8012     * @param uri This uri must NOT contain an embedded userId.
8013     * @param userId The userId in which the uri is to be resolved.
8014     */
8015    @Override
8016    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8017        enforceNotIsolatedCaller("takePersistableUriPermission");
8018
8019        Preconditions.checkFlagsArgument(modeFlags,
8020                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8021
8022        synchronized (this) {
8023            final int callingUid = Binder.getCallingUid();
8024            boolean persistChanged = false;
8025            GrantUri grantUri = new GrantUri(userId, uri, false);
8026
8027            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8028                    new GrantUri(userId, uri, false));
8029            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8030                    new GrantUri(userId, uri, true));
8031
8032            final boolean exactValid = (exactPerm != null)
8033                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8034            final boolean prefixValid = (prefixPerm != null)
8035                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8036
8037            if (!(exactValid || prefixValid)) {
8038                throw new SecurityException("No persistable permission grants found for UID "
8039                        + callingUid + " and Uri " + grantUri.toSafeString());
8040            }
8041
8042            if (exactValid) {
8043                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8044            }
8045            if (prefixValid) {
8046                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8047            }
8048
8049            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8050
8051            if (persistChanged) {
8052                schedulePersistUriGrants();
8053            }
8054        }
8055    }
8056
8057    /**
8058     * @param uri This uri must NOT contain an embedded userId.
8059     * @param userId The userId in which the uri is to be resolved.
8060     */
8061    @Override
8062    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8063        enforceNotIsolatedCaller("releasePersistableUriPermission");
8064
8065        Preconditions.checkFlagsArgument(modeFlags,
8066                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8067
8068        synchronized (this) {
8069            final int callingUid = Binder.getCallingUid();
8070            boolean persistChanged = false;
8071
8072            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8073                    new GrantUri(userId, uri, false));
8074            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8075                    new GrantUri(userId, uri, true));
8076            if (exactPerm == null && prefixPerm == null) {
8077                throw new SecurityException("No permission grants found for UID " + callingUid
8078                        + " and Uri " + uri.toSafeString());
8079            }
8080
8081            if (exactPerm != null) {
8082                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8083                removeUriPermissionIfNeededLocked(exactPerm);
8084            }
8085            if (prefixPerm != null) {
8086                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8087                removeUriPermissionIfNeededLocked(prefixPerm);
8088            }
8089
8090            if (persistChanged) {
8091                schedulePersistUriGrants();
8092            }
8093        }
8094    }
8095
8096    /**
8097     * Prune any older {@link UriPermission} for the given UID until outstanding
8098     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8099     *
8100     * @return if any mutations occured that require persisting.
8101     */
8102    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8103        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8104        if (perms == null) return false;
8105        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8106
8107        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8108        for (UriPermission perm : perms.values()) {
8109            if (perm.persistedModeFlags != 0) {
8110                persisted.add(perm);
8111            }
8112        }
8113
8114        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8115        if (trimCount <= 0) return false;
8116
8117        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8118        for (int i = 0; i < trimCount; i++) {
8119            final UriPermission perm = persisted.get(i);
8120
8121            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8122                    "Trimming grant created at " + perm.persistedCreateTime);
8123
8124            perm.releasePersistableModes(~0);
8125            removeUriPermissionIfNeededLocked(perm);
8126        }
8127
8128        return true;
8129    }
8130
8131    @Override
8132    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8133            String packageName, boolean incoming) {
8134        enforceNotIsolatedCaller("getPersistedUriPermissions");
8135        Preconditions.checkNotNull(packageName, "packageName");
8136
8137        final int callingUid = Binder.getCallingUid();
8138        final IPackageManager pm = AppGlobals.getPackageManager();
8139        try {
8140            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8141            if (packageUid != callingUid) {
8142                throw new SecurityException(
8143                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8144            }
8145        } catch (RemoteException e) {
8146            throw new SecurityException("Failed to verify package name ownership");
8147        }
8148
8149        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8150        synchronized (this) {
8151            if (incoming) {
8152                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8153                        callingUid);
8154                if (perms == null) {
8155                    Slog.w(TAG, "No permission grants found for " + packageName);
8156                } else {
8157                    for (UriPermission perm : perms.values()) {
8158                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8159                            result.add(perm.buildPersistedPublicApiObject());
8160                        }
8161                    }
8162                }
8163            } else {
8164                final int size = mGrantedUriPermissions.size();
8165                for (int i = 0; i < size; i++) {
8166                    final ArrayMap<GrantUri, UriPermission> perms =
8167                            mGrantedUriPermissions.valueAt(i);
8168                    for (UriPermission perm : perms.values()) {
8169                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8170                            result.add(perm.buildPersistedPublicApiObject());
8171                        }
8172                    }
8173                }
8174            }
8175        }
8176        return new ParceledListSlice<android.content.UriPermission>(result);
8177    }
8178
8179    @Override
8180    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8181        synchronized (this) {
8182            ProcessRecord app =
8183                who != null ? getRecordForAppLocked(who) : null;
8184            if (app == null) return;
8185
8186            Message msg = Message.obtain();
8187            msg.what = WAIT_FOR_DEBUGGER_MSG;
8188            msg.obj = app;
8189            msg.arg1 = waiting ? 1 : 0;
8190            mUiHandler.sendMessage(msg);
8191        }
8192    }
8193
8194    @Override
8195    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8196        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8197        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8198        outInfo.availMem = Process.getFreeMemory();
8199        outInfo.totalMem = Process.getTotalMemory();
8200        outInfo.threshold = homeAppMem;
8201        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8202        outInfo.hiddenAppThreshold = cachedAppMem;
8203        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8204                ProcessList.SERVICE_ADJ);
8205        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8206                ProcessList.VISIBLE_APP_ADJ);
8207        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8208                ProcessList.FOREGROUND_APP_ADJ);
8209    }
8210
8211    // =========================================================
8212    // TASK MANAGEMENT
8213    // =========================================================
8214
8215    @Override
8216    public List<IAppTask> getAppTasks(String callingPackage) {
8217        int callingUid = Binder.getCallingUid();
8218        long ident = Binder.clearCallingIdentity();
8219
8220        synchronized(this) {
8221            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8222            try {
8223                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8224
8225                final int N = mRecentTasks.size();
8226                for (int i = 0; i < N; i++) {
8227                    TaskRecord tr = mRecentTasks.get(i);
8228                    // Skip tasks that do not match the caller.  We don't need to verify
8229                    // callingPackage, because we are also limiting to callingUid and know
8230                    // that will limit to the correct security sandbox.
8231                    if (tr.effectiveUid != callingUid) {
8232                        continue;
8233                    }
8234                    Intent intent = tr.getBaseIntent();
8235                    if (intent == null ||
8236                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8237                        continue;
8238                    }
8239                    ActivityManager.RecentTaskInfo taskInfo =
8240                            createRecentTaskInfoFromTaskRecord(tr);
8241                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8242                    list.add(taskImpl);
8243                }
8244            } finally {
8245                Binder.restoreCallingIdentity(ident);
8246            }
8247            return list;
8248        }
8249    }
8250
8251    @Override
8252    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8253        final int callingUid = Binder.getCallingUid();
8254        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8255
8256        synchronized(this) {
8257            if (DEBUG_ALL) Slog.v(
8258                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8259
8260            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8261                    callingUid);
8262
8263            // TODO: Improve with MRU list from all ActivityStacks.
8264            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8265        }
8266
8267        return list;
8268    }
8269
8270    /**
8271     * Creates a new RecentTaskInfo from a TaskRecord.
8272     */
8273    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8274        // Update the task description to reflect any changes in the task stack
8275        tr.updateTaskDescription();
8276
8277        // Compose the recent task info
8278        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8279        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8280        rti.persistentId = tr.taskId;
8281        rti.baseIntent = new Intent(tr.getBaseIntent());
8282        rti.origActivity = tr.origActivity;
8283        rti.description = tr.lastDescription;
8284        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8285        rti.userId = tr.userId;
8286        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8287        rti.firstActiveTime = tr.firstActiveTime;
8288        rti.lastActiveTime = tr.lastActiveTime;
8289        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8290        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8291        rti.numActivities = 0;
8292
8293        ActivityRecord base = null;
8294        ActivityRecord top = null;
8295        ActivityRecord tmp;
8296
8297        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8298            tmp = tr.mActivities.get(i);
8299            if (tmp.finishing) {
8300                continue;
8301            }
8302            base = tmp;
8303            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8304                top = base;
8305            }
8306            rti.numActivities++;
8307        }
8308
8309        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8310        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8311
8312        return rti;
8313    }
8314
8315    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8316        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8317                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8318        if (!allowed) {
8319            if (checkPermission(android.Manifest.permission.GET_TASKS,
8320                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8321                // Temporary compatibility: some existing apps on the system image may
8322                // still be requesting the old permission and not switched to the new
8323                // one; if so, we'll still allow them full access.  This means we need
8324                // to see if they are holding the old permission and are a system app.
8325                try {
8326                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8327                        allowed = true;
8328                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8329                                + " is using old GET_TASKS but privileged; allowing");
8330                    }
8331                } catch (RemoteException e) {
8332                }
8333            }
8334        }
8335        if (!allowed) {
8336            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8337                    + " does not hold REAL_GET_TASKS; limiting output");
8338        }
8339        return allowed;
8340    }
8341
8342    @Override
8343    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8344        final int callingUid = Binder.getCallingUid();
8345        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8346                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8347
8348        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8349        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8350        synchronized (this) {
8351            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8352                    callingUid);
8353            final boolean detailed = checkCallingPermission(
8354                    android.Manifest.permission.GET_DETAILED_TASKS)
8355                    == PackageManager.PERMISSION_GRANTED;
8356
8357            final int recentsCount = mRecentTasks.size();
8358            ArrayList<ActivityManager.RecentTaskInfo> res =
8359                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8360
8361            final Set<Integer> includedUsers;
8362            if (includeProfiles) {
8363                includedUsers = getProfileIdsLocked(userId);
8364            } else {
8365                includedUsers = new HashSet<>();
8366            }
8367            includedUsers.add(Integer.valueOf(userId));
8368
8369            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8370                TaskRecord tr = mRecentTasks.get(i);
8371                // Only add calling user or related users recent tasks
8372                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8373                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8374                    continue;
8375                }
8376
8377                // Return the entry if desired by the caller.  We always return
8378                // the first entry, because callers always expect this to be the
8379                // foreground app.  We may filter others if the caller has
8380                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8381                // we should exclude the entry.
8382
8383                if (i == 0
8384                        || withExcluded
8385                        || (tr.intent == null)
8386                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8387                                == 0)) {
8388                    if (!allowed) {
8389                        // If the caller doesn't have the GET_TASKS permission, then only
8390                        // allow them to see a small subset of tasks -- their own and home.
8391                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8392                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8393                            continue;
8394                        }
8395                    }
8396                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8397                        if (tr.stack != null && tr.stack.isHomeStack()) {
8398                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8399                                    "Skipping, home stack task: " + tr);
8400                            continue;
8401                        }
8402                    }
8403                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8404                        // Don't include auto remove tasks that are finished or finishing.
8405                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8406                                "Skipping, auto-remove without activity: " + tr);
8407                        continue;
8408                    }
8409                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8410                            && !tr.isAvailable) {
8411                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8412                                "Skipping, unavail real act: " + tr);
8413                        continue;
8414                    }
8415
8416                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8417                    if (!detailed) {
8418                        rti.baseIntent.replaceExtras((Bundle)null);
8419                    }
8420
8421                    res.add(rti);
8422                    maxNum--;
8423                }
8424            }
8425            return res;
8426        }
8427    }
8428
8429    @Override
8430    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8431        synchronized (this) {
8432            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8433                    "getTaskThumbnail()");
8434            TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id, false);
8435            if (tr != null) {
8436                return tr.getTaskThumbnailLocked();
8437            }
8438        }
8439        return null;
8440    }
8441
8442    @Override
8443    public int addAppTask(IBinder activityToken, Intent intent,
8444            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8445        final int callingUid = Binder.getCallingUid();
8446        final long callingIdent = Binder.clearCallingIdentity();
8447
8448        try {
8449            synchronized (this) {
8450                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8451                if (r == null) {
8452                    throw new IllegalArgumentException("Activity does not exist; token="
8453                            + activityToken);
8454                }
8455                ComponentName comp = intent.getComponent();
8456                if (comp == null) {
8457                    throw new IllegalArgumentException("Intent " + intent
8458                            + " must specify explicit component");
8459                }
8460                if (thumbnail.getWidth() != mThumbnailWidth
8461                        || thumbnail.getHeight() != mThumbnailHeight) {
8462                    throw new IllegalArgumentException("Bad thumbnail size: got "
8463                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8464                            + mThumbnailWidth + "x" + mThumbnailHeight);
8465                }
8466                if (intent.getSelector() != null) {
8467                    intent.setSelector(null);
8468                }
8469                if (intent.getSourceBounds() != null) {
8470                    intent.setSourceBounds(null);
8471                }
8472                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8473                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8474                        // The caller has added this as an auto-remove task...  that makes no
8475                        // sense, so turn off auto-remove.
8476                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8477                    }
8478                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8479                    // Must be a new task.
8480                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8481                }
8482                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8483                    mLastAddedTaskActivity = null;
8484                }
8485                ActivityInfo ainfo = mLastAddedTaskActivity;
8486                if (ainfo == null) {
8487                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8488                            comp, 0, UserHandle.getUserId(callingUid));
8489                    if (ainfo.applicationInfo.uid != callingUid) {
8490                        throw new SecurityException(
8491                                "Can't add task for another application: target uid="
8492                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8493                    }
8494                }
8495
8496                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8497                        intent, description);
8498
8499                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
8500                if (trimIdx >= 0) {
8501                    // If this would have caused a trim, then we'll abort because that
8502                    // means it would be added at the end of the list but then just removed.
8503                    return INVALID_TASK_ID;
8504                }
8505
8506                final int N = mRecentTasks.size();
8507                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8508                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8509                    tr.removedFromRecents();
8510                }
8511
8512                task.inRecents = true;
8513                mRecentTasks.add(task);
8514                r.task.stack.addTask(task, false, false);
8515
8516                task.setLastThumbnail(thumbnail);
8517                task.freeLastThumbnail();
8518
8519                return task.taskId;
8520            }
8521        } finally {
8522            Binder.restoreCallingIdentity(callingIdent);
8523        }
8524    }
8525
8526    @Override
8527    public Point getAppTaskThumbnailSize() {
8528        synchronized (this) {
8529            return new Point(mThumbnailWidth,  mThumbnailHeight);
8530        }
8531    }
8532
8533    @Override
8534    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8535        synchronized (this) {
8536            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8537            if (r != null) {
8538                r.setTaskDescription(td);
8539                r.task.updateTaskDescription();
8540            }
8541        }
8542    }
8543
8544    @Override
8545    public void setTaskResizeable(int taskId, boolean resizeable) {
8546        synchronized (this) {
8547            TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8548            if (task == null) {
8549                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
8550                return;
8551            }
8552            if (task.mResizeable != resizeable) {
8553                task.mResizeable = resizeable;
8554                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8555                mStackSupervisor.resumeTopActivitiesLocked();
8556            }
8557        }
8558    }
8559
8560    @Override
8561    public void resizeTask(int taskId, Rect bounds) {
8562        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8563                "resizeTask()");
8564        long ident = Binder.clearCallingIdentity();
8565        try {
8566            synchronized (this) {
8567                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8568                if (task == null) {
8569                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
8570                    return;
8571                }
8572                mStackSupervisor.resizeTaskLocked(task, bounds);
8573            }
8574        } finally {
8575            Binder.restoreCallingIdentity(ident);
8576        }
8577    }
8578
8579    @Override
8580    public Bitmap getTaskDescriptionIcon(String filename) {
8581        if (!FileUtils.isValidExtFilename(filename)
8582                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8583            throw new IllegalArgumentException("Bad filename: " + filename);
8584        }
8585        return mTaskPersister.getTaskDescriptionIcon(filename);
8586    }
8587
8588    @Override
8589    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8590            throws RemoteException {
8591        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8592                opts.getCustomInPlaceResId() == 0) {
8593            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8594                    "with valid animation");
8595        }
8596        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8597        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8598                opts.getCustomInPlaceResId());
8599        mWindowManager.executeAppTransition();
8600    }
8601
8602    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8603        mRecentTasks.remove(tr);
8604        tr.removedFromRecents();
8605        ComponentName component = tr.getBaseIntent().getComponent();
8606        if (component == null) {
8607            Slog.w(TAG, "No component for base intent of task: " + tr);
8608            return;
8609        }
8610
8611        // Find any running services associated with this app and stop if needed.
8612        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8613
8614        if (!killProcess) {
8615            return;
8616        }
8617
8618        // Determine if the process(es) for this task should be killed.
8619        final String pkg = component.getPackageName();
8620        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
8621        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8622        for (int i = 0; i < pmap.size(); i++) {
8623
8624            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8625            for (int j = 0; j < uids.size(); j++) {
8626                ProcessRecord proc = uids.valueAt(j);
8627                if (proc.userId != tr.userId) {
8628                    // Don't kill process for a different user.
8629                    continue;
8630                }
8631                if (proc == mHomeProcess) {
8632                    // Don't kill the home process along with tasks from the same package.
8633                    continue;
8634                }
8635                if (!proc.pkgList.containsKey(pkg)) {
8636                    // Don't kill process that is not associated with this task.
8637                    continue;
8638                }
8639
8640                for (int k = 0; k < proc.activities.size(); k++) {
8641                    TaskRecord otherTask = proc.activities.get(k).task;
8642                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8643                        // Don't kill process(es) that has an activity in a different task that is
8644                        // also in recents.
8645                        return;
8646                    }
8647                }
8648
8649                if (proc.foregroundServices) {
8650                    // Don't kill process(es) with foreground service.
8651                    return;
8652                }
8653
8654                // Add process to kill list.
8655                procsToKill.add(proc);
8656            }
8657        }
8658
8659        // Kill the running processes.
8660        for (int i = 0; i < procsToKill.size(); i++) {
8661            ProcessRecord pr = procsToKill.get(i);
8662            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
8663                    && pr.curReceiver == null) {
8664                pr.kill("remove task", true);
8665            } else {
8666                // We delay killing processes that are not in the background or running a receiver.
8667                pr.waitingToKill = "remove task";
8668            }
8669        }
8670    }
8671
8672    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8673        // Remove all tasks with activities in the specified package from the list of recent tasks
8674        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8675            TaskRecord tr = mRecentTasks.get(i);
8676            if (tr.userId != userId) continue;
8677
8678            ComponentName cn = tr.intent.getComponent();
8679            if (cn != null && cn.getPackageName().equals(packageName)) {
8680                // If the package name matches, remove the task.
8681                removeTaskByIdLocked(tr.taskId, true);
8682            }
8683        }
8684    }
8685
8686    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
8687            int userId) {
8688
8689        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8690            TaskRecord tr = mRecentTasks.get(i);
8691            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
8692                continue;
8693            }
8694
8695            ComponentName cn = tr.intent.getComponent();
8696            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
8697                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
8698            if (sameComponent) {
8699                removeTaskByIdLocked(tr.taskId, false);
8700            }
8701        }
8702    }
8703
8704    /**
8705     * Removes the task with the specified task id.
8706     *
8707     * @param taskId Identifier of the task to be removed.
8708     * @param killProcess Kill any process associated with the task if possible.
8709     * @return Returns true if the given task was found and removed.
8710     */
8711    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8712        TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8713        if (tr != null) {
8714            tr.removeTaskActivitiesLocked();
8715            cleanUpRemovedTaskLocked(tr, killProcess);
8716            if (tr.isPersistable) {
8717                notifyTaskPersisterLocked(null, true);
8718            }
8719            return true;
8720        }
8721        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8722        return false;
8723    }
8724
8725    @Override
8726    public boolean removeTask(int taskId) {
8727        synchronized (this) {
8728            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8729                    "removeTask()");
8730            long ident = Binder.clearCallingIdentity();
8731            try {
8732                return removeTaskByIdLocked(taskId, true);
8733            } finally {
8734                Binder.restoreCallingIdentity(ident);
8735            }
8736        }
8737    }
8738
8739    /**
8740     * TODO: Add mController hook
8741     */
8742    @Override
8743    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8744        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
8745
8746        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
8747        synchronized(this) {
8748            moveTaskToFrontLocked(taskId, flags, options);
8749        }
8750    }
8751
8752    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8753        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8754                Binder.getCallingUid(), -1, -1, "Task to front")) {
8755            ActivityOptions.abort(options);
8756            return;
8757        }
8758        final long origId = Binder.clearCallingIdentity();
8759        try {
8760            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8761            if (task == null) {
8762                Slog.d(TAG, "Could not find task for id: "+ taskId);
8763                return;
8764            }
8765            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8766                mStackSupervisor.showLockTaskToast();
8767                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8768                return;
8769            }
8770            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8771            if (prev != null && prev.isRecentsActivity()) {
8772                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8773            }
8774            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
8775        } finally {
8776            Binder.restoreCallingIdentity(origId);
8777        }
8778        ActivityOptions.abort(options);
8779    }
8780
8781    /**
8782     * Moves an activity, and all of the other activities within the same task, to the bottom
8783     * of the history stack.  The activity's order within the task is unchanged.
8784     *
8785     * @param token A reference to the activity we wish to move
8786     * @param nonRoot If false then this only works if the activity is the root
8787     *                of a task; if true it will work for any activity in a task.
8788     * @return Returns true if the move completed, false if not.
8789     */
8790    @Override
8791    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8792        enforceNotIsolatedCaller("moveActivityTaskToBack");
8793        synchronized(this) {
8794            final long origId = Binder.clearCallingIdentity();
8795            try {
8796                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8797                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8798                if (task != null) {
8799                    if (mStackSupervisor.isLockedTask(task)) {
8800                        mStackSupervisor.showLockTaskToast();
8801                        return false;
8802                    }
8803                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
8804                }
8805            } finally {
8806                Binder.restoreCallingIdentity(origId);
8807            }
8808        }
8809        return false;
8810    }
8811
8812    @Override
8813    public void moveTaskBackwards(int task) {
8814        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8815                "moveTaskBackwards()");
8816
8817        synchronized(this) {
8818            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8819                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8820                return;
8821            }
8822            final long origId = Binder.clearCallingIdentity();
8823            moveTaskBackwardsLocked(task);
8824            Binder.restoreCallingIdentity(origId);
8825        }
8826    }
8827
8828    private final void moveTaskBackwardsLocked(int task) {
8829        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8830    }
8831
8832    @Override
8833    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
8834            IActivityContainerCallback callback) throws RemoteException {
8835        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8836                "createActivityContainer()");
8837        synchronized (this) {
8838            if (parentActivityToken == null) {
8839                throw new IllegalArgumentException("parent token must not be null");
8840            }
8841            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
8842            if (r == null) {
8843                return null;
8844            }
8845            if (callback == null) {
8846                throw new IllegalArgumentException("callback must not be null");
8847            }
8848            return mStackSupervisor.createVirtualActivityContainer(r, callback);
8849        }
8850    }
8851
8852    @Override
8853    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8854        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8855                "deleteActivityContainer()");
8856        synchronized (this) {
8857            mStackSupervisor.deleteActivityContainer(container);
8858        }
8859    }
8860
8861    @Override
8862    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
8863        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8864                "createStackOnDisplay()");
8865        synchronized (this) {
8866            final int stackId = mStackSupervisor.getNextStackId();
8867            final ActivityStack stack = mStackSupervisor.createStackOnDisplay(stackId, displayId);
8868            if (stack == null) {
8869                return null;
8870            }
8871            return stack.mActivityContainer;
8872        }
8873    }
8874
8875    @Override
8876    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
8877        synchronized (this) {
8878            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8879            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
8880                return stack.mActivityContainer.getDisplayId();
8881            }
8882            return Display.DEFAULT_DISPLAY;
8883        }
8884    }
8885
8886    @Override
8887    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8888        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8889                "moveTaskToStack()");
8890        if (stackId == HOME_STACK_ID) {
8891            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8892                    new RuntimeException("here").fillInStackTrace());
8893        }
8894        synchronized (this) {
8895            long ident = Binder.clearCallingIdentity();
8896            try {
8897                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
8898                        + " to stackId=" + stackId + " toTop=" + toTop);
8899                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop);
8900            } finally {
8901                Binder.restoreCallingIdentity(ident);
8902            }
8903        }
8904    }
8905
8906    @Override
8907    public void resizeStack(int stackId, Rect bounds) {
8908        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8909                "resizeStack()");
8910        long ident = Binder.clearCallingIdentity();
8911        try {
8912            synchronized (this) {
8913                mStackSupervisor.resizeStackLocked(stackId, bounds);
8914            }
8915        } finally {
8916            Binder.restoreCallingIdentity(ident);
8917        }
8918    }
8919
8920    @Override
8921    public List<StackInfo> getAllStackInfos() {
8922        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8923                "getAllStackInfos()");
8924        long ident = Binder.clearCallingIdentity();
8925        try {
8926            synchronized (this) {
8927                return mStackSupervisor.getAllStackInfosLocked();
8928            }
8929        } finally {
8930            Binder.restoreCallingIdentity(ident);
8931        }
8932    }
8933
8934    @Override
8935    public StackInfo getStackInfo(int stackId) {
8936        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8937                "getStackInfo()");
8938        long ident = Binder.clearCallingIdentity();
8939        try {
8940            synchronized (this) {
8941                return mStackSupervisor.getStackInfoLocked(stackId);
8942            }
8943        } finally {
8944            Binder.restoreCallingIdentity(ident);
8945        }
8946    }
8947
8948    @Override
8949    public boolean isInHomeStack(int taskId) {
8950        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8951                "getStackInfo()");
8952        long ident = Binder.clearCallingIdentity();
8953        try {
8954            synchronized (this) {
8955                TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8956                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8957            }
8958        } finally {
8959            Binder.restoreCallingIdentity(ident);
8960        }
8961    }
8962
8963    @Override
8964    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8965        synchronized(this) {
8966            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8967        }
8968    }
8969
8970    @Override
8971    public void updateDeviceOwner(String packageName) {
8972        final int callingUid = Binder.getCallingUid();
8973        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
8974            throw new SecurityException("updateDeviceOwner called from non-system process");
8975        }
8976        synchronized (this) {
8977            mDeviceOwnerName = packageName;
8978        }
8979    }
8980
8981    @Override
8982    public void updateLockTaskPackages(int userId, String[] packages) {
8983        final int callingUid = Binder.getCallingUid();
8984        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
8985            throw new SecurityException("updateLockTaskPackage called from non-system process");
8986        }
8987        synchronized (this) {
8988            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
8989                    Arrays.toString(packages));
8990            mLockTaskPackages.put(userId, packages);
8991            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
8992        }
8993    }
8994
8995
8996    void startLockTaskModeLocked(TaskRecord task) {
8997        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
8998        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
8999            return;
9000        }
9001
9002        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9003        // is initiated by system after the pinning request was shown and locked mode is initiated
9004        // by an authorized app directly
9005        final int callingUid = Binder.getCallingUid();
9006        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9007        long ident = Binder.clearCallingIdentity();
9008        try {
9009            final ActivityStack stack = mStackSupervisor.getFocusedStack();
9010            if (!isSystemInitiated) {
9011                task.mLockTaskUid = callingUid;
9012                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9013                    // startLockTask() called by app and task mode is lockTaskModeDefault.
9014                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9015                    StatusBarManagerInternal statusBarManager =
9016                            LocalServices.getService(StatusBarManagerInternal.class);
9017                    if (statusBarManager != null) {
9018                        statusBarManager.showScreenPinningRequest();
9019                    }
9020                    return;
9021                }
9022
9023                if (stack == null || task != stack.topTask()) {
9024                    throw new IllegalArgumentException("Invalid task, not in foreground");
9025                }
9026            }
9027            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9028                    "Locking fully");
9029            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9030                    ActivityManager.LOCK_TASK_MODE_PINNED :
9031                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9032                    "startLockTask", true);
9033        } finally {
9034            Binder.restoreCallingIdentity(ident);
9035        }
9036    }
9037
9038    @Override
9039    public void startLockTaskMode(int taskId) {
9040        synchronized (this) {
9041            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9042            if (task != null) {
9043                startLockTaskModeLocked(task);
9044            }
9045        }
9046    }
9047
9048    @Override
9049    public void startLockTaskMode(IBinder token) {
9050        synchronized (this) {
9051            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9052            if (r == null) {
9053                return;
9054            }
9055            final TaskRecord task = r.task;
9056            if (task != null) {
9057                startLockTaskModeLocked(task);
9058            }
9059        }
9060    }
9061
9062    @Override
9063    public void startLockTaskModeOnCurrent() throws RemoteException {
9064        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9065                "startLockTaskModeOnCurrent");
9066        long ident = Binder.clearCallingIdentity();
9067        try {
9068            synchronized (this) {
9069                ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9070                if (r != null) {
9071                    startLockTaskModeLocked(r.task);
9072                }
9073            }
9074        } finally {
9075            Binder.restoreCallingIdentity(ident);
9076        }
9077    }
9078
9079    @Override
9080    public void stopLockTaskMode() {
9081        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9082        if (lockTask == null) {
9083            // Our work here is done.
9084            return;
9085        }
9086
9087        final int callingUid = Binder.getCallingUid();
9088        final int lockTaskUid = lockTask.mLockTaskUid;
9089        // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9090        // It is possible lockTaskMode was started by the system process because
9091        // android:lockTaskMode is set to a locking value in the application manifest instead of
9092        // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9093        // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9094        if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9095                callingUid != lockTaskUid
9096                && (lockTaskUid != 0
9097                    || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9098            throw new SecurityException("Invalid uid, expected " + lockTaskUid
9099                    + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9100        }
9101
9102        long ident = Binder.clearCallingIdentity();
9103        try {
9104            Log.d(TAG, "stopLockTaskMode");
9105            // Stop lock task
9106            synchronized (this) {
9107                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9108                        "stopLockTask", true);
9109            }
9110        } finally {
9111            Binder.restoreCallingIdentity(ident);
9112        }
9113    }
9114
9115    @Override
9116    public void stopLockTaskModeOnCurrent() throws RemoteException {
9117        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9118                "stopLockTaskModeOnCurrent");
9119        long ident = Binder.clearCallingIdentity();
9120        try {
9121            stopLockTaskMode();
9122        } finally {
9123            Binder.restoreCallingIdentity(ident);
9124        }
9125    }
9126
9127    @Override
9128    public boolean isInLockTaskMode() {
9129        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9130    }
9131
9132    @Override
9133    public int getLockTaskModeState() {
9134        synchronized (this) {
9135            return mStackSupervisor.getLockTaskModeState();
9136        }
9137    }
9138
9139    @Override
9140    public void showLockTaskEscapeMessage(IBinder token) {
9141        synchronized (this) {
9142            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9143            if (r == null) {
9144                return;
9145            }
9146            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9147        }
9148    }
9149
9150    // =========================================================
9151    // CONTENT PROVIDERS
9152    // =========================================================
9153
9154    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9155        List<ProviderInfo> providers = null;
9156        try {
9157            ParceledListSlice<ProviderInfo> slice = AppGlobals.getPackageManager().
9158                queryContentProviders(app.processName, app.uid,
9159                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
9160            providers = slice != null ? slice.getList() : null;
9161        } catch (RemoteException ex) {
9162        }
9163        if (DEBUG_MU) Slog.v(TAG_MU,
9164                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9165        int userId = app.userId;
9166        if (providers != null) {
9167            int N = providers.size();
9168            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9169            for (int i=0; i<N; i++) {
9170                ProviderInfo cpi =
9171                    (ProviderInfo)providers.get(i);
9172                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9173                        cpi.name, cpi.flags);
9174                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_OWNER) {
9175                    // This is a singleton provider, but a user besides the
9176                    // default user is asking to initialize a process it runs
9177                    // in...  well, no, it doesn't actually run in this process,
9178                    // it runs in the process of the default user.  Get rid of it.
9179                    providers.remove(i);
9180                    N--;
9181                    i--;
9182                    continue;
9183                }
9184
9185                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9186                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9187                if (cpr == null) {
9188                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9189                    mProviderMap.putProviderByClass(comp, cpr);
9190                }
9191                if (DEBUG_MU) Slog.v(TAG_MU,
9192                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9193                app.pubProviders.put(cpi.name, cpr);
9194                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9195                    // Don't add this if it is a platform component that is marked
9196                    // to run in multiple processes, because this is actually
9197                    // part of the framework so doesn't make sense to track as a
9198                    // separate apk in the process.
9199                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9200                            mProcessStats);
9201                }
9202                ensurePackageDexOpt(cpi.applicationInfo.packageName);
9203            }
9204        }
9205        return providers;
9206    }
9207
9208    /**
9209     * Check if {@link ProcessRecord} has a possible chance at accessing the
9210     * given {@link ProviderInfo}. Final permission checking is always done
9211     * in {@link ContentProvider}.
9212     */
9213    private final String checkContentProviderPermissionLocked(
9214            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9215        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9216        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9217        boolean checkedGrants = false;
9218        if (checkUser) {
9219            // Looking for cross-user grants before enforcing the typical cross-users permissions
9220            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
9221            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9222                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9223                    return null;
9224                }
9225                checkedGrants = true;
9226            }
9227            userId = handleIncomingUser(callingPid, callingUid, userId,
9228                    false, ALLOW_NON_FULL,
9229                    "checkContentProviderPermissionLocked " + cpi.authority, null);
9230            if (userId != tmpTargetUserId) {
9231                // When we actually went to determine the final targer user ID, this ended
9232                // up different than our initial check for the authority.  This is because
9233                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9234                // SELF.  So we need to re-check the grants again.
9235                checkedGrants = false;
9236            }
9237        }
9238        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9239                cpi.applicationInfo.uid, cpi.exported)
9240                == PackageManager.PERMISSION_GRANTED) {
9241            return null;
9242        }
9243        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9244                cpi.applicationInfo.uid, cpi.exported)
9245                == PackageManager.PERMISSION_GRANTED) {
9246            return null;
9247        }
9248
9249        PathPermission[] pps = cpi.pathPermissions;
9250        if (pps != null) {
9251            int i = pps.length;
9252            while (i > 0) {
9253                i--;
9254                PathPermission pp = pps[i];
9255                String pprperm = pp.getReadPermission();
9256                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9257                        cpi.applicationInfo.uid, cpi.exported)
9258                        == PackageManager.PERMISSION_GRANTED) {
9259                    return null;
9260                }
9261                String ppwperm = pp.getWritePermission();
9262                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9263                        cpi.applicationInfo.uid, cpi.exported)
9264                        == PackageManager.PERMISSION_GRANTED) {
9265                    return null;
9266                }
9267            }
9268        }
9269        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9270            return null;
9271        }
9272
9273        String msg;
9274        if (!cpi.exported) {
9275            msg = "Permission Denial: opening provider " + cpi.name
9276                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9277                    + ", uid=" + callingUid + ") that is not exported from uid "
9278                    + cpi.applicationInfo.uid;
9279        } else {
9280            msg = "Permission Denial: opening provider " + cpi.name
9281                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9282                    + ", uid=" + callingUid + ") requires "
9283                    + cpi.readPermission + " or " + cpi.writePermission;
9284        }
9285        Slog.w(TAG, msg);
9286        return msg;
9287    }
9288
9289    /**
9290     * Returns if the ContentProvider has granted a uri to callingUid
9291     */
9292    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9293        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9294        if (perms != null) {
9295            for (int i=perms.size()-1; i>=0; i--) {
9296                GrantUri grantUri = perms.keyAt(i);
9297                if (grantUri.sourceUserId == userId || !checkUser) {
9298                    if (matchesProvider(grantUri.uri, cpi)) {
9299                        return true;
9300                    }
9301                }
9302            }
9303        }
9304        return false;
9305    }
9306
9307    /**
9308     * Returns true if the uri authority is one of the authorities specified in the provider.
9309     */
9310    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9311        String uriAuth = uri.getAuthority();
9312        String cpiAuth = cpi.authority;
9313        if (cpiAuth.indexOf(';') == -1) {
9314            return cpiAuth.equals(uriAuth);
9315        }
9316        String[] cpiAuths = cpiAuth.split(";");
9317        int length = cpiAuths.length;
9318        for (int i = 0; i < length; i++) {
9319            if (cpiAuths[i].equals(uriAuth)) return true;
9320        }
9321        return false;
9322    }
9323
9324    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9325            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9326        if (r != null) {
9327            for (int i=0; i<r.conProviders.size(); i++) {
9328                ContentProviderConnection conn = r.conProviders.get(i);
9329                if (conn.provider == cpr) {
9330                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9331                            "Adding provider requested by "
9332                            + r.processName + " from process "
9333                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9334                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9335                    if (stable) {
9336                        conn.stableCount++;
9337                        conn.numStableIncs++;
9338                    } else {
9339                        conn.unstableCount++;
9340                        conn.numUnstableIncs++;
9341                    }
9342                    return conn;
9343                }
9344            }
9345            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9346            if (stable) {
9347                conn.stableCount = 1;
9348                conn.numStableIncs = 1;
9349            } else {
9350                conn.unstableCount = 1;
9351                conn.numUnstableIncs = 1;
9352            }
9353            cpr.connections.add(conn);
9354            r.conProviders.add(conn);
9355            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9356            return conn;
9357        }
9358        cpr.addExternalProcessHandleLocked(externalProcessToken);
9359        return null;
9360    }
9361
9362    boolean decProviderCountLocked(ContentProviderConnection conn,
9363            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9364        if (conn != null) {
9365            cpr = conn.provider;
9366            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9367                    "Removing provider requested by "
9368                    + conn.client.processName + " from process "
9369                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9370                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9371            if (stable) {
9372                conn.stableCount--;
9373            } else {
9374                conn.unstableCount--;
9375            }
9376            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9377                cpr.connections.remove(conn);
9378                conn.client.conProviders.remove(conn);
9379                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9380                return true;
9381            }
9382            return false;
9383        }
9384        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9385        return false;
9386    }
9387
9388    private void checkTime(long startTime, String where) {
9389        long now = SystemClock.elapsedRealtime();
9390        if ((now-startTime) > 1000) {
9391            // If we are taking more than a second, log about it.
9392            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9393        }
9394    }
9395
9396    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9397            String name, IBinder token, boolean stable, int userId) {
9398        ContentProviderRecord cpr;
9399        ContentProviderConnection conn = null;
9400        ProviderInfo cpi = null;
9401
9402        synchronized(this) {
9403            long startTime = SystemClock.elapsedRealtime();
9404
9405            ProcessRecord r = null;
9406            if (caller != null) {
9407                r = getRecordForAppLocked(caller);
9408                if (r == null) {
9409                    throw new SecurityException(
9410                            "Unable to find app for caller " + caller
9411                          + " (pid=" + Binder.getCallingPid()
9412                          + ") when getting content provider " + name);
9413                }
9414            }
9415
9416            boolean checkCrossUser = true;
9417
9418            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9419
9420            // First check if this content provider has been published...
9421            cpr = mProviderMap.getProviderByName(name, userId);
9422            // If that didn't work, check if it exists for user 0 and then
9423            // verify that it's a singleton provider before using it.
9424            if (cpr == null && userId != UserHandle.USER_OWNER) {
9425                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9426                if (cpr != null) {
9427                    cpi = cpr.info;
9428                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9429                            cpi.name, cpi.flags)
9430                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9431                        userId = UserHandle.USER_OWNER;
9432                        checkCrossUser = false;
9433                    } else {
9434                        cpr = null;
9435                        cpi = null;
9436                    }
9437                }
9438            }
9439
9440            boolean providerRunning = cpr != null;
9441            if (providerRunning) {
9442                cpi = cpr.info;
9443                String msg;
9444                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9445                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9446                        != null) {
9447                    throw new SecurityException(msg);
9448                }
9449                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9450
9451                if (r != null && cpr.canRunHere(r)) {
9452                    // This provider has been published or is in the process
9453                    // of being published...  but it is also allowed to run
9454                    // in the caller's process, so don't make a connection
9455                    // and just let the caller instantiate its own instance.
9456                    ContentProviderHolder holder = cpr.newHolder(null);
9457                    // don't give caller the provider object, it needs
9458                    // to make its own.
9459                    holder.provider = null;
9460                    return holder;
9461                }
9462
9463                final long origId = Binder.clearCallingIdentity();
9464
9465                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9466
9467                // In this case the provider instance already exists, so we can
9468                // return it right away.
9469                conn = incProviderCountLocked(r, cpr, token, stable);
9470                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9471                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9472                        // If this is a perceptible app accessing the provider,
9473                        // make sure to count it as being accessed and thus
9474                        // back up on the LRU list.  This is good because
9475                        // content providers are often expensive to start.
9476                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9477                        updateLruProcessLocked(cpr.proc, false, null);
9478                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9479                    }
9480                }
9481
9482                if (cpr.proc != null) {
9483                    if (false) {
9484                        if (cpr.name.flattenToShortString().equals(
9485                                "com.android.providers.calendar/.CalendarProvider2")) {
9486                            Slog.v(TAG, "****************** KILLING "
9487                                + cpr.name.flattenToShortString());
9488                            Process.killProcess(cpr.proc.pid);
9489                        }
9490                    }
9491                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9492                    boolean success = updateOomAdjLocked(cpr.proc);
9493                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
9494                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9495                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
9496                    // NOTE: there is still a race here where a signal could be
9497                    // pending on the process even though we managed to update its
9498                    // adj level.  Not sure what to do about this, but at least
9499                    // the race is now smaller.
9500                    if (!success) {
9501                        // Uh oh...  it looks like the provider's process
9502                        // has been killed on us.  We need to wait for a new
9503                        // process to be started, and make sure its death
9504                        // doesn't kill our process.
9505                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
9506                                + " is crashing; detaching " + r);
9507                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9508                        checkTime(startTime, "getContentProviderImpl: before appDied");
9509                        appDiedLocked(cpr.proc);
9510                        checkTime(startTime, "getContentProviderImpl: after appDied");
9511                        if (!lastRef) {
9512                            // This wasn't the last ref our process had on
9513                            // the provider...  we have now been killed, bail.
9514                            return null;
9515                        }
9516                        providerRunning = false;
9517                        conn = null;
9518                    }
9519                }
9520
9521                Binder.restoreCallingIdentity(origId);
9522            }
9523
9524            boolean singleton;
9525            if (!providerRunning) {
9526                try {
9527                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9528                    cpi = AppGlobals.getPackageManager().
9529                        resolveContentProvider(name,
9530                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9531                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9532                } catch (RemoteException ex) {
9533                }
9534                if (cpi == null) {
9535                    return null;
9536                }
9537                // If the provider is a singleton AND
9538                // (it's a call within the same user || the provider is a
9539                // privileged app)
9540                // Then allow connecting to the singleton provider
9541                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9542                        cpi.name, cpi.flags)
9543                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9544                if (singleton) {
9545                    userId = UserHandle.USER_OWNER;
9546                }
9547                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9548                checkTime(startTime, "getContentProviderImpl: got app info for user");
9549
9550                String msg;
9551                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9552                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9553                        != null) {
9554                    throw new SecurityException(msg);
9555                }
9556                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9557
9558                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9559                        && !cpi.processName.equals("system")) {
9560                    // If this content provider does not run in the system
9561                    // process, and the system is not yet ready to run other
9562                    // processes, then fail fast instead of hanging.
9563                    throw new IllegalArgumentException(
9564                            "Attempt to launch content provider before system ready");
9565                }
9566
9567                // Make sure that the user who owns this provider is running.  If not,
9568                // we don't want to allow it to run.
9569                if (!isUserRunningLocked(userId, false)) {
9570                    Slog.w(TAG, "Unable to launch app "
9571                            + cpi.applicationInfo.packageName + "/"
9572                            + cpi.applicationInfo.uid + " for provider "
9573                            + name + ": user " + userId + " is stopped");
9574                    return null;
9575                }
9576
9577                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9578                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9579                cpr = mProviderMap.getProviderByClass(comp, userId);
9580                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9581                final boolean firstClass = cpr == null;
9582                if (firstClass) {
9583                    final long ident = Binder.clearCallingIdentity();
9584                    try {
9585                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9586                        ApplicationInfo ai =
9587                            AppGlobals.getPackageManager().
9588                                getApplicationInfo(
9589                                        cpi.applicationInfo.packageName,
9590                                        STOCK_PM_FLAGS, userId);
9591                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9592                        if (ai == null) {
9593                            Slog.w(TAG, "No package info for content provider "
9594                                    + cpi.name);
9595                            return null;
9596                        }
9597                        ai = getAppInfoForUser(ai, userId);
9598                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9599                    } catch (RemoteException ex) {
9600                        // pm is in same process, this will never happen.
9601                    } finally {
9602                        Binder.restoreCallingIdentity(ident);
9603                    }
9604                }
9605
9606                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9607
9608                if (r != null && cpr.canRunHere(r)) {
9609                    // If this is a multiprocess provider, then just return its
9610                    // info and allow the caller to instantiate it.  Only do
9611                    // this if the provider is the same user as the caller's
9612                    // process, or can run as root (so can be in any process).
9613                    return cpr.newHolder(null);
9614                }
9615
9616                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
9617                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
9618                            + cpr.info.name + " callers=" + Debug.getCallers(6));
9619
9620                // This is single process, and our app is now connecting to it.
9621                // See if we are already in the process of launching this
9622                // provider.
9623                final int N = mLaunchingProviders.size();
9624                int i;
9625                for (i = 0; i < N; i++) {
9626                    if (mLaunchingProviders.get(i) == cpr) {
9627                        break;
9628                    }
9629                }
9630
9631                // If the provider is not already being launched, then get it
9632                // started.
9633                if (i >= N) {
9634                    final long origId = Binder.clearCallingIdentity();
9635
9636                    try {
9637                        // Content provider is now in use, its package can't be stopped.
9638                        try {
9639                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9640                            AppGlobals.getPackageManager().setPackageStoppedState(
9641                                    cpr.appInfo.packageName, false, userId);
9642                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9643                        } catch (RemoteException e) {
9644                        } catch (IllegalArgumentException e) {
9645                            Slog.w(TAG, "Failed trying to unstop package "
9646                                    + cpr.appInfo.packageName + ": " + e);
9647                        }
9648
9649                        // Use existing process if already started
9650                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9651                        ProcessRecord proc = getProcessRecordLocked(
9652                                cpi.processName, cpr.appInfo.uid, false);
9653                        if (proc != null && proc.thread != null) {
9654                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
9655                                    "Installing in existing process " + proc);
9656                            if (!proc.pubProviders.containsKey(cpi.name)) {
9657                                checkTime(startTime, "getContentProviderImpl: scheduling install");
9658                                proc.pubProviders.put(cpi.name, cpr);
9659                                try {
9660                                    proc.thread.scheduleInstallProvider(cpi);
9661                                } catch (RemoteException e) {
9662                                }
9663                            }
9664                        } else {
9665                            checkTime(startTime, "getContentProviderImpl: before start process");
9666                            proc = startProcessLocked(cpi.processName,
9667                                    cpr.appInfo, false, 0, "content provider",
9668                                    new ComponentName(cpi.applicationInfo.packageName,
9669                                            cpi.name), false, false, false);
9670                            checkTime(startTime, "getContentProviderImpl: after start process");
9671                            if (proc == null) {
9672                                Slog.w(TAG, "Unable to launch app "
9673                                        + cpi.applicationInfo.packageName + "/"
9674                                        + cpi.applicationInfo.uid + " for provider "
9675                                        + name + ": process is bad");
9676                                return null;
9677                            }
9678                        }
9679                        cpr.launchingApp = proc;
9680                        mLaunchingProviders.add(cpr);
9681                    } finally {
9682                        Binder.restoreCallingIdentity(origId);
9683                    }
9684                }
9685
9686                checkTime(startTime, "getContentProviderImpl: updating data structures");
9687
9688                // Make sure the provider is published (the same provider class
9689                // may be published under multiple names).
9690                if (firstClass) {
9691                    mProviderMap.putProviderByClass(comp, cpr);
9692                }
9693
9694                mProviderMap.putProviderByName(name, cpr);
9695                conn = incProviderCountLocked(r, cpr, token, stable);
9696                if (conn != null) {
9697                    conn.waiting = true;
9698                }
9699            }
9700            checkTime(startTime, "getContentProviderImpl: done!");
9701        }
9702
9703        // Wait for the provider to be published...
9704        synchronized (cpr) {
9705            while (cpr.provider == null) {
9706                if (cpr.launchingApp == null) {
9707                    Slog.w(TAG, "Unable to launch app "
9708                            + cpi.applicationInfo.packageName + "/"
9709                            + cpi.applicationInfo.uid + " for provider "
9710                            + name + ": launching app became null");
9711                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9712                            UserHandle.getUserId(cpi.applicationInfo.uid),
9713                            cpi.applicationInfo.packageName,
9714                            cpi.applicationInfo.uid, name);
9715                    return null;
9716                }
9717                try {
9718                    if (DEBUG_MU) Slog.v(TAG_MU,
9719                            "Waiting to start provider " + cpr
9720                            + " launchingApp=" + cpr.launchingApp);
9721                    if (conn != null) {
9722                        conn.waiting = true;
9723                    }
9724                    cpr.wait();
9725                } catch (InterruptedException ex) {
9726                } finally {
9727                    if (conn != null) {
9728                        conn.waiting = false;
9729                    }
9730                }
9731            }
9732        }
9733        return cpr != null ? cpr.newHolder(conn) : null;
9734    }
9735
9736    @Override
9737    public final ContentProviderHolder getContentProvider(
9738            IApplicationThread caller, String name, int userId, boolean stable) {
9739        enforceNotIsolatedCaller("getContentProvider");
9740        if (caller == null) {
9741            String msg = "null IApplicationThread when getting content provider "
9742                    + name;
9743            Slog.w(TAG, msg);
9744            throw new SecurityException(msg);
9745        }
9746        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9747        // with cross-user grant.
9748        return getContentProviderImpl(caller, name, null, stable, userId);
9749    }
9750
9751    public ContentProviderHolder getContentProviderExternal(
9752            String name, int userId, IBinder token) {
9753        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9754            "Do not have permission in call getContentProviderExternal()");
9755        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9756                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9757        return getContentProviderExternalUnchecked(name, token, userId);
9758    }
9759
9760    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9761            IBinder token, int userId) {
9762        return getContentProviderImpl(null, name, token, true, userId);
9763    }
9764
9765    /**
9766     * Drop a content provider from a ProcessRecord's bookkeeping
9767     */
9768    public void removeContentProvider(IBinder connection, boolean stable) {
9769        enforceNotIsolatedCaller("removeContentProvider");
9770        long ident = Binder.clearCallingIdentity();
9771        try {
9772            synchronized (this) {
9773                ContentProviderConnection conn;
9774                try {
9775                    conn = (ContentProviderConnection)connection;
9776                } catch (ClassCastException e) {
9777                    String msg ="removeContentProvider: " + connection
9778                            + " not a ContentProviderConnection";
9779                    Slog.w(TAG, msg);
9780                    throw new IllegalArgumentException(msg);
9781                }
9782                if (conn == null) {
9783                    throw new NullPointerException("connection is null");
9784                }
9785                if (decProviderCountLocked(conn, null, null, stable)) {
9786                    updateOomAdjLocked();
9787                }
9788            }
9789        } finally {
9790            Binder.restoreCallingIdentity(ident);
9791        }
9792    }
9793
9794    public void removeContentProviderExternal(String name, IBinder token) {
9795        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9796            "Do not have permission in call removeContentProviderExternal()");
9797        int userId = UserHandle.getCallingUserId();
9798        long ident = Binder.clearCallingIdentity();
9799        try {
9800            removeContentProviderExternalUnchecked(name, token, userId);
9801        } finally {
9802            Binder.restoreCallingIdentity(ident);
9803        }
9804    }
9805
9806    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9807        synchronized (this) {
9808            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9809            if(cpr == null) {
9810                //remove from mProvidersByClass
9811                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
9812                return;
9813            }
9814
9815            //update content provider record entry info
9816            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9817            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9818            if (localCpr.hasExternalProcessHandles()) {
9819                if (localCpr.removeExternalProcessHandleLocked(token)) {
9820                    updateOomAdjLocked();
9821                } else {
9822                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9823                            + " with no external reference for token: "
9824                            + token + ".");
9825                }
9826            } else {
9827                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9828                        + " with no external references.");
9829            }
9830        }
9831    }
9832
9833    public final void publishContentProviders(IApplicationThread caller,
9834            List<ContentProviderHolder> providers) {
9835        if (providers == null) {
9836            return;
9837        }
9838
9839        enforceNotIsolatedCaller("publishContentProviders");
9840        synchronized (this) {
9841            final ProcessRecord r = getRecordForAppLocked(caller);
9842            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9843            if (r == null) {
9844                throw new SecurityException(
9845                        "Unable to find app for caller " + caller
9846                      + " (pid=" + Binder.getCallingPid()
9847                      + ") when publishing content providers");
9848            }
9849
9850            final long origId = Binder.clearCallingIdentity();
9851
9852            final int N = providers.size();
9853            for (int i=0; i<N; i++) {
9854                ContentProviderHolder src = providers.get(i);
9855                if (src == null || src.info == null || src.provider == null) {
9856                    continue;
9857                }
9858                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9859                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9860                if (dst != null) {
9861                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9862                    mProviderMap.putProviderByClass(comp, dst);
9863                    String names[] = dst.info.authority.split(";");
9864                    for (int j = 0; j < names.length; j++) {
9865                        mProviderMap.putProviderByName(names[j], dst);
9866                    }
9867
9868                    int NL = mLaunchingProviders.size();
9869                    int j;
9870                    for (j=0; j<NL; j++) {
9871                        if (mLaunchingProviders.get(j) == dst) {
9872                            mLaunchingProviders.remove(j);
9873                            j--;
9874                            NL--;
9875                        }
9876                    }
9877                    synchronized (dst) {
9878                        dst.provider = src.provider;
9879                        dst.proc = r;
9880                        dst.notifyAll();
9881                    }
9882                    updateOomAdjLocked(r);
9883                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
9884                            src.info.authority);
9885                }
9886            }
9887
9888            Binder.restoreCallingIdentity(origId);
9889        }
9890    }
9891
9892    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9893        ContentProviderConnection conn;
9894        try {
9895            conn = (ContentProviderConnection)connection;
9896        } catch (ClassCastException e) {
9897            String msg ="refContentProvider: " + connection
9898                    + " not a ContentProviderConnection";
9899            Slog.w(TAG, msg);
9900            throw new IllegalArgumentException(msg);
9901        }
9902        if (conn == null) {
9903            throw new NullPointerException("connection is null");
9904        }
9905
9906        synchronized (this) {
9907            if (stable > 0) {
9908                conn.numStableIncs += stable;
9909            }
9910            stable = conn.stableCount + stable;
9911            if (stable < 0) {
9912                throw new IllegalStateException("stableCount < 0: " + stable);
9913            }
9914
9915            if (unstable > 0) {
9916                conn.numUnstableIncs += unstable;
9917            }
9918            unstable = conn.unstableCount + unstable;
9919            if (unstable < 0) {
9920                throw new IllegalStateException("unstableCount < 0: " + unstable);
9921            }
9922
9923            if ((stable+unstable) <= 0) {
9924                throw new IllegalStateException("ref counts can't go to zero here: stable="
9925                        + stable + " unstable=" + unstable);
9926            }
9927            conn.stableCount = stable;
9928            conn.unstableCount = unstable;
9929            return !conn.dead;
9930        }
9931    }
9932
9933    public void unstableProviderDied(IBinder connection) {
9934        ContentProviderConnection conn;
9935        try {
9936            conn = (ContentProviderConnection)connection;
9937        } catch (ClassCastException e) {
9938            String msg ="refContentProvider: " + connection
9939                    + " not a ContentProviderConnection";
9940            Slog.w(TAG, msg);
9941            throw new IllegalArgumentException(msg);
9942        }
9943        if (conn == null) {
9944            throw new NullPointerException("connection is null");
9945        }
9946
9947        // Safely retrieve the content provider associated with the connection.
9948        IContentProvider provider;
9949        synchronized (this) {
9950            provider = conn.provider.provider;
9951        }
9952
9953        if (provider == null) {
9954            // Um, yeah, we're way ahead of you.
9955            return;
9956        }
9957
9958        // Make sure the caller is being honest with us.
9959        if (provider.asBinder().pingBinder()) {
9960            // Er, no, still looks good to us.
9961            synchronized (this) {
9962                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9963                        + " says " + conn + " died, but we don't agree");
9964                return;
9965            }
9966        }
9967
9968        // Well look at that!  It's dead!
9969        synchronized (this) {
9970            if (conn.provider.provider != provider) {
9971                // But something changed...  good enough.
9972                return;
9973            }
9974
9975            ProcessRecord proc = conn.provider.proc;
9976            if (proc == null || proc.thread == null) {
9977                // Seems like the process is already cleaned up.
9978                return;
9979            }
9980
9981            // As far as we're concerned, this is just like receiving a
9982            // death notification...  just a bit prematurely.
9983            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9984                    + ") early provider death");
9985            final long ident = Binder.clearCallingIdentity();
9986            try {
9987                appDiedLocked(proc);
9988            } finally {
9989                Binder.restoreCallingIdentity(ident);
9990            }
9991        }
9992    }
9993
9994    @Override
9995    public void appNotRespondingViaProvider(IBinder connection) {
9996        enforceCallingPermission(
9997                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9998
9999        final ContentProviderConnection conn = (ContentProviderConnection) connection;
10000        if (conn == null) {
10001            Slog.w(TAG, "ContentProviderConnection is null");
10002            return;
10003        }
10004
10005        final ProcessRecord host = conn.provider.proc;
10006        if (host == null) {
10007            Slog.w(TAG, "Failed to find hosting ProcessRecord");
10008            return;
10009        }
10010
10011        final long token = Binder.clearCallingIdentity();
10012        try {
10013            appNotResponding(host, null, null, false, "ContentProvider not responding");
10014        } finally {
10015            Binder.restoreCallingIdentity(token);
10016        }
10017    }
10018
10019    public final void installSystemProviders() {
10020        List<ProviderInfo> providers;
10021        synchronized (this) {
10022            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10023            providers = generateApplicationProvidersLocked(app);
10024            if (providers != null) {
10025                for (int i=providers.size()-1; i>=0; i--) {
10026                    ProviderInfo pi = (ProviderInfo)providers.get(i);
10027                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10028                        Slog.w(TAG, "Not installing system proc provider " + pi.name
10029                                + ": not system .apk");
10030                        providers.remove(i);
10031                    }
10032                }
10033            }
10034        }
10035        if (providers != null) {
10036            mSystemThread.installSystemProviders(providers);
10037        }
10038
10039        mCoreSettingsObserver = new CoreSettingsObserver(this);
10040
10041        //mUsageStatsService.monitorPackages();
10042    }
10043
10044    /**
10045     * Allows apps to retrieve the MIME type of a URI.
10046     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
10047     * users, then it does not need permission to access the ContentProvider.
10048     * Either, it needs cross-user uri grants.
10049     *
10050     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
10051     *
10052     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
10053     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
10054     */
10055    public String getProviderMimeType(Uri uri, int userId) {
10056        enforceNotIsolatedCaller("getProviderMimeType");
10057        final String name = uri.getAuthority();
10058        int callingUid = Binder.getCallingUid();
10059        int callingPid = Binder.getCallingPid();
10060        long ident = 0;
10061        boolean clearedIdentity = false;
10062        userId = unsafeConvertIncomingUser(userId);
10063        if (canClearIdentity(callingPid, callingUid, userId)) {
10064            clearedIdentity = true;
10065            ident = Binder.clearCallingIdentity();
10066        }
10067        ContentProviderHolder holder = null;
10068        try {
10069            holder = getContentProviderExternalUnchecked(name, null, userId);
10070            if (holder != null) {
10071                return holder.provider.getType(uri);
10072            }
10073        } catch (RemoteException e) {
10074            Log.w(TAG, "Content provider dead retrieving " + uri, e);
10075            return null;
10076        } finally {
10077            // We need to clear the identity to call removeContentProviderExternalUnchecked
10078            if (!clearedIdentity) {
10079                ident = Binder.clearCallingIdentity();
10080            }
10081            try {
10082                if (holder != null) {
10083                    removeContentProviderExternalUnchecked(name, null, userId);
10084                }
10085            } finally {
10086                Binder.restoreCallingIdentity(ident);
10087            }
10088        }
10089
10090        return null;
10091    }
10092
10093    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
10094        if (UserHandle.getUserId(callingUid) == userId) {
10095            return true;
10096        }
10097        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
10098                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
10099                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
10100                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
10101                return true;
10102        }
10103        return false;
10104    }
10105
10106    // =========================================================
10107    // GLOBAL MANAGEMENT
10108    // =========================================================
10109
10110    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
10111            boolean isolated, int isolatedUid) {
10112        String proc = customProcess != null ? customProcess : info.processName;
10113        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10114        final int userId = UserHandle.getUserId(info.uid);
10115        int uid = info.uid;
10116        if (isolated) {
10117            if (isolatedUid == 0) {
10118                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
10119                while (true) {
10120                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
10121                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
10122                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
10123                    }
10124                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
10125                    mNextIsolatedProcessUid++;
10126                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
10127                        // No process for this uid, use it.
10128                        break;
10129                    }
10130                    stepsLeft--;
10131                    if (stepsLeft <= 0) {
10132                        return null;
10133                    }
10134                }
10135            } else {
10136                // Special case for startIsolatedProcess (internal only), where
10137                // the uid of the isolated process is specified by the caller.
10138                uid = isolatedUid;
10139            }
10140        }
10141        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
10142        if (!mBooted && !mBooting
10143                && userId == UserHandle.USER_OWNER
10144                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10145            r.persistent = true;
10146        }
10147        addProcessNameLocked(r);
10148        return r;
10149    }
10150
10151    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
10152            String abiOverride) {
10153        ProcessRecord app;
10154        if (!isolated) {
10155            app = getProcessRecordLocked(info.processName, info.uid, true);
10156        } else {
10157            app = null;
10158        }
10159
10160        if (app == null) {
10161            app = newProcessRecordLocked(info, null, isolated, 0);
10162            updateLruProcessLocked(app, false, null);
10163            updateOomAdjLocked();
10164        }
10165
10166        // This package really, really can not be stopped.
10167        try {
10168            AppGlobals.getPackageManager().setPackageStoppedState(
10169                    info.packageName, false, UserHandle.getUserId(app.uid));
10170        } catch (RemoteException e) {
10171        } catch (IllegalArgumentException e) {
10172            Slog.w(TAG, "Failed trying to unstop package "
10173                    + info.packageName + ": " + e);
10174        }
10175
10176        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10177            app.persistent = true;
10178            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10179        }
10180        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10181            mPersistentStartingProcesses.add(app);
10182            startProcessLocked(app, "added application", app.processName, abiOverride,
10183                    null /* entryPoint */, null /* entryPointArgs */);
10184        }
10185
10186        return app;
10187    }
10188
10189    public void unhandledBack() {
10190        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10191                "unhandledBack()");
10192
10193        synchronized(this) {
10194            final long origId = Binder.clearCallingIdentity();
10195            try {
10196                getFocusedStack().unhandledBackLocked();
10197            } finally {
10198                Binder.restoreCallingIdentity(origId);
10199            }
10200        }
10201    }
10202
10203    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10204        enforceNotIsolatedCaller("openContentUri");
10205        final int userId = UserHandle.getCallingUserId();
10206        String name = uri.getAuthority();
10207        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10208        ParcelFileDescriptor pfd = null;
10209        if (cph != null) {
10210            // We record the binder invoker's uid in thread-local storage before
10211            // going to the content provider to open the file.  Later, in the code
10212            // that handles all permissions checks, we look for this uid and use
10213            // that rather than the Activity Manager's own uid.  The effect is that
10214            // we do the check against the caller's permissions even though it looks
10215            // to the content provider like the Activity Manager itself is making
10216            // the request.
10217            Binder token = new Binder();
10218            sCallerIdentity.set(new Identity(
10219                    token, Binder.getCallingPid(), Binder.getCallingUid()));
10220            try {
10221                pfd = cph.provider.openFile(null, uri, "r", null, token);
10222            } catch (FileNotFoundException e) {
10223                // do nothing; pfd will be returned null
10224            } finally {
10225                // Ensure that whatever happens, we clean up the identity state
10226                sCallerIdentity.remove();
10227                // Ensure we're done with the provider.
10228                removeContentProviderExternalUnchecked(name, null, userId);
10229            }
10230        } else {
10231            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10232        }
10233        return pfd;
10234    }
10235
10236    // Actually is sleeping or shutting down or whatever else in the future
10237    // is an inactive state.
10238    public boolean isSleepingOrShuttingDown() {
10239        return isSleeping() || mShuttingDown;
10240    }
10241
10242    public boolean isSleeping() {
10243        return mSleeping;
10244    }
10245
10246    void onWakefulnessChanged(int wakefulness) {
10247        synchronized(this) {
10248            mWakefulness = wakefulness;
10249            updateSleepIfNeededLocked();
10250        }
10251    }
10252
10253    void finishRunningVoiceLocked() {
10254        if (mRunningVoice != null) {
10255            mRunningVoice = null;
10256            mVoiceWakeLock.release();
10257            updateSleepIfNeededLocked();
10258        }
10259    }
10260
10261    void startTimeTrackingFocusedActivityLocked() {
10262        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
10263            mCurAppTimeTracker.start(mFocusedActivity.packageName);
10264        }
10265    }
10266
10267    void updateSleepIfNeededLocked() {
10268        if (mSleeping && !shouldSleepLocked()) {
10269            mSleeping = false;
10270            startTimeTrackingFocusedActivityLocked();
10271            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
10272            mStackSupervisor.comeOutOfSleepIfNeededLocked();
10273            updateOomAdjLocked();
10274        } else if (!mSleeping && shouldSleepLocked()) {
10275            mSleeping = true;
10276            if (mCurAppTimeTracker != null) {
10277                mCurAppTimeTracker.stop();
10278            }
10279            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
10280            mStackSupervisor.goingToSleepLocked();
10281            updateOomAdjLocked();
10282
10283            // Initialize the wake times of all processes.
10284            checkExcessivePowerUsageLocked(false);
10285            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10286            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10287            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10288        }
10289    }
10290
10291    private boolean shouldSleepLocked() {
10292        // Resume applications while running a voice interactor.
10293        if (mRunningVoice != null) {
10294            return false;
10295        }
10296
10297        // TODO: Transform the lock screen state into a sleep token instead.
10298        switch (mWakefulness) {
10299            case PowerManagerInternal.WAKEFULNESS_AWAKE:
10300            case PowerManagerInternal.WAKEFULNESS_DREAMING:
10301            case PowerManagerInternal.WAKEFULNESS_DOZING:
10302                // Pause applications whenever the lock screen is shown or any sleep
10303                // tokens have been acquired.
10304                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
10305            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10306            default:
10307                // If we're asleep then pause applications unconditionally.
10308                return true;
10309        }
10310    }
10311
10312    /** Pokes the task persister. */
10313    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10314        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10315            // Never persist the home stack.
10316            return;
10317        }
10318        mTaskPersister.wakeup(task, flush);
10319    }
10320
10321    /** Notifies all listeners when the task stack has changed. */
10322    void notifyTaskStackChangedLocked() {
10323        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10324        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10325        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10326    }
10327
10328    @Override
10329    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
10330        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
10331    }
10332
10333    @Override
10334    public boolean shutdown(int timeout) {
10335        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10336                != PackageManager.PERMISSION_GRANTED) {
10337            throw new SecurityException("Requires permission "
10338                    + android.Manifest.permission.SHUTDOWN);
10339        }
10340
10341        boolean timedout = false;
10342
10343        synchronized(this) {
10344            mShuttingDown = true;
10345            updateEventDispatchingLocked();
10346            timedout = mStackSupervisor.shutdownLocked(timeout);
10347        }
10348
10349        mAppOpsService.shutdown();
10350        if (mUsageStatsService != null) {
10351            mUsageStatsService.prepareShutdown();
10352        }
10353        mBatteryStatsService.shutdown();
10354        synchronized (this) {
10355            mProcessStats.shutdownLocked();
10356            notifyTaskPersisterLocked(null, true);
10357        }
10358
10359        return timedout;
10360    }
10361
10362    public final void activitySlept(IBinder token) {
10363        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
10364
10365        final long origId = Binder.clearCallingIdentity();
10366
10367        synchronized (this) {
10368            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10369            if (r != null) {
10370                mStackSupervisor.activitySleptLocked(r);
10371            }
10372        }
10373
10374        Binder.restoreCallingIdentity(origId);
10375    }
10376
10377    private String lockScreenShownToString() {
10378        switch (mLockScreenShown) {
10379            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10380            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10381            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10382            default: return "Unknown=" + mLockScreenShown;
10383        }
10384    }
10385
10386    void logLockScreen(String msg) {
10387        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
10388                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10389                + PowerManagerInternal.wakefulnessToString(mWakefulness)
10390                + " mSleeping=" + mSleeping);
10391    }
10392
10393    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
10394        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
10395        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
10396            boolean wasRunningVoice = mRunningVoice != null;
10397            mRunningVoice = session;
10398            if (!wasRunningVoice) {
10399                mVoiceWakeLock.acquire();
10400                updateSleepIfNeededLocked();
10401            }
10402        }
10403    }
10404
10405    private void updateEventDispatchingLocked() {
10406        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10407    }
10408
10409    public void setLockScreenShown(boolean shown) {
10410        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10411                != PackageManager.PERMISSION_GRANTED) {
10412            throw new SecurityException("Requires permission "
10413                    + android.Manifest.permission.DEVICE_POWER);
10414        }
10415
10416        synchronized(this) {
10417            long ident = Binder.clearCallingIdentity();
10418            try {
10419                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10420                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10421                updateSleepIfNeededLocked();
10422            } finally {
10423                Binder.restoreCallingIdentity(ident);
10424            }
10425        }
10426    }
10427
10428    @Override
10429    public void stopAppSwitches() {
10430        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10431                != PackageManager.PERMISSION_GRANTED) {
10432            throw new SecurityException("Requires permission "
10433                    + android.Manifest.permission.STOP_APP_SWITCHES);
10434        }
10435
10436        synchronized(this) {
10437            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10438                    + APP_SWITCH_DELAY_TIME;
10439            mDidAppSwitch = false;
10440            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10441            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10442            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10443        }
10444    }
10445
10446    public void resumeAppSwitches() {
10447        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10448                != PackageManager.PERMISSION_GRANTED) {
10449            throw new SecurityException("Requires permission "
10450                    + android.Manifest.permission.STOP_APP_SWITCHES);
10451        }
10452
10453        synchronized(this) {
10454            // Note that we don't execute any pending app switches... we will
10455            // let those wait until either the timeout, or the next start
10456            // activity request.
10457            mAppSwitchesAllowedTime = 0;
10458        }
10459    }
10460
10461    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10462            int callingPid, int callingUid, String name) {
10463        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10464            return true;
10465        }
10466
10467        int perm = checkComponentPermission(
10468                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10469                sourceUid, -1, true);
10470        if (perm == PackageManager.PERMISSION_GRANTED) {
10471            return true;
10472        }
10473
10474        // If the actual IPC caller is different from the logical source, then
10475        // also see if they are allowed to control app switches.
10476        if (callingUid != -1 && callingUid != sourceUid) {
10477            perm = checkComponentPermission(
10478                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10479                    callingUid, -1, true);
10480            if (perm == PackageManager.PERMISSION_GRANTED) {
10481                return true;
10482            }
10483        }
10484
10485        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10486        return false;
10487    }
10488
10489    public void setDebugApp(String packageName, boolean waitForDebugger,
10490            boolean persistent) {
10491        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10492                "setDebugApp()");
10493
10494        long ident = Binder.clearCallingIdentity();
10495        try {
10496            // Note that this is not really thread safe if there are multiple
10497            // callers into it at the same time, but that's not a situation we
10498            // care about.
10499            if (persistent) {
10500                final ContentResolver resolver = mContext.getContentResolver();
10501                Settings.Global.putString(
10502                    resolver, Settings.Global.DEBUG_APP,
10503                    packageName);
10504                Settings.Global.putInt(
10505                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10506                    waitForDebugger ? 1 : 0);
10507            }
10508
10509            synchronized (this) {
10510                if (!persistent) {
10511                    mOrigDebugApp = mDebugApp;
10512                    mOrigWaitForDebugger = mWaitForDebugger;
10513                }
10514                mDebugApp = packageName;
10515                mWaitForDebugger = waitForDebugger;
10516                mDebugTransient = !persistent;
10517                if (packageName != null) {
10518                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10519                            false, UserHandle.USER_ALL, "set debug app");
10520                }
10521            }
10522        } finally {
10523            Binder.restoreCallingIdentity(ident);
10524        }
10525    }
10526
10527    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10528        synchronized (this) {
10529            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10530            if (!isDebuggable) {
10531                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10532                    throw new SecurityException("Process not debuggable: " + app.packageName);
10533                }
10534            }
10535
10536            mOpenGlTraceApp = processName;
10537        }
10538    }
10539
10540    void setTrackAllocationApp(ApplicationInfo app, String processName) {
10541        synchronized (this) {
10542            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10543            if (!isDebuggable) {
10544                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10545                    throw new SecurityException("Process not debuggable: " + app.packageName);
10546                }
10547            }
10548
10549            mTrackAllocationApp = processName;
10550        }
10551    }
10552
10553    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10554        synchronized (this) {
10555            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10556            if (!isDebuggable) {
10557                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10558                    throw new SecurityException("Process not debuggable: " + app.packageName);
10559                }
10560            }
10561            mProfileApp = processName;
10562            mProfileFile = profilerInfo.profileFile;
10563            if (mProfileFd != null) {
10564                try {
10565                    mProfileFd.close();
10566                } catch (IOException e) {
10567                }
10568                mProfileFd = null;
10569            }
10570            mProfileFd = profilerInfo.profileFd;
10571            mSamplingInterval = profilerInfo.samplingInterval;
10572            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10573            mProfileType = 0;
10574        }
10575    }
10576
10577    @Override
10578    public void setAlwaysFinish(boolean enabled) {
10579        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10580                "setAlwaysFinish()");
10581
10582        Settings.Global.putInt(
10583                mContext.getContentResolver(),
10584                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10585
10586        synchronized (this) {
10587            mAlwaysFinishActivities = enabled;
10588        }
10589    }
10590
10591    @Override
10592    public void setActivityController(IActivityController controller) {
10593        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10594                "setActivityController()");
10595        synchronized (this) {
10596            mController = controller;
10597            Watchdog.getInstance().setActivityController(controller);
10598        }
10599    }
10600
10601    @Override
10602    public void setUserIsMonkey(boolean userIsMonkey) {
10603        synchronized (this) {
10604            synchronized (mPidsSelfLocked) {
10605                final int callingPid = Binder.getCallingPid();
10606                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10607                if (precessRecord == null) {
10608                    throw new SecurityException("Unknown process: " + callingPid);
10609                }
10610                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10611                    throw new SecurityException("Only an instrumentation process "
10612                            + "with a UiAutomation can call setUserIsMonkey");
10613                }
10614            }
10615            mUserIsMonkey = userIsMonkey;
10616        }
10617    }
10618
10619    @Override
10620    public boolean isUserAMonkey() {
10621        synchronized (this) {
10622            // If there is a controller also implies the user is a monkey.
10623            return (mUserIsMonkey || mController != null);
10624        }
10625    }
10626
10627    public void requestBugReport() {
10628        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10629        SystemProperties.set("ctl.start", "bugreport");
10630    }
10631
10632    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10633        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10634    }
10635
10636    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10637        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10638            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10639        }
10640        return KEY_DISPATCHING_TIMEOUT;
10641    }
10642
10643    @Override
10644    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10645        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10646                != PackageManager.PERMISSION_GRANTED) {
10647            throw new SecurityException("Requires permission "
10648                    + android.Manifest.permission.FILTER_EVENTS);
10649        }
10650        ProcessRecord proc;
10651        long timeout;
10652        synchronized (this) {
10653            synchronized (mPidsSelfLocked) {
10654                proc = mPidsSelfLocked.get(pid);
10655            }
10656            timeout = getInputDispatchingTimeoutLocked(proc);
10657        }
10658
10659        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10660            return -1;
10661        }
10662
10663        return timeout;
10664    }
10665
10666    /**
10667     * Handle input dispatching timeouts.
10668     * Returns whether input dispatching should be aborted or not.
10669     */
10670    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10671            final ActivityRecord activity, final ActivityRecord parent,
10672            final boolean aboveSystem, String reason) {
10673        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10674                != PackageManager.PERMISSION_GRANTED) {
10675            throw new SecurityException("Requires permission "
10676                    + android.Manifest.permission.FILTER_EVENTS);
10677        }
10678
10679        final String annotation;
10680        if (reason == null) {
10681            annotation = "Input dispatching timed out";
10682        } else {
10683            annotation = "Input dispatching timed out (" + reason + ")";
10684        }
10685
10686        if (proc != null) {
10687            synchronized (this) {
10688                if (proc.debugging) {
10689                    return false;
10690                }
10691
10692                if (mDidDexOpt) {
10693                    // Give more time since we were dexopting.
10694                    mDidDexOpt = false;
10695                    return false;
10696                }
10697
10698                if (proc.instrumentationClass != null) {
10699                    Bundle info = new Bundle();
10700                    info.putString("shortMsg", "keyDispatchingTimedOut");
10701                    info.putString("longMsg", annotation);
10702                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10703                    return true;
10704                }
10705            }
10706            mHandler.post(new Runnable() {
10707                @Override
10708                public void run() {
10709                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10710                }
10711            });
10712        }
10713
10714        return true;
10715    }
10716
10717    @Override
10718    public Bundle getAssistContextExtras(int requestType) {
10719        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
10720                null, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
10721        if (pae == null) {
10722            return null;
10723        }
10724        synchronized (pae) {
10725            while (!pae.haveResult) {
10726                try {
10727                    pae.wait();
10728                } catch (InterruptedException e) {
10729                }
10730            }
10731        }
10732        synchronized (this) {
10733            buildAssistBundleLocked(pae, pae.result);
10734            mPendingAssistExtras.remove(pae);
10735            mHandler.removeCallbacks(pae);
10736        }
10737        return pae.extras;
10738    }
10739
10740    @Override
10741    public boolean isAssistDataAllowedOnCurrentActivity() {
10742        int userId = mCurrentUserId;
10743        synchronized (this) {
10744            ActivityRecord activity = getFocusedStack().topActivity();
10745            if (activity == null) {
10746                return false;
10747            }
10748            userId = activity.userId;
10749        }
10750        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
10751                Context.DEVICE_POLICY_SERVICE);
10752        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
10753    }
10754
10755    @Override
10756    public boolean showAssistFromActivity(IBinder token, Bundle args) {
10757        long ident = Binder.clearCallingIdentity();
10758        try {
10759            synchronized (this) {
10760                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
10761                ActivityRecord top = getFocusedStack().topActivity();
10762                if (top != caller) {
10763                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
10764                            + " is not current top " + top);
10765                    return false;
10766                }
10767                if (!top.nowVisible) {
10768                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
10769                            + " is not visible");
10770                    return false;
10771                }
10772            }
10773            AssistUtils utils = new AssistUtils(mContext);
10774            return utils.showSessionForActiveService(args,
10775                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
10776        } finally {
10777            Binder.restoreCallingIdentity(ident);
10778        }
10779    }
10780
10781    @Override
10782    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
10783            IBinder activityToken) {
10784        return enqueueAssistContext(requestType, null, null, receiver, activityToken,
10785                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
10786    }
10787
10788    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10789            IResultReceiver receiver, IBinder activityToken, int userHandle, Bundle args,
10790            long timeout) {
10791        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10792                "enqueueAssistContext()");
10793        synchronized (this) {
10794            ActivityRecord activity = getFocusedStack().topActivity();
10795            if (activity == null) {
10796                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
10797                return null;
10798            }
10799            if (activity.app == null || activity.app.thread == null) {
10800                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10801                return null;
10802            }
10803            if (activityToken != null) {
10804                ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
10805                if (activity != caller) {
10806                    Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
10807                            + " is not current top " + activity);
10808                    return null;
10809                }
10810            }
10811            PendingAssistExtras pae;
10812            Bundle extras = new Bundle();
10813            if (args != null) {
10814                extras.putAll(args);
10815            }
10816            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10817            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
10818            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
10819            try {
10820                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10821                        requestType);
10822                mPendingAssistExtras.add(pae);
10823                mHandler.postDelayed(pae, timeout);
10824            } catch (RemoteException e) {
10825                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10826                return null;
10827            }
10828            return pae;
10829        }
10830    }
10831
10832    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
10833        IResultReceiver receiver;
10834        synchronized (this) {
10835            mPendingAssistExtras.remove(pae);
10836            receiver = pae.receiver;
10837        }
10838        if (receiver != null) {
10839            // Caller wants result sent back to them.
10840            try {
10841                pae.receiver.send(0, null);
10842            } catch (RemoteException e) {
10843            }
10844        }
10845    }
10846
10847    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
10848        if (result != null) {
10849            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
10850        }
10851        if (pae.hint != null) {
10852            pae.extras.putBoolean(pae.hint, true);
10853        }
10854    }
10855
10856    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
10857            AssistContent content, Uri referrer) {
10858        PendingAssistExtras pae = (PendingAssistExtras)token;
10859        synchronized (pae) {
10860            pae.result = extras;
10861            pae.structure = structure;
10862            pae.content = content;
10863            if (referrer != null) {
10864                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
10865            }
10866            pae.haveResult = true;
10867            pae.notifyAll();
10868            if (pae.intent == null && pae.receiver == null) {
10869                // Caller is just waiting for the result.
10870                return;
10871            }
10872        }
10873
10874        // We are now ready to launch the assist activity.
10875        IResultReceiver sendReceiver = null;
10876        Bundle sendBundle = null;
10877        synchronized (this) {
10878            buildAssistBundleLocked(pae, extras);
10879            boolean exists = mPendingAssistExtras.remove(pae);
10880            mHandler.removeCallbacks(pae);
10881            if (!exists) {
10882                // Timed out.
10883                return;
10884            }
10885            if ((sendReceiver=pae.receiver) != null) {
10886                // Caller wants result sent back to them.
10887                sendBundle = new Bundle();
10888                sendBundle.putBundle("data", pae.extras);
10889                sendBundle.putParcelable("structure", pae.structure);
10890                sendBundle.putParcelable("content", pae.content);
10891            }
10892        }
10893        if (sendReceiver != null) {
10894            try {
10895                sendReceiver.send(0, sendBundle);
10896            } catch (RemoteException e) {
10897            }
10898            return;
10899        }
10900
10901        long ident = Binder.clearCallingIdentity();
10902        try {
10903            pae.intent.replaceExtras(pae.extras);
10904            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10905                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
10906                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10907            closeSystemDialogs("assist");
10908            try {
10909                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10910            } catch (ActivityNotFoundException e) {
10911                Slog.w(TAG, "No activity to handle assist action.", e);
10912            }
10913        } finally {
10914            Binder.restoreCallingIdentity(ident);
10915        }
10916    }
10917
10918    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
10919            Bundle args) {
10920        return enqueueAssistContext(requestType, intent, hint, null, null, userHandle, args,
10921                PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
10922    }
10923
10924    public void registerProcessObserver(IProcessObserver observer) {
10925        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10926                "registerProcessObserver()");
10927        synchronized (this) {
10928            mProcessObservers.register(observer);
10929        }
10930    }
10931
10932    @Override
10933    public void unregisterProcessObserver(IProcessObserver observer) {
10934        synchronized (this) {
10935            mProcessObservers.unregister(observer);
10936        }
10937    }
10938
10939    public void registerUidObserver(IUidObserver observer) {
10940        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10941                "registerUidObserver()");
10942        synchronized (this) {
10943            mUidObservers.register(observer);
10944        }
10945    }
10946
10947    @Override
10948    public void unregisterUidObserver(IUidObserver observer) {
10949        synchronized (this) {
10950            mUidObservers.unregister(observer);
10951        }
10952    }
10953
10954    @Override
10955    public boolean convertFromTranslucent(IBinder token) {
10956        final long origId = Binder.clearCallingIdentity();
10957        try {
10958            synchronized (this) {
10959                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10960                if (r == null) {
10961                    return false;
10962                }
10963                final boolean translucentChanged = r.changeWindowTranslucency(true);
10964                if (translucentChanged) {
10965                    r.task.stack.releaseBackgroundResources(r);
10966                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10967                }
10968                mWindowManager.setAppFullscreen(token, true);
10969                return translucentChanged;
10970            }
10971        } finally {
10972            Binder.restoreCallingIdentity(origId);
10973        }
10974    }
10975
10976    @Override
10977    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10978        final long origId = Binder.clearCallingIdentity();
10979        try {
10980            synchronized (this) {
10981                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10982                if (r == null) {
10983                    return false;
10984                }
10985                int index = r.task.mActivities.lastIndexOf(r);
10986                if (index > 0) {
10987                    ActivityRecord under = r.task.mActivities.get(index - 1);
10988                    under.returningOptions = options;
10989                }
10990                final boolean translucentChanged = r.changeWindowTranslucency(false);
10991                if (translucentChanged) {
10992                    r.task.stack.convertActivityToTranslucent(r);
10993                }
10994                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10995                mWindowManager.setAppFullscreen(token, false);
10996                return translucentChanged;
10997            }
10998        } finally {
10999            Binder.restoreCallingIdentity(origId);
11000        }
11001    }
11002
11003    @Override
11004    public boolean requestVisibleBehind(IBinder token, boolean visible) {
11005        final long origId = Binder.clearCallingIdentity();
11006        try {
11007            synchronized (this) {
11008                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11009                if (r != null) {
11010                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
11011                }
11012            }
11013            return false;
11014        } finally {
11015            Binder.restoreCallingIdentity(origId);
11016        }
11017    }
11018
11019    @Override
11020    public boolean isBackgroundVisibleBehind(IBinder token) {
11021        final long origId = Binder.clearCallingIdentity();
11022        try {
11023            synchronized (this) {
11024                final ActivityStack stack = ActivityRecord.getStackLocked(token);
11025                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
11026                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
11027                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
11028                return visible;
11029            }
11030        } finally {
11031            Binder.restoreCallingIdentity(origId);
11032        }
11033    }
11034
11035    @Override
11036    public ActivityOptions getActivityOptions(IBinder token) {
11037        final long origId = Binder.clearCallingIdentity();
11038        try {
11039            synchronized (this) {
11040                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11041                if (r != null) {
11042                    final ActivityOptions activityOptions = r.pendingOptions;
11043                    r.pendingOptions = null;
11044                    return activityOptions;
11045                }
11046                return null;
11047            }
11048        } finally {
11049            Binder.restoreCallingIdentity(origId);
11050        }
11051    }
11052
11053    @Override
11054    public void setImmersive(IBinder token, boolean immersive) {
11055        synchronized(this) {
11056            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11057            if (r == null) {
11058                throw new IllegalArgumentException();
11059            }
11060            r.immersive = immersive;
11061
11062            // update associated state if we're frontmost
11063            if (r == mFocusedActivity) {
11064                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
11065                applyUpdateLockStateLocked(r);
11066            }
11067        }
11068    }
11069
11070    @Override
11071    public boolean isImmersive(IBinder token) {
11072        synchronized (this) {
11073            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11074            if (r == null) {
11075                throw new IllegalArgumentException();
11076            }
11077            return r.immersive;
11078        }
11079    }
11080
11081    public boolean isTopActivityImmersive() {
11082        enforceNotIsolatedCaller("startActivity");
11083        synchronized (this) {
11084            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
11085            return (r != null) ? r.immersive : false;
11086        }
11087    }
11088
11089    @Override
11090    public boolean isTopOfTask(IBinder token) {
11091        synchronized (this) {
11092            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11093            if (r == null) {
11094                throw new IllegalArgumentException();
11095            }
11096            return r.task.getTopActivity() == r;
11097        }
11098    }
11099
11100    public final void enterSafeMode() {
11101        synchronized(this) {
11102            // It only makes sense to do this before the system is ready
11103            // and started launching other packages.
11104            if (!mSystemReady) {
11105                try {
11106                    AppGlobals.getPackageManager().enterSafeMode();
11107                } catch (RemoteException e) {
11108                }
11109            }
11110
11111            mSafeMode = true;
11112        }
11113    }
11114
11115    public final void showSafeModeOverlay() {
11116        View v = LayoutInflater.from(mContext).inflate(
11117                com.android.internal.R.layout.safe_mode, null);
11118        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
11119        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
11120        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
11121        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
11122        lp.gravity = Gravity.BOTTOM | Gravity.START;
11123        lp.format = v.getBackground().getOpacity();
11124        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
11125                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
11126        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
11127        ((WindowManager)mContext.getSystemService(
11128                Context.WINDOW_SERVICE)).addView(v, lp);
11129    }
11130
11131    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
11132        if (!(sender instanceof PendingIntentRecord)) {
11133            return;
11134        }
11135        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11136        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11137        synchronized (stats) {
11138            if (mBatteryStatsService.isOnBattery()) {
11139                mBatteryStatsService.enforceCallingPermission();
11140                int MY_UID = Binder.getCallingUid();
11141                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11142                BatteryStatsImpl.Uid.Pkg pkg =
11143                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
11144                            sourcePkg != null ? sourcePkg : rec.key.packageName);
11145                pkg.noteWakeupAlarmLocked(tag);
11146            }
11147        }
11148    }
11149
11150    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
11151        if (!(sender instanceof PendingIntentRecord)) {
11152            return;
11153        }
11154        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11155        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11156        synchronized (stats) {
11157            mBatteryStatsService.enforceCallingPermission();
11158            int MY_UID = Binder.getCallingUid();
11159            int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11160            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
11161        }
11162    }
11163
11164    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
11165        if (!(sender instanceof PendingIntentRecord)) {
11166            return;
11167        }
11168        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11169        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11170        synchronized (stats) {
11171            mBatteryStatsService.enforceCallingPermission();
11172            int MY_UID = Binder.getCallingUid();
11173            int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11174            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
11175        }
11176    }
11177
11178    public boolean killPids(int[] pids, String pReason, boolean secure) {
11179        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11180            throw new SecurityException("killPids only available to the system");
11181        }
11182        String reason = (pReason == null) ? "Unknown" : pReason;
11183        // XXX Note: don't acquire main activity lock here, because the window
11184        // manager calls in with its locks held.
11185
11186        boolean killed = false;
11187        synchronized (mPidsSelfLocked) {
11188            int[] types = new int[pids.length];
11189            int worstType = 0;
11190            for (int i=0; i<pids.length; i++) {
11191                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11192                if (proc != null) {
11193                    int type = proc.setAdj;
11194                    types[i] = type;
11195                    if (type > worstType) {
11196                        worstType = type;
11197                    }
11198                }
11199            }
11200
11201            // If the worst oom_adj is somewhere in the cached proc LRU range,
11202            // then constrain it so we will kill all cached procs.
11203            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
11204                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
11205                worstType = ProcessList.CACHED_APP_MIN_ADJ;
11206            }
11207
11208            // If this is not a secure call, don't let it kill processes that
11209            // are important.
11210            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
11211                worstType = ProcessList.SERVICE_ADJ;
11212            }
11213
11214            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
11215            for (int i=0; i<pids.length; i++) {
11216                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11217                if (proc == null) {
11218                    continue;
11219                }
11220                int adj = proc.setAdj;
11221                if (adj >= worstType && !proc.killedByAm) {
11222                    proc.kill(reason, true);
11223                    killed = true;
11224                }
11225            }
11226        }
11227        return killed;
11228    }
11229
11230    @Override
11231    public void killUid(int appId, int userId, String reason) {
11232        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
11233        synchronized (this) {
11234            final long identity = Binder.clearCallingIdentity();
11235            try {
11236                killPackageProcessesLocked(null, appId, userId,
11237                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
11238                        reason != null ? reason : "kill uid");
11239            } finally {
11240                Binder.restoreCallingIdentity(identity);
11241            }
11242        }
11243    }
11244
11245    @Override
11246    public boolean killProcessesBelowForeground(String reason) {
11247        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11248            throw new SecurityException("killProcessesBelowForeground() only available to system");
11249        }
11250
11251        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
11252    }
11253
11254    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
11255        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11256            throw new SecurityException("killProcessesBelowAdj() only available to system");
11257        }
11258
11259        boolean killed = false;
11260        synchronized (mPidsSelfLocked) {
11261            final int size = mPidsSelfLocked.size();
11262            for (int i = 0; i < size; i++) {
11263                final int pid = mPidsSelfLocked.keyAt(i);
11264                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11265                if (proc == null) continue;
11266
11267                final int adj = proc.setAdj;
11268                if (adj > belowAdj && !proc.killedByAm) {
11269                    proc.kill(reason, true);
11270                    killed = true;
11271                }
11272            }
11273        }
11274        return killed;
11275    }
11276
11277    @Override
11278    public void hang(final IBinder who, boolean allowRestart) {
11279        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11280                != PackageManager.PERMISSION_GRANTED) {
11281            throw new SecurityException("Requires permission "
11282                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11283        }
11284
11285        final IBinder.DeathRecipient death = new DeathRecipient() {
11286            @Override
11287            public void binderDied() {
11288                synchronized (this) {
11289                    notifyAll();
11290                }
11291            }
11292        };
11293
11294        try {
11295            who.linkToDeath(death, 0);
11296        } catch (RemoteException e) {
11297            Slog.w(TAG, "hang: given caller IBinder is already dead.");
11298            return;
11299        }
11300
11301        synchronized (this) {
11302            Watchdog.getInstance().setAllowRestart(allowRestart);
11303            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
11304            synchronized (death) {
11305                while (who.isBinderAlive()) {
11306                    try {
11307                        death.wait();
11308                    } catch (InterruptedException e) {
11309                    }
11310                }
11311            }
11312            Watchdog.getInstance().setAllowRestart(true);
11313        }
11314    }
11315
11316    @Override
11317    public void restart() {
11318        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11319                != PackageManager.PERMISSION_GRANTED) {
11320            throw new SecurityException("Requires permission "
11321                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11322        }
11323
11324        Log.i(TAG, "Sending shutdown broadcast...");
11325
11326        BroadcastReceiver br = new BroadcastReceiver() {
11327            @Override public void onReceive(Context context, Intent intent) {
11328                // Now the broadcast is done, finish up the low-level shutdown.
11329                Log.i(TAG, "Shutting down activity manager...");
11330                shutdown(10000);
11331                Log.i(TAG, "Shutdown complete, restarting!");
11332                Process.killProcess(Process.myPid());
11333                System.exit(10);
11334            }
11335        };
11336
11337        // First send the high-level shut down broadcast.
11338        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
11339        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
11340        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
11341        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
11342        mContext.sendOrderedBroadcastAsUser(intent,
11343                UserHandle.ALL, null, br, mHandler, 0, null, null);
11344        */
11345        br.onReceive(mContext, intent);
11346    }
11347
11348    private long getLowRamTimeSinceIdle(long now) {
11349        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
11350    }
11351
11352    @Override
11353    public void performIdleMaintenance() {
11354        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11355                != PackageManager.PERMISSION_GRANTED) {
11356            throw new SecurityException("Requires permission "
11357                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11358        }
11359
11360        synchronized (this) {
11361            final long now = SystemClock.uptimeMillis();
11362            final long timeSinceLastIdle = now - mLastIdleTime;
11363            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
11364            mLastIdleTime = now;
11365            mLowRamTimeSinceLastIdle = 0;
11366            if (mLowRamStartTime != 0) {
11367                mLowRamStartTime = now;
11368            }
11369
11370            StringBuilder sb = new StringBuilder(128);
11371            sb.append("Idle maintenance over ");
11372            TimeUtils.formatDuration(timeSinceLastIdle, sb);
11373            sb.append(" low RAM for ");
11374            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11375            Slog.i(TAG, sb.toString());
11376
11377            // If at least 1/3 of our time since the last idle period has been spent
11378            // with RAM low, then we want to kill processes.
11379            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
11380
11381            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11382                ProcessRecord proc = mLruProcesses.get(i);
11383                if (proc.notCachedSinceIdle) {
11384                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
11385                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
11386                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
11387                        if (doKilling && proc.initialIdlePss != 0
11388                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
11389                            sb = new StringBuilder(128);
11390                            sb.append("Kill");
11391                            sb.append(proc.processName);
11392                            sb.append(" in idle maint: pss=");
11393                            sb.append(proc.lastPss);
11394                            sb.append(", initialPss=");
11395                            sb.append(proc.initialIdlePss);
11396                            sb.append(", period=");
11397                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
11398                            sb.append(", lowRamPeriod=");
11399                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11400                            Slog.wtfQuiet(TAG, sb.toString());
11401                            proc.kill("idle maint (pss " + proc.lastPss
11402                                    + " from " + proc.initialIdlePss + ")", true);
11403                        }
11404                    }
11405                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
11406                    proc.notCachedSinceIdle = true;
11407                    proc.initialIdlePss = 0;
11408                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
11409                            mTestPssMode, isSleeping(), now);
11410                }
11411            }
11412
11413            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
11414            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
11415        }
11416    }
11417
11418    private void retrieveSettings() {
11419        final ContentResolver resolver = mContext.getContentResolver();
11420        String debugApp = Settings.Global.getString(
11421            resolver, Settings.Global.DEBUG_APP);
11422        boolean waitForDebugger = Settings.Global.getInt(
11423            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11424        boolean alwaysFinishActivities = Settings.Global.getInt(
11425            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11426        boolean forceRtl = Settings.Global.getInt(
11427                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11428        // Transfer any global setting for forcing RTL layout, into a System Property
11429        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11430
11431        Configuration configuration = new Configuration();
11432        Settings.System.getConfiguration(resolver, configuration);
11433        if (forceRtl) {
11434            // This will take care of setting the correct layout direction flags
11435            configuration.setLayoutDirection(configuration.locale);
11436        }
11437
11438        synchronized (this) {
11439            mDebugApp = mOrigDebugApp = debugApp;
11440            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11441            mAlwaysFinishActivities = alwaysFinishActivities;
11442            // This happens before any activities are started, so we can
11443            // change mConfiguration in-place.
11444            updateConfigurationLocked(configuration, null, false, true);
11445            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
11446                    "Initial config: " + mConfiguration);
11447        }
11448    }
11449
11450    /** Loads resources after the current configuration has been set. */
11451    private void loadResourcesOnSystemReady() {
11452        final Resources res = mContext.getResources();
11453        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11454        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11455        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11456    }
11457
11458    public boolean testIsSystemReady() {
11459        // no need to synchronize(this) just to read & return the value
11460        return mSystemReady;
11461    }
11462
11463    private static File getCalledPreBootReceiversFile() {
11464        File dataDir = Environment.getDataDirectory();
11465        File systemDir = new File(dataDir, "system");
11466        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11467        return fname;
11468    }
11469
11470    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11471        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11472        File file = getCalledPreBootReceiversFile();
11473        FileInputStream fis = null;
11474        try {
11475            fis = new FileInputStream(file);
11476            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11477            int fvers = dis.readInt();
11478            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11479                String vers = dis.readUTF();
11480                String codename = dis.readUTF();
11481                String build = dis.readUTF();
11482                if (android.os.Build.VERSION.RELEASE.equals(vers)
11483                        && android.os.Build.VERSION.CODENAME.equals(codename)
11484                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11485                    int num = dis.readInt();
11486                    while (num > 0) {
11487                        num--;
11488                        String pkg = dis.readUTF();
11489                        String cls = dis.readUTF();
11490                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11491                    }
11492                }
11493            }
11494        } catch (FileNotFoundException e) {
11495        } catch (IOException e) {
11496            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11497        } finally {
11498            if (fis != null) {
11499                try {
11500                    fis.close();
11501                } catch (IOException e) {
11502                }
11503            }
11504        }
11505        return lastDoneReceivers;
11506    }
11507
11508    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11509        File file = getCalledPreBootReceiversFile();
11510        FileOutputStream fos = null;
11511        DataOutputStream dos = null;
11512        try {
11513            fos = new FileOutputStream(file);
11514            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11515            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11516            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11517            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11518            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11519            dos.writeInt(list.size());
11520            for (int i=0; i<list.size(); i++) {
11521                dos.writeUTF(list.get(i).getPackageName());
11522                dos.writeUTF(list.get(i).getClassName());
11523            }
11524        } catch (IOException e) {
11525            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11526            file.delete();
11527        } finally {
11528            FileUtils.sync(fos);
11529            if (dos != null) {
11530                try {
11531                    dos.close();
11532                } catch (IOException e) {
11533                    // TODO Auto-generated catch block
11534                    e.printStackTrace();
11535                }
11536            }
11537        }
11538    }
11539
11540    final class PreBootContinuation extends IIntentReceiver.Stub {
11541        final Intent intent;
11542        final Runnable onFinishCallback;
11543        final ArrayList<ComponentName> doneReceivers;
11544        final List<ResolveInfo> ris;
11545        final int[] users;
11546        int lastRi = -1;
11547        int curRi = 0;
11548        int curUser = 0;
11549
11550        PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
11551                ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
11552            intent = _intent;
11553            onFinishCallback = _onFinishCallback;
11554            doneReceivers = _doneReceivers;
11555            ris = _ris;
11556            users = _users;
11557        }
11558
11559        void go() {
11560            if (lastRi != curRi) {
11561                ActivityInfo ai = ris.get(curRi).activityInfo;
11562                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11563                intent.setComponent(comp);
11564                doneReceivers.add(comp);
11565                lastRi = curRi;
11566                CharSequence label = ai.loadLabel(mContext.getPackageManager());
11567                showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
11568            }
11569            Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
11570                    + " for user " + users[curUser]);
11571            EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
11572            broadcastIntentLocked(null, null, intent, null, this,
11573                    0, null, null, null, AppOpsManager.OP_NONE,
11574                    null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
11575        }
11576
11577        public void performReceive(Intent intent, int resultCode,
11578                String data, Bundle extras, boolean ordered,
11579                boolean sticky, int sendingUser) {
11580            curUser++;
11581            if (curUser >= users.length) {
11582                curUser = 0;
11583                curRi++;
11584                if (curRi >= ris.size()) {
11585                    // All done sending broadcasts!
11586                    if (onFinishCallback != null) {
11587                        // The raw IIntentReceiver interface is called
11588                        // with the AM lock held, so redispatch to
11589                        // execute our code without the lock.
11590                        mHandler.post(onFinishCallback);
11591                    }
11592                    return;
11593                }
11594            }
11595            go();
11596        }
11597    }
11598
11599    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11600            ArrayList<ComponentName> doneReceivers, int userId) {
11601        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11602        List<ResolveInfo> ris = null;
11603        try {
11604            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11605                    intent, null, 0, userId);
11606        } catch (RemoteException e) {
11607        }
11608        if (ris == null) {
11609            return false;
11610        }
11611        for (int i=ris.size()-1; i>=0; i--) {
11612            if ((ris.get(i).activityInfo.applicationInfo.flags
11613                    &ApplicationInfo.FLAG_SYSTEM) == 0) {
11614                ris.remove(i);
11615            }
11616        }
11617        intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11618
11619        // For User 0, load the version number. When delivering to a new user, deliver
11620        // to all receivers.
11621        if (userId == UserHandle.USER_OWNER) {
11622            ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11623            for (int i=0; i<ris.size(); i++) {
11624                ActivityInfo ai = ris.get(i).activityInfo;
11625                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11626                if (lastDoneReceivers.contains(comp)) {
11627                    // We already did the pre boot receiver for this app with the current
11628                    // platform version, so don't do it again...
11629                    ris.remove(i);
11630                    i--;
11631                    // ...however, do keep it as one that has been done, so we don't
11632                    // forget about it when rewriting the file of last done receivers.
11633                    doneReceivers.add(comp);
11634                }
11635            }
11636        }
11637
11638        if (ris.size() <= 0) {
11639            return false;
11640        }
11641
11642        // If primary user, send broadcast to all available users, else just to userId
11643        final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11644                : new int[] { userId };
11645        if (users.length <= 0) {
11646            return false;
11647        }
11648
11649        PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
11650                ris, users);
11651        cont.go();
11652        return true;
11653    }
11654
11655    public void systemReady(final Runnable goingCallback) {
11656        synchronized(this) {
11657            if (mSystemReady) {
11658                // If we're done calling all the receivers, run the next "boot phase" passed in
11659                // by the SystemServer
11660                if (goingCallback != null) {
11661                    goingCallback.run();
11662                }
11663                return;
11664            }
11665
11666            mLocalDeviceIdleController
11667                    = LocalServices.getService(DeviceIdleController.LocalService.class);
11668
11669            // Make sure we have the current profile info, since it is needed for
11670            // security checks.
11671            updateCurrentProfileIdsLocked();
11672
11673            mRecentTasks.clear();
11674            mRecentTasks.addAll(mTaskPersister.restoreTasksLocked());
11675            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
11676            mTaskPersister.startPersisting();
11677
11678            // Check to see if there are any update receivers to run.
11679            if (!mDidUpdate) {
11680                if (mWaitingUpdate) {
11681                    return;
11682                }
11683                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11684                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11685                    public void run() {
11686                        synchronized (ActivityManagerService.this) {
11687                            mDidUpdate = true;
11688                        }
11689                        showBootMessage(mContext.getText(
11690                                R.string.android_upgrading_complete),
11691                                false);
11692                        writeLastDonePreBootReceivers(doneReceivers);
11693                        systemReady(goingCallback);
11694                    }
11695                }, doneReceivers, UserHandle.USER_OWNER);
11696
11697                if (mWaitingUpdate) {
11698                    return;
11699                }
11700                mDidUpdate = true;
11701            }
11702
11703            mAppOpsService.systemReady();
11704            mSystemReady = true;
11705        }
11706
11707        ArrayList<ProcessRecord> procsToKill = null;
11708        synchronized(mPidsSelfLocked) {
11709            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11710                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11711                if (!isAllowedWhileBooting(proc.info)){
11712                    if (procsToKill == null) {
11713                        procsToKill = new ArrayList<ProcessRecord>();
11714                    }
11715                    procsToKill.add(proc);
11716                }
11717            }
11718        }
11719
11720        synchronized(this) {
11721            if (procsToKill != null) {
11722                for (int i=procsToKill.size()-1; i>=0; i--) {
11723                    ProcessRecord proc = procsToKill.get(i);
11724                    Slog.i(TAG, "Removing system update proc: " + proc);
11725                    removeProcessLocked(proc, true, false, "system update done");
11726                }
11727            }
11728
11729            // Now that we have cleaned up any update processes, we
11730            // are ready to start launching real processes and know that
11731            // we won't trample on them any more.
11732            mProcessesReady = true;
11733        }
11734
11735        Slog.i(TAG, "System now ready");
11736        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11737            SystemClock.uptimeMillis());
11738
11739        synchronized(this) {
11740            // Make sure we have no pre-ready processes sitting around.
11741
11742            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11743                ResolveInfo ri = mContext.getPackageManager()
11744                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11745                                STOCK_PM_FLAGS);
11746                CharSequence errorMsg = null;
11747                if (ri != null) {
11748                    ActivityInfo ai = ri.activityInfo;
11749                    ApplicationInfo app = ai.applicationInfo;
11750                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11751                        mTopAction = Intent.ACTION_FACTORY_TEST;
11752                        mTopData = null;
11753                        mTopComponent = new ComponentName(app.packageName,
11754                                ai.name);
11755                    } else {
11756                        errorMsg = mContext.getResources().getText(
11757                                com.android.internal.R.string.factorytest_not_system);
11758                    }
11759                } else {
11760                    errorMsg = mContext.getResources().getText(
11761                            com.android.internal.R.string.factorytest_no_action);
11762                }
11763                if (errorMsg != null) {
11764                    mTopAction = null;
11765                    mTopData = null;
11766                    mTopComponent = null;
11767                    Message msg = Message.obtain();
11768                    msg.what = SHOW_FACTORY_ERROR_MSG;
11769                    msg.getData().putCharSequence("msg", errorMsg);
11770                    mUiHandler.sendMessage(msg);
11771                }
11772            }
11773        }
11774
11775        retrieveSettings();
11776        loadResourcesOnSystemReady();
11777
11778        synchronized (this) {
11779            readGrantedUriPermissionsLocked();
11780        }
11781
11782        if (goingCallback != null) goingCallback.run();
11783
11784        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11785                Integer.toString(mCurrentUserId), mCurrentUserId);
11786        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11787                Integer.toString(mCurrentUserId), mCurrentUserId);
11788        mSystemServiceManager.startUser(mCurrentUserId);
11789
11790        synchronized (this) {
11791            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11792                try {
11793                    List apps = AppGlobals.getPackageManager().
11794                        getPersistentApplications(STOCK_PM_FLAGS);
11795                    if (apps != null) {
11796                        int N = apps.size();
11797                        int i;
11798                        for (i=0; i<N; i++) {
11799                            ApplicationInfo info
11800                                = (ApplicationInfo)apps.get(i);
11801                            if (info != null &&
11802                                    !info.packageName.equals("android")) {
11803                                addAppLocked(info, false, null /* ABI override */);
11804                            }
11805                        }
11806                    }
11807                } catch (RemoteException ex) {
11808                    // pm is in same process, this will never happen.
11809                }
11810            }
11811
11812            // Start up initial activity.
11813            mBooting = true;
11814            startHomeActivityLocked(mCurrentUserId, "systemReady");
11815
11816            try {
11817                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11818                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11819                            + " data partition or your device will be unstable.");
11820                    mUiHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11821                }
11822            } catch (RemoteException e) {
11823            }
11824
11825            if (!Build.isBuildConsistent()) {
11826                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11827                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11828            }
11829
11830            long ident = Binder.clearCallingIdentity();
11831            try {
11832                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11833                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11834                        | Intent.FLAG_RECEIVER_FOREGROUND);
11835                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11836                broadcastIntentLocked(null, null, intent,
11837                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11838                        null, false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11839                intent = new Intent(Intent.ACTION_USER_STARTING);
11840                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11841                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11842                broadcastIntentLocked(null, null, intent,
11843                        null, new IIntentReceiver.Stub() {
11844                            @Override
11845                            public void performReceive(Intent intent, int resultCode, String data,
11846                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11847                                    throws RemoteException {
11848                            }
11849                        }, 0, null, null,
11850                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
11851                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11852            } catch (Throwable t) {
11853                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11854            } finally {
11855                Binder.restoreCallingIdentity(ident);
11856            }
11857            mStackSupervisor.resumeTopActivitiesLocked();
11858            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11859        }
11860    }
11861
11862    private boolean makeAppCrashingLocked(ProcessRecord app,
11863            String shortMsg, String longMsg, String stackTrace) {
11864        app.crashing = true;
11865        app.crashingReport = generateProcessError(app,
11866                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11867        startAppProblemLocked(app);
11868        app.stopFreezingAllLocked();
11869        return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
11870    }
11871
11872    private void makeAppNotRespondingLocked(ProcessRecord app,
11873            String activity, String shortMsg, String longMsg) {
11874        app.notResponding = true;
11875        app.notRespondingReport = generateProcessError(app,
11876                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11877                activity, shortMsg, longMsg, null);
11878        startAppProblemLocked(app);
11879        app.stopFreezingAllLocked();
11880    }
11881
11882    /**
11883     * Generate a process error record, suitable for attachment to a ProcessRecord.
11884     *
11885     * @param app The ProcessRecord in which the error occurred.
11886     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11887     *                      ActivityManager.AppErrorStateInfo
11888     * @param activity The activity associated with the crash, if known.
11889     * @param shortMsg Short message describing the crash.
11890     * @param longMsg Long message describing the crash.
11891     * @param stackTrace Full crash stack trace, may be null.
11892     *
11893     * @return Returns a fully-formed AppErrorStateInfo record.
11894     */
11895    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11896            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11897        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11898
11899        report.condition = condition;
11900        report.processName = app.processName;
11901        report.pid = app.pid;
11902        report.uid = app.info.uid;
11903        report.tag = activity;
11904        report.shortMsg = shortMsg;
11905        report.longMsg = longMsg;
11906        report.stackTrace = stackTrace;
11907
11908        return report;
11909    }
11910
11911    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11912        synchronized (this) {
11913            app.crashing = false;
11914            app.crashingReport = null;
11915            app.notResponding = false;
11916            app.notRespondingReport = null;
11917            if (app.anrDialog == fromDialog) {
11918                app.anrDialog = null;
11919            }
11920            if (app.waitDialog == fromDialog) {
11921                app.waitDialog = null;
11922            }
11923            if (app.pid > 0 && app.pid != MY_PID) {
11924                handleAppCrashLocked(app, "user-terminated" /*reason*/,
11925                        null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
11926                app.kill("user request after error", true);
11927            }
11928        }
11929    }
11930
11931    private boolean handleAppCrashLocked(ProcessRecord app, String reason,
11932            String shortMsg, String longMsg, String stackTrace) {
11933        long now = SystemClock.uptimeMillis();
11934
11935        Long crashTime;
11936        if (!app.isolated) {
11937            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11938        } else {
11939            crashTime = null;
11940        }
11941        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11942            // This process loses!
11943            Slog.w(TAG, "Process " + app.info.processName
11944                    + " has crashed too many times: killing!");
11945            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11946                    app.userId, app.info.processName, app.uid);
11947            mStackSupervisor.handleAppCrashLocked(app);
11948            if (!app.persistent) {
11949                // We don't want to start this process again until the user
11950                // explicitly does so...  but for persistent process, we really
11951                // need to keep it running.  If a persistent process is actually
11952                // repeatedly crashing, then badness for everyone.
11953                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11954                        app.info.processName);
11955                if (!app.isolated) {
11956                    // XXX We don't have a way to mark isolated processes
11957                    // as bad, since they don't have a peristent identity.
11958                    mBadProcesses.put(app.info.processName, app.uid,
11959                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11960                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11961                }
11962                app.bad = true;
11963                app.removed = true;
11964                // Don't let services in this process be restarted and potentially
11965                // annoy the user repeatedly.  Unless it is persistent, since those
11966                // processes run critical code.
11967                removeProcessLocked(app, false, false, "crash");
11968                mStackSupervisor.resumeTopActivitiesLocked();
11969                return false;
11970            }
11971            mStackSupervisor.resumeTopActivitiesLocked();
11972        } else {
11973            mStackSupervisor.finishTopRunningActivityLocked(app, reason);
11974        }
11975
11976        // Bump up the crash count of any services currently running in the proc.
11977        for (int i=app.services.size()-1; i>=0; i--) {
11978            // Any services running in the application need to be placed
11979            // back in the pending list.
11980            ServiceRecord sr = app.services.valueAt(i);
11981            sr.crashCount++;
11982        }
11983
11984        // If the crashing process is what we consider to be the "home process" and it has been
11985        // replaced by a third-party app, clear the package preferred activities from packages
11986        // with a home activity running in the process to prevent a repeatedly crashing app
11987        // from blocking the user to manually clear the list.
11988        final ArrayList<ActivityRecord> activities = app.activities;
11989        if (app == mHomeProcess && activities.size() > 0
11990                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11991            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11992                final ActivityRecord r = activities.get(activityNdx);
11993                if (r.isHomeActivity()) {
11994                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11995                    try {
11996                        ActivityThread.getPackageManager()
11997                                .clearPackagePreferredActivities(r.packageName);
11998                    } catch (RemoteException c) {
11999                        // pm is in same process, this will never happen.
12000                    }
12001                }
12002            }
12003        }
12004
12005        if (!app.isolated) {
12006            // XXX Can't keep track of crash times for isolated processes,
12007            // because they don't have a perisistent identity.
12008            mProcessCrashTimes.put(app.info.processName, app.uid, now);
12009        }
12010
12011        if (app.crashHandler != null) mHandler.post(app.crashHandler);
12012        return true;
12013    }
12014
12015    void startAppProblemLocked(ProcessRecord app) {
12016        // If this app is not running under the current user, then we
12017        // can't give it a report button because that would require
12018        // launching the report UI under a different user.
12019        app.errorReportReceiver = null;
12020
12021        for (int userId : mCurrentProfileIds) {
12022            if (app.userId == userId) {
12023                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
12024                        mContext, app.info.packageName, app.info.flags);
12025            }
12026        }
12027        skipCurrentReceiverLocked(app);
12028    }
12029
12030    void skipCurrentReceiverLocked(ProcessRecord app) {
12031        for (BroadcastQueue queue : mBroadcastQueues) {
12032            queue.skipCurrentReceiverLocked(app);
12033        }
12034    }
12035
12036    /**
12037     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12038     * The application process will exit immediately after this call returns.
12039     * @param app object of the crashing app, null for the system server
12040     * @param crashInfo describing the exception
12041     */
12042    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12043        ProcessRecord r = findAppProcess(app, "Crash");
12044        final String processName = app == null ? "system_server"
12045                : (r == null ? "unknown" : r.processName);
12046
12047        handleApplicationCrashInner("crash", r, processName, crashInfo);
12048    }
12049
12050    /* Native crash reporting uses this inner version because it needs to be somewhat
12051     * decoupled from the AM-managed cleanup lifecycle
12052     */
12053    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12054            ApplicationErrorReport.CrashInfo crashInfo) {
12055        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12056                UserHandle.getUserId(Binder.getCallingUid()), processName,
12057                r == null ? -1 : r.info.flags,
12058                crashInfo.exceptionClassName,
12059                crashInfo.exceptionMessage,
12060                crashInfo.throwFileName,
12061                crashInfo.throwLineNumber);
12062
12063        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12064
12065        crashApplication(r, crashInfo);
12066    }
12067
12068    public void handleApplicationStrictModeViolation(
12069            IBinder app,
12070            int violationMask,
12071            StrictMode.ViolationInfo info) {
12072        ProcessRecord r = findAppProcess(app, "StrictMode");
12073        if (r == null) {
12074            return;
12075        }
12076
12077        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12078            Integer stackFingerprint = info.hashCode();
12079            boolean logIt = true;
12080            synchronized (mAlreadyLoggedViolatedStacks) {
12081                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12082                    logIt = false;
12083                    // TODO: sub-sample into EventLog for these, with
12084                    // the info.durationMillis?  Then we'd get
12085                    // the relative pain numbers, without logging all
12086                    // the stack traces repeatedly.  We'd want to do
12087                    // likewise in the client code, which also does
12088                    // dup suppression, before the Binder call.
12089                } else {
12090                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12091                        mAlreadyLoggedViolatedStacks.clear();
12092                    }
12093                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12094                }
12095            }
12096            if (logIt) {
12097                logStrictModeViolationToDropBox(r, info);
12098            }
12099        }
12100
12101        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12102            AppErrorResult result = new AppErrorResult();
12103            synchronized (this) {
12104                final long origId = Binder.clearCallingIdentity();
12105
12106                Message msg = Message.obtain();
12107                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
12108                HashMap<String, Object> data = new HashMap<String, Object>();
12109                data.put("result", result);
12110                data.put("app", r);
12111                data.put("violationMask", violationMask);
12112                data.put("info", info);
12113                msg.obj = data;
12114                mUiHandler.sendMessage(msg);
12115
12116                Binder.restoreCallingIdentity(origId);
12117            }
12118            int res = result.get();
12119            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12120        }
12121    }
12122
12123    // Depending on the policy in effect, there could be a bunch of
12124    // these in quick succession so we try to batch these together to
12125    // minimize disk writes, number of dropbox entries, and maximize
12126    // compression, by having more fewer, larger records.
12127    private void logStrictModeViolationToDropBox(
12128            ProcessRecord process,
12129            StrictMode.ViolationInfo info) {
12130        if (info == null) {
12131            return;
12132        }
12133        final boolean isSystemApp = process == null ||
12134                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12135                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12136        final String processName = process == null ? "unknown" : process.processName;
12137        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12138        final DropBoxManager dbox = (DropBoxManager)
12139                mContext.getSystemService(Context.DROPBOX_SERVICE);
12140
12141        // Exit early if the dropbox isn't configured to accept this report type.
12142        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12143
12144        boolean bufferWasEmpty;
12145        boolean needsFlush;
12146        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12147        synchronized (sb) {
12148            bufferWasEmpty = sb.length() == 0;
12149            appendDropBoxProcessHeaders(process, processName, sb);
12150            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12151            sb.append("System-App: ").append(isSystemApp).append("\n");
12152            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12153            if (info.violationNumThisLoop != 0) {
12154                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12155            }
12156            if (info.numAnimationsRunning != 0) {
12157                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12158            }
12159            if (info.broadcastIntentAction != null) {
12160                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12161            }
12162            if (info.durationMillis != -1) {
12163                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12164            }
12165            if (info.numInstances != -1) {
12166                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12167            }
12168            if (info.tags != null) {
12169                for (String tag : info.tags) {
12170                    sb.append("Span-Tag: ").append(tag).append("\n");
12171                }
12172            }
12173            sb.append("\n");
12174            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
12175                sb.append(info.crashInfo.stackTrace);
12176                sb.append("\n");
12177            }
12178            if (info.message != null) {
12179                sb.append(info.message);
12180                sb.append("\n");
12181            }
12182
12183            // Only buffer up to ~64k.  Various logging bits truncate
12184            // things at 128k.
12185            needsFlush = (sb.length() > 64 * 1024);
12186        }
12187
12188        // Flush immediately if the buffer's grown too large, or this
12189        // is a non-system app.  Non-system apps are isolated with a
12190        // different tag & policy and not batched.
12191        //
12192        // Batching is useful during internal testing with
12193        // StrictMode settings turned up high.  Without batching,
12194        // thousands of separate files could be created on boot.
12195        if (!isSystemApp || needsFlush) {
12196            new Thread("Error dump: " + dropboxTag) {
12197                @Override
12198                public void run() {
12199                    String report;
12200                    synchronized (sb) {
12201                        report = sb.toString();
12202                        sb.delete(0, sb.length());
12203                        sb.trimToSize();
12204                    }
12205                    if (report.length() != 0) {
12206                        dbox.addText(dropboxTag, report);
12207                    }
12208                }
12209            }.start();
12210            return;
12211        }
12212
12213        // System app batching:
12214        if (!bufferWasEmpty) {
12215            // An existing dropbox-writing thread is outstanding, so
12216            // we don't need to start it up.  The existing thread will
12217            // catch the buffer appends we just did.
12218            return;
12219        }
12220
12221        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
12222        // (After this point, we shouldn't access AMS internal data structures.)
12223        new Thread("Error dump: " + dropboxTag) {
12224            @Override
12225            public void run() {
12226                // 5 second sleep to let stacks arrive and be batched together
12227                try {
12228                    Thread.sleep(5000);  // 5 seconds
12229                } catch (InterruptedException e) {}
12230
12231                String errorReport;
12232                synchronized (mStrictModeBuffer) {
12233                    errorReport = mStrictModeBuffer.toString();
12234                    if (errorReport.length() == 0) {
12235                        return;
12236                    }
12237                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
12238                    mStrictModeBuffer.trimToSize();
12239                }
12240                dbox.addText(dropboxTag, errorReport);
12241            }
12242        }.start();
12243    }
12244
12245    /**
12246     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
12247     * @param app object of the crashing app, null for the system server
12248     * @param tag reported by the caller
12249     * @param system whether this wtf is coming from the system
12250     * @param crashInfo describing the context of the error
12251     * @return true if the process should exit immediately (WTF is fatal)
12252     */
12253    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
12254            final ApplicationErrorReport.CrashInfo crashInfo) {
12255        final int callingUid = Binder.getCallingUid();
12256        final int callingPid = Binder.getCallingPid();
12257
12258        if (system) {
12259            // If this is coming from the system, we could very well have low-level
12260            // system locks held, so we want to do this all asynchronously.  And we
12261            // never want this to become fatal, so there is that too.
12262            mHandler.post(new Runnable() {
12263                @Override public void run() {
12264                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
12265                }
12266            });
12267            return false;
12268        }
12269
12270        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
12271                crashInfo);
12272
12273        if (r != null && r.pid != Process.myPid() &&
12274                Settings.Global.getInt(mContext.getContentResolver(),
12275                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
12276            crashApplication(r, crashInfo);
12277            return true;
12278        } else {
12279            return false;
12280        }
12281    }
12282
12283    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
12284            final ApplicationErrorReport.CrashInfo crashInfo) {
12285        final ProcessRecord r = findAppProcess(app, "WTF");
12286        final String processName = app == null ? "system_server"
12287                : (r == null ? "unknown" : r.processName);
12288
12289        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
12290                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
12291
12292        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
12293
12294        return r;
12295    }
12296
12297    /**
12298     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
12299     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
12300     */
12301    private ProcessRecord findAppProcess(IBinder app, String reason) {
12302        if (app == null) {
12303            return null;
12304        }
12305
12306        synchronized (this) {
12307            final int NP = mProcessNames.getMap().size();
12308            for (int ip=0; ip<NP; ip++) {
12309                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12310                final int NA = apps.size();
12311                for (int ia=0; ia<NA; ia++) {
12312                    ProcessRecord p = apps.valueAt(ia);
12313                    if (p.thread != null && p.thread.asBinder() == app) {
12314                        return p;
12315                    }
12316                }
12317            }
12318
12319            Slog.w(TAG, "Can't find mystery application for " + reason
12320                    + " from pid=" + Binder.getCallingPid()
12321                    + " uid=" + Binder.getCallingUid() + ": " + app);
12322            return null;
12323        }
12324    }
12325
12326    /**
12327     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
12328     * to append various headers to the dropbox log text.
12329     */
12330    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
12331            StringBuilder sb) {
12332        // Watchdog thread ends up invoking this function (with
12333        // a null ProcessRecord) to add the stack file to dropbox.
12334        // Do not acquire a lock on this (am) in such cases, as it
12335        // could cause a potential deadlock, if and when watchdog
12336        // is invoked due to unavailability of lock on am and it
12337        // would prevent watchdog from killing system_server.
12338        if (process == null) {
12339            sb.append("Process: ").append(processName).append("\n");
12340            return;
12341        }
12342        // Note: ProcessRecord 'process' is guarded by the service
12343        // instance.  (notably process.pkgList, which could otherwise change
12344        // concurrently during execution of this method)
12345        synchronized (this) {
12346            sb.append("Process: ").append(processName).append("\n");
12347            int flags = process.info.flags;
12348            IPackageManager pm = AppGlobals.getPackageManager();
12349            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
12350            for (int ip=0; ip<process.pkgList.size(); ip++) {
12351                String pkg = process.pkgList.keyAt(ip);
12352                sb.append("Package: ").append(pkg);
12353                try {
12354                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
12355                    if (pi != null) {
12356                        sb.append(" v").append(pi.versionCode);
12357                        if (pi.versionName != null) {
12358                            sb.append(" (").append(pi.versionName).append(")");
12359                        }
12360                    }
12361                } catch (RemoteException e) {
12362                    Slog.e(TAG, "Error getting package info: " + pkg, e);
12363                }
12364                sb.append("\n");
12365            }
12366        }
12367    }
12368
12369    private static String processClass(ProcessRecord process) {
12370        if (process == null || process.pid == MY_PID) {
12371            return "system_server";
12372        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
12373            return "system_app";
12374        } else {
12375            return "data_app";
12376        }
12377    }
12378
12379    /**
12380     * Write a description of an error (crash, WTF, ANR) to the drop box.
12381     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
12382     * @param process which caused the error, null means the system server
12383     * @param activity which triggered the error, null if unknown
12384     * @param parent activity related to the error, null if unknown
12385     * @param subject line related to the error, null if absent
12386     * @param report in long form describing the error, null if absent
12387     * @param logFile to include in the report, null if none
12388     * @param crashInfo giving an application stack trace, null if absent
12389     */
12390    public void addErrorToDropBox(String eventType,
12391            ProcessRecord process, String processName, ActivityRecord activity,
12392            ActivityRecord parent, String subject,
12393            final String report, final File logFile,
12394            final ApplicationErrorReport.CrashInfo crashInfo) {
12395        // NOTE -- this must never acquire the ActivityManagerService lock,
12396        // otherwise the watchdog may be prevented from resetting the system.
12397
12398        final String dropboxTag = processClass(process) + "_" + eventType;
12399        final DropBoxManager dbox = (DropBoxManager)
12400                mContext.getSystemService(Context.DROPBOX_SERVICE);
12401
12402        // Exit early if the dropbox isn't configured to accept this report type.
12403        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12404
12405        final StringBuilder sb = new StringBuilder(1024);
12406        appendDropBoxProcessHeaders(process, processName, sb);
12407        if (activity != null) {
12408            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
12409        }
12410        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
12411            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
12412        }
12413        if (parent != null && parent != activity) {
12414            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
12415        }
12416        if (subject != null) {
12417            sb.append("Subject: ").append(subject).append("\n");
12418        }
12419        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12420        if (Debug.isDebuggerConnected()) {
12421            sb.append("Debugger: Connected\n");
12422        }
12423        sb.append("\n");
12424
12425        // Do the rest in a worker thread to avoid blocking the caller on I/O
12426        // (After this point, we shouldn't access AMS internal data structures.)
12427        Thread worker = new Thread("Error dump: " + dropboxTag) {
12428            @Override
12429            public void run() {
12430                if (report != null) {
12431                    sb.append(report);
12432                }
12433                if (logFile != null) {
12434                    try {
12435                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
12436                                    "\n\n[[TRUNCATED]]"));
12437                    } catch (IOException e) {
12438                        Slog.e(TAG, "Error reading " + logFile, e);
12439                    }
12440                }
12441                if (crashInfo != null && crashInfo.stackTrace != null) {
12442                    sb.append(crashInfo.stackTrace);
12443                }
12444
12445                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
12446                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
12447                if (lines > 0) {
12448                    sb.append("\n");
12449
12450                    // Merge several logcat streams, and take the last N lines
12451                    InputStreamReader input = null;
12452                    try {
12453                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
12454                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
12455                                "-b", "crash",
12456                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
12457
12458                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
12459                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
12460                        input = new InputStreamReader(logcat.getInputStream());
12461
12462                        int num;
12463                        char[] buf = new char[8192];
12464                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
12465                    } catch (IOException e) {
12466                        Slog.e(TAG, "Error running logcat", e);
12467                    } finally {
12468                        if (input != null) try { input.close(); } catch (IOException e) {}
12469                    }
12470                }
12471
12472                dbox.addText(dropboxTag, sb.toString());
12473            }
12474        };
12475
12476        if (process == null) {
12477            // If process is null, we are being called from some internal code
12478            // and may be about to die -- run this synchronously.
12479            worker.run();
12480        } else {
12481            worker.start();
12482        }
12483    }
12484
12485    /**
12486     * Bring up the "unexpected error" dialog box for a crashing app.
12487     * Deal with edge cases (intercepts from instrumented applications,
12488     * ActivityController, error intent receivers, that sort of thing).
12489     * @param r the application crashing
12490     * @param crashInfo describing the failure
12491     */
12492    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12493        long timeMillis = System.currentTimeMillis();
12494        String shortMsg = crashInfo.exceptionClassName;
12495        String longMsg = crashInfo.exceptionMessage;
12496        String stackTrace = crashInfo.stackTrace;
12497        if (shortMsg != null && longMsg != null) {
12498            longMsg = shortMsg + ": " + longMsg;
12499        } else if (shortMsg != null) {
12500            longMsg = shortMsg;
12501        }
12502
12503        AppErrorResult result = new AppErrorResult();
12504        synchronized (this) {
12505            if (mController != null) {
12506                try {
12507                    String name = r != null ? r.processName : null;
12508                    int pid = r != null ? r.pid : Binder.getCallingPid();
12509                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
12510                    if (!mController.appCrashed(name, pid,
12511                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12512                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12513                                && "Native crash".equals(crashInfo.exceptionClassName)) {
12514                            Slog.w(TAG, "Skip killing native crashed app " + name
12515                                    + "(" + pid + ") during testing");
12516                        } else {
12517                            Slog.w(TAG, "Force-killing crashed app " + name
12518                                    + " at watcher's request");
12519                            if (r != null) {
12520                                r.kill("crash", true);
12521                            } else {
12522                                // Huh.
12523                                Process.killProcess(pid);
12524                                killProcessGroup(uid, pid);
12525                            }
12526                        }
12527                        return;
12528                    }
12529                } catch (RemoteException e) {
12530                    mController = null;
12531                    Watchdog.getInstance().setActivityController(null);
12532                }
12533            }
12534
12535            final long origId = Binder.clearCallingIdentity();
12536
12537            // If this process is running instrumentation, finish it.
12538            if (r != null && r.instrumentationClass != null) {
12539                Slog.w(TAG, "Error in app " + r.processName
12540                      + " running instrumentation " + r.instrumentationClass + ":");
12541                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12542                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12543                Bundle info = new Bundle();
12544                info.putString("shortMsg", shortMsg);
12545                info.putString("longMsg", longMsg);
12546                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12547                Binder.restoreCallingIdentity(origId);
12548                return;
12549            }
12550
12551            // Log crash in battery stats.
12552            if (r != null) {
12553                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12554            }
12555
12556            // If we can't identify the process or it's already exceeded its crash quota,
12557            // quit right away without showing a crash dialog.
12558            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12559                Binder.restoreCallingIdentity(origId);
12560                return;
12561            }
12562
12563            Message msg = Message.obtain();
12564            msg.what = SHOW_ERROR_MSG;
12565            HashMap data = new HashMap();
12566            data.put("result", result);
12567            data.put("app", r);
12568            msg.obj = data;
12569            mUiHandler.sendMessage(msg);
12570
12571            Binder.restoreCallingIdentity(origId);
12572        }
12573
12574        int res = result.get();
12575
12576        Intent appErrorIntent = null;
12577        synchronized (this) {
12578            if (r != null && !r.isolated) {
12579                // XXX Can't keep track of crash time for isolated processes,
12580                // since they don't have a persistent identity.
12581                mProcessCrashTimes.put(r.info.processName, r.uid,
12582                        SystemClock.uptimeMillis());
12583            }
12584            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12585                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12586            }
12587        }
12588
12589        if (appErrorIntent != null) {
12590            try {
12591                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12592            } catch (ActivityNotFoundException e) {
12593                Slog.w(TAG, "bug report receiver dissappeared", e);
12594            }
12595        }
12596    }
12597
12598    Intent createAppErrorIntentLocked(ProcessRecord r,
12599            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12600        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12601        if (report == null) {
12602            return null;
12603        }
12604        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12605        result.setComponent(r.errorReportReceiver);
12606        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12607        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12608        return result;
12609    }
12610
12611    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12612            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12613        if (r.errorReportReceiver == null) {
12614            return null;
12615        }
12616
12617        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12618            return null;
12619        }
12620
12621        ApplicationErrorReport report = new ApplicationErrorReport();
12622        report.packageName = r.info.packageName;
12623        report.installerPackageName = r.errorReportReceiver.getPackageName();
12624        report.processName = r.processName;
12625        report.time = timeMillis;
12626        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12627
12628        if (r.crashing || r.forceCrashReport) {
12629            report.type = ApplicationErrorReport.TYPE_CRASH;
12630            report.crashInfo = crashInfo;
12631        } else if (r.notResponding) {
12632            report.type = ApplicationErrorReport.TYPE_ANR;
12633            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12634
12635            report.anrInfo.activity = r.notRespondingReport.tag;
12636            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12637            report.anrInfo.info = r.notRespondingReport.longMsg;
12638        }
12639
12640        return report;
12641    }
12642
12643    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12644        enforceNotIsolatedCaller("getProcessesInErrorState");
12645        // assume our apps are happy - lazy create the list
12646        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12647
12648        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12649                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12650        int userId = UserHandle.getUserId(Binder.getCallingUid());
12651
12652        synchronized (this) {
12653
12654            // iterate across all processes
12655            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12656                ProcessRecord app = mLruProcesses.get(i);
12657                if (!allUsers && app.userId != userId) {
12658                    continue;
12659                }
12660                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12661                    // This one's in trouble, so we'll generate a report for it
12662                    // crashes are higher priority (in case there's a crash *and* an anr)
12663                    ActivityManager.ProcessErrorStateInfo report = null;
12664                    if (app.crashing) {
12665                        report = app.crashingReport;
12666                    } else if (app.notResponding) {
12667                        report = app.notRespondingReport;
12668                    }
12669
12670                    if (report != null) {
12671                        if (errList == null) {
12672                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12673                        }
12674                        errList.add(report);
12675                    } else {
12676                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12677                                " crashing = " + app.crashing +
12678                                " notResponding = " + app.notResponding);
12679                    }
12680                }
12681            }
12682        }
12683
12684        return errList;
12685    }
12686
12687    static int procStateToImportance(int procState, int memAdj,
12688            ActivityManager.RunningAppProcessInfo currApp) {
12689        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12690        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12691            currApp.lru = memAdj;
12692        } else {
12693            currApp.lru = 0;
12694        }
12695        return imp;
12696    }
12697
12698    private void fillInProcMemInfo(ProcessRecord app,
12699            ActivityManager.RunningAppProcessInfo outInfo) {
12700        outInfo.pid = app.pid;
12701        outInfo.uid = app.info.uid;
12702        if (mHeavyWeightProcess == app) {
12703            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12704        }
12705        if (app.persistent) {
12706            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12707        }
12708        if (app.activities.size() > 0) {
12709            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12710        }
12711        outInfo.lastTrimLevel = app.trimMemoryLevel;
12712        int adj = app.curAdj;
12713        int procState = app.curProcState;
12714        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12715        outInfo.importanceReasonCode = app.adjTypeCode;
12716        outInfo.processState = app.curProcState;
12717    }
12718
12719    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12720        enforceNotIsolatedCaller("getRunningAppProcesses");
12721
12722        final int callingUid = Binder.getCallingUid();
12723
12724        // Lazy instantiation of list
12725        List<ActivityManager.RunningAppProcessInfo> runList = null;
12726        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12727                callingUid) == PackageManager.PERMISSION_GRANTED;
12728        final int userId = UserHandle.getUserId(callingUid);
12729        final boolean allUids = isGetTasksAllowed(
12730                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
12731
12732        synchronized (this) {
12733            // Iterate across all processes
12734            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
12735                ProcessRecord app = mLruProcesses.get(i);
12736                if ((!allUsers && app.userId != userId)
12737                        || (!allUids && app.uid != callingUid)) {
12738                    continue;
12739                }
12740                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12741                    // Generate process state info for running application
12742                    ActivityManager.RunningAppProcessInfo currApp =
12743                        new ActivityManager.RunningAppProcessInfo(app.processName,
12744                                app.pid, app.getPackageList());
12745                    fillInProcMemInfo(app, currApp);
12746                    if (app.adjSource instanceof ProcessRecord) {
12747                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12748                        currApp.importanceReasonImportance =
12749                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12750                                        app.adjSourceProcState);
12751                    } else if (app.adjSource instanceof ActivityRecord) {
12752                        ActivityRecord r = (ActivityRecord)app.adjSource;
12753                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12754                    }
12755                    if (app.adjTarget instanceof ComponentName) {
12756                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12757                    }
12758                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12759                    //        + " lru=" + currApp.lru);
12760                    if (runList == null) {
12761                        runList = new ArrayList<>();
12762                    }
12763                    runList.add(currApp);
12764                }
12765            }
12766        }
12767        return runList;
12768    }
12769
12770    public List<ApplicationInfo> getRunningExternalApplications() {
12771        enforceNotIsolatedCaller("getRunningExternalApplications");
12772        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12773        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12774        if (runningApps != null && runningApps.size() > 0) {
12775            Set<String> extList = new HashSet<String>();
12776            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12777                if (app.pkgList != null) {
12778                    for (String pkg : app.pkgList) {
12779                        extList.add(pkg);
12780                    }
12781                }
12782            }
12783            IPackageManager pm = AppGlobals.getPackageManager();
12784            for (String pkg : extList) {
12785                try {
12786                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12787                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12788                        retList.add(info);
12789                    }
12790                } catch (RemoteException e) {
12791                }
12792            }
12793        }
12794        return retList;
12795    }
12796
12797    @Override
12798    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12799        enforceNotIsolatedCaller("getMyMemoryState");
12800        synchronized (this) {
12801            ProcessRecord proc;
12802            synchronized (mPidsSelfLocked) {
12803                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12804            }
12805            fillInProcMemInfo(proc, outInfo);
12806        }
12807    }
12808
12809    @Override
12810    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12811        if (checkCallingPermission(android.Manifest.permission.DUMP)
12812                != PackageManager.PERMISSION_GRANTED) {
12813            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12814                    + Binder.getCallingPid()
12815                    + ", uid=" + Binder.getCallingUid()
12816                    + " without permission "
12817                    + android.Manifest.permission.DUMP);
12818            return;
12819        }
12820
12821        boolean dumpAll = false;
12822        boolean dumpClient = false;
12823        String dumpPackage = null;
12824
12825        int opti = 0;
12826        while (opti < args.length) {
12827            String opt = args[opti];
12828            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12829                break;
12830            }
12831            opti++;
12832            if ("-a".equals(opt)) {
12833                dumpAll = true;
12834            } else if ("-c".equals(opt)) {
12835                dumpClient = true;
12836            } else if ("-p".equals(opt)) {
12837                if (opti < args.length) {
12838                    dumpPackage = args[opti];
12839                    opti++;
12840                } else {
12841                    pw.println("Error: -p option requires package argument");
12842                    return;
12843                }
12844                dumpClient = true;
12845            } else if ("-h".equals(opt)) {
12846                pw.println("Activity manager dump options:");
12847                pw.println("  [-a] [-c] [-p package] [-h] [cmd] ...");
12848                pw.println("  cmd may be one of:");
12849                pw.println("    a[ctivities]: activity stack state");
12850                pw.println("    r[recents]: recent activities state");
12851                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12852                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12853                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12854                pw.println("    o[om]: out of memory management");
12855                pw.println("    perm[issions]: URI permission grant state");
12856                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12857                pw.println("    provider [COMP_SPEC]: provider client-side state");
12858                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12859                pw.println("    as[sociations]: tracked app associations");
12860                pw.println("    service [COMP_SPEC]: service client-side state");
12861                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12862                pw.println("    all: dump all activities");
12863                pw.println("    top: dump the top activity");
12864                pw.println("    write: write all pending state to storage");
12865                pw.println("    track-associations: enable association tracking");
12866                pw.println("    untrack-associations: disable and clear association tracking");
12867                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12868                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12869                pw.println("    a partial substring in a component name, a");
12870                pw.println("    hex object identifier.");
12871                pw.println("  -a: include all available server state.");
12872                pw.println("  -c: include client state.");
12873                pw.println("  -p: limit output to given package.");
12874                return;
12875            } else {
12876                pw.println("Unknown argument: " + opt + "; use -h for help");
12877            }
12878        }
12879
12880        long origId = Binder.clearCallingIdentity();
12881        boolean more = false;
12882        // Is the caller requesting to dump a particular piece of data?
12883        if (opti < args.length) {
12884            String cmd = args[opti];
12885            opti++;
12886            if ("activities".equals(cmd) || "a".equals(cmd)) {
12887                synchronized (this) {
12888                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12889                }
12890            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12891                synchronized (this) {
12892                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
12893                }
12894            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12895                String[] newArgs;
12896                String name;
12897                if (opti >= args.length) {
12898                    name = null;
12899                    newArgs = EMPTY_STRING_ARRAY;
12900                } else {
12901                    dumpPackage = args[opti];
12902                    opti++;
12903                    newArgs = new String[args.length - opti];
12904                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12905                            args.length - opti);
12906                }
12907                synchronized (this) {
12908                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
12909                }
12910            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12911                String[] newArgs;
12912                String name;
12913                if (opti >= args.length) {
12914                    name = null;
12915                    newArgs = EMPTY_STRING_ARRAY;
12916                } else {
12917                    dumpPackage = args[opti];
12918                    opti++;
12919                    newArgs = new String[args.length - opti];
12920                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12921                            args.length - opti);
12922                }
12923                synchronized (this) {
12924                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
12925                }
12926            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12927                String[] newArgs;
12928                String name;
12929                if (opti >= args.length) {
12930                    name = null;
12931                    newArgs = EMPTY_STRING_ARRAY;
12932                } else {
12933                    dumpPackage = args[opti];
12934                    opti++;
12935                    newArgs = new String[args.length - opti];
12936                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12937                            args.length - opti);
12938                }
12939                synchronized (this) {
12940                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
12941                }
12942            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12943                synchronized (this) {
12944                    dumpOomLocked(fd, pw, args, opti, true);
12945                }
12946            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
12947                synchronized (this) {
12948                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
12949                }
12950            } else if ("provider".equals(cmd)) {
12951                String[] newArgs;
12952                String name;
12953                if (opti >= args.length) {
12954                    name = null;
12955                    newArgs = EMPTY_STRING_ARRAY;
12956                } else {
12957                    name = args[opti];
12958                    opti++;
12959                    newArgs = new String[args.length - opti];
12960                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12961                }
12962                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12963                    pw.println("No providers match: " + name);
12964                    pw.println("Use -h for help.");
12965                }
12966            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12967                synchronized (this) {
12968                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12969                }
12970            } else if ("service".equals(cmd)) {
12971                String[] newArgs;
12972                String name;
12973                if (opti >= args.length) {
12974                    name = null;
12975                    newArgs = EMPTY_STRING_ARRAY;
12976                } else {
12977                    name = args[opti];
12978                    opti++;
12979                    newArgs = new String[args.length - opti];
12980                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12981                            args.length - opti);
12982                }
12983                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12984                    pw.println("No services match: " + name);
12985                    pw.println("Use -h for help.");
12986                }
12987            } else if ("package".equals(cmd)) {
12988                String[] newArgs;
12989                if (opti >= args.length) {
12990                    pw.println("package: no package name specified");
12991                    pw.println("Use -h for help.");
12992                } else {
12993                    dumpPackage = args[opti];
12994                    opti++;
12995                    newArgs = new String[args.length - opti];
12996                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12997                            args.length - opti);
12998                    args = newArgs;
12999                    opti = 0;
13000                    more = true;
13001                }
13002            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13003                synchronized (this) {
13004                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13005                }
13006            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13007                synchronized (this) {
13008                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13009                }
13010            } else if ("write".equals(cmd)) {
13011                mTaskPersister.flush();
13012                pw.println("All tasks persisted.");
13013                return;
13014            } else if ("track-associations".equals(cmd)) {
13015                synchronized (this) {
13016                    if (!mTrackingAssociations) {
13017                        mTrackingAssociations = true;
13018                        pw.println("Association tracking started.");
13019                    } else {
13020                        pw.println("Association tracking already enabled.");
13021                    }
13022                }
13023                return;
13024            } else if ("untrack-associations".equals(cmd)) {
13025                synchronized (this) {
13026                    if (mTrackingAssociations) {
13027                        mTrackingAssociations = false;
13028                        mAssociations.clear();
13029                        pw.println("Association tracking stopped.");
13030                    } else {
13031                        pw.println("Association tracking not running.");
13032                    }
13033                }
13034                return;
13035            } else {
13036                // Dumping a single activity?
13037                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13038                    pw.println("Bad activity command, or no activities match: " + cmd);
13039                    pw.println("Use -h for help.");
13040                }
13041            }
13042            if (!more) {
13043                Binder.restoreCallingIdentity(origId);
13044                return;
13045            }
13046        }
13047
13048        // No piece of data specified, dump everything.
13049        synchronized (this) {
13050            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13051            pw.println();
13052            if (dumpAll) {
13053                pw.println("-------------------------------------------------------------------------------");
13054            }
13055            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13056            pw.println();
13057            if (dumpAll) {
13058                pw.println("-------------------------------------------------------------------------------");
13059            }
13060            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13061            pw.println();
13062            if (dumpAll) {
13063                pw.println("-------------------------------------------------------------------------------");
13064            }
13065            dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13066            pw.println();
13067            if (dumpAll) {
13068                pw.println("-------------------------------------------------------------------------------");
13069            }
13070            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13071            pw.println();
13072            if (dumpAll) {
13073                pw.println("-------------------------------------------------------------------------------");
13074            }
13075            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13076            pw.println();
13077            if (dumpAll) {
13078                pw.println("-------------------------------------------------------------------------------");
13079            }
13080            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13081            if (mAssociations.size() > 0) {
13082                pw.println();
13083                if (dumpAll) {
13084                    pw.println("-------------------------------------------------------------------------------");
13085                }
13086                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13087            }
13088            pw.println();
13089            if (dumpAll) {
13090                pw.println("-------------------------------------------------------------------------------");
13091            }
13092            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13093        }
13094        Binder.restoreCallingIdentity(origId);
13095    }
13096
13097    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13098            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13099        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13100
13101        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13102                dumpPackage);
13103        boolean needSep = printedAnything;
13104
13105        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13106                dumpPackage, needSep, "  mFocusedActivity: ");
13107        if (printed) {
13108            printedAnything = true;
13109            needSep = false;
13110        }
13111
13112        if (dumpPackage == null) {
13113            if (needSep) {
13114                pw.println();
13115            }
13116            needSep = true;
13117            printedAnything = true;
13118            mStackSupervisor.dump(pw, "  ");
13119        }
13120
13121        if (!printedAnything) {
13122            pw.println("  (nothing)");
13123        }
13124    }
13125
13126    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13127            int opti, boolean dumpAll, String dumpPackage) {
13128        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13129
13130        boolean printedAnything = false;
13131
13132        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13133            boolean printedHeader = false;
13134
13135            final int N = mRecentTasks.size();
13136            for (int i=0; i<N; i++) {
13137                TaskRecord tr = mRecentTasks.get(i);
13138                if (dumpPackage != null) {
13139                    if (tr.realActivity == null ||
13140                            !dumpPackage.equals(tr.realActivity)) {
13141                        continue;
13142                    }
13143                }
13144                if (!printedHeader) {
13145                    pw.println("  Recent tasks:");
13146                    printedHeader = true;
13147                    printedAnything = true;
13148                }
13149                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13150                        pw.println(tr);
13151                if (dumpAll) {
13152                    mRecentTasks.get(i).dump(pw, "    ");
13153                }
13154            }
13155        }
13156
13157        if (!printedAnything) {
13158            pw.println("  (nothing)");
13159        }
13160    }
13161
13162    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13163            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13164        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13165
13166        int dumpUid = 0;
13167        if (dumpPackage != null) {
13168            IPackageManager pm = AppGlobals.getPackageManager();
13169            try {
13170                dumpUid = pm.getPackageUid(dumpPackage, 0);
13171            } catch (RemoteException e) {
13172            }
13173        }
13174
13175        boolean printedAnything = false;
13176
13177        final long now = SystemClock.uptimeMillis();
13178
13179        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13180            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13181                    = mAssociations.valueAt(i1);
13182            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13183                SparseArray<ArrayMap<String, Association>> sourceUids
13184                        = targetComponents.valueAt(i2);
13185                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13186                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13187                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13188                        Association ass = sourceProcesses.valueAt(i4);
13189                        if (dumpPackage != null) {
13190                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13191                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13192                                continue;
13193                            }
13194                        }
13195                        printedAnything = true;
13196                        pw.print("  ");
13197                        pw.print(ass.mTargetProcess);
13198                        pw.print("/");
13199                        UserHandle.formatUid(pw, ass.mTargetUid);
13200                        pw.print(" <- ");
13201                        pw.print(ass.mSourceProcess);
13202                        pw.print("/");
13203                        UserHandle.formatUid(pw, ass.mSourceUid);
13204                        pw.println();
13205                        pw.print("    via ");
13206                        pw.print(ass.mTargetComponent.flattenToShortString());
13207                        pw.println();
13208                        pw.print("    ");
13209                        long dur = ass.mTime;
13210                        if (ass.mNesting > 0) {
13211                            dur += now - ass.mStartTime;
13212                        }
13213                        TimeUtils.formatDuration(dur, pw);
13214                        pw.print(" (");
13215                        pw.print(ass.mCount);
13216                        pw.println(" times)");
13217                        if (ass.mNesting > 0) {
13218                            pw.print("    ");
13219                            pw.print(" Currently active: ");
13220                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13221                            pw.println();
13222                        }
13223                    }
13224                }
13225            }
13226
13227        }
13228
13229        if (!printedAnything) {
13230            pw.println("  (nothing)");
13231        }
13232    }
13233
13234    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13235            int opti, boolean dumpAll, String dumpPackage) {
13236        boolean needSep = false;
13237        boolean printedAnything = false;
13238        int numPers = 0;
13239
13240        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13241
13242        if (dumpAll) {
13243            final int NP = mProcessNames.getMap().size();
13244            for (int ip=0; ip<NP; ip++) {
13245                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13246                final int NA = procs.size();
13247                for (int ia=0; ia<NA; ia++) {
13248                    ProcessRecord r = procs.valueAt(ia);
13249                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13250                        continue;
13251                    }
13252                    if (!needSep) {
13253                        pw.println("  All known processes:");
13254                        needSep = true;
13255                        printedAnything = true;
13256                    }
13257                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13258                        pw.print(" UID "); pw.print(procs.keyAt(ia));
13259                        pw.print(" "); pw.println(r);
13260                    r.dump(pw, "    ");
13261                    if (r.persistent) {
13262                        numPers++;
13263                    }
13264                }
13265            }
13266        }
13267
13268        if (mIsolatedProcesses.size() > 0) {
13269            boolean printed = false;
13270            for (int i=0; i<mIsolatedProcesses.size(); i++) {
13271                ProcessRecord r = mIsolatedProcesses.valueAt(i);
13272                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13273                    continue;
13274                }
13275                if (!printed) {
13276                    if (needSep) {
13277                        pw.println();
13278                    }
13279                    pw.println("  Isolated process list (sorted by uid):");
13280                    printedAnything = true;
13281                    printed = true;
13282                    needSep = true;
13283                }
13284                pw.println(String.format("%sIsolated #%2d: %s",
13285                        "    ", i, r.toString()));
13286            }
13287        }
13288
13289        if (mActiveUids.size() > 0) {
13290            if (needSep) {
13291                pw.println();
13292            }
13293            pw.println("  UID states:");
13294            for (int i=0; i<mActiveUids.size(); i++) {
13295                UidRecord uidRec = mActiveUids.valueAt(i);
13296                pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13297                pw.print(": "); pw.println(uidRec);
13298            }
13299            needSep = true;
13300            printedAnything = true;
13301        }
13302
13303        if (mLruProcesses.size() > 0) {
13304            if (needSep) {
13305                pw.println();
13306            }
13307            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
13308                    pw.print(" total, non-act at ");
13309                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13310                    pw.print(", non-svc at ");
13311                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13312                    pw.println("):");
13313            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
13314            needSep = true;
13315            printedAnything = true;
13316        }
13317
13318        if (dumpAll || dumpPackage != null) {
13319            synchronized (mPidsSelfLocked) {
13320                boolean printed = false;
13321                for (int i=0; i<mPidsSelfLocked.size(); i++) {
13322                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
13323                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13324                        continue;
13325                    }
13326                    if (!printed) {
13327                        if (needSep) pw.println();
13328                        needSep = true;
13329                        pw.println("  PID mappings:");
13330                        printed = true;
13331                        printedAnything = true;
13332                    }
13333                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
13334                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
13335                }
13336            }
13337        }
13338
13339        if (mForegroundProcesses.size() > 0) {
13340            synchronized (mPidsSelfLocked) {
13341                boolean printed = false;
13342                for (int i=0; i<mForegroundProcesses.size(); i++) {
13343                    ProcessRecord r = mPidsSelfLocked.get(
13344                            mForegroundProcesses.valueAt(i).pid);
13345                    if (dumpPackage != null && (r == null
13346                            || !r.pkgList.containsKey(dumpPackage))) {
13347                        continue;
13348                    }
13349                    if (!printed) {
13350                        if (needSep) pw.println();
13351                        needSep = true;
13352                        pw.println("  Foreground Processes:");
13353                        printed = true;
13354                        printedAnything = true;
13355                    }
13356                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
13357                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
13358                }
13359            }
13360        }
13361
13362        if (mPersistentStartingProcesses.size() > 0) {
13363            if (needSep) pw.println();
13364            needSep = true;
13365            printedAnything = true;
13366            pw.println("  Persisent processes that are starting:");
13367            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
13368                    "Starting Norm", "Restarting PERS", dumpPackage);
13369        }
13370
13371        if (mRemovedProcesses.size() > 0) {
13372            if (needSep) pw.println();
13373            needSep = true;
13374            printedAnything = true;
13375            pw.println("  Processes that are being removed:");
13376            dumpProcessList(pw, this, mRemovedProcesses, "    ",
13377                    "Removed Norm", "Removed PERS", dumpPackage);
13378        }
13379
13380        if (mProcessesOnHold.size() > 0) {
13381            if (needSep) pw.println();
13382            needSep = true;
13383            printedAnything = true;
13384            pw.println("  Processes that are on old until the system is ready:");
13385            dumpProcessList(pw, this, mProcessesOnHold, "    ",
13386                    "OnHold Norm", "OnHold PERS", dumpPackage);
13387        }
13388
13389        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
13390
13391        if (mProcessCrashTimes.getMap().size() > 0) {
13392            boolean printed = false;
13393            long now = SystemClock.uptimeMillis();
13394            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
13395            final int NP = pmap.size();
13396            for (int ip=0; ip<NP; ip++) {
13397                String pname = pmap.keyAt(ip);
13398                SparseArray<Long> uids = pmap.valueAt(ip);
13399                final int N = uids.size();
13400                for (int i=0; i<N; i++) {
13401                    int puid = uids.keyAt(i);
13402                    ProcessRecord r = mProcessNames.get(pname, puid);
13403                    if (dumpPackage != null && (r == null
13404                            || !r.pkgList.containsKey(dumpPackage))) {
13405                        continue;
13406                    }
13407                    if (!printed) {
13408                        if (needSep) pw.println();
13409                        needSep = true;
13410                        pw.println("  Time since processes crashed:");
13411                        printed = true;
13412                        printedAnything = true;
13413                    }
13414                    pw.print("    Process "); pw.print(pname);
13415                            pw.print(" uid "); pw.print(puid);
13416                            pw.print(": last crashed ");
13417                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
13418                            pw.println(" ago");
13419                }
13420            }
13421        }
13422
13423        if (mBadProcesses.getMap().size() > 0) {
13424            boolean printed = false;
13425            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
13426            final int NP = pmap.size();
13427            for (int ip=0; ip<NP; ip++) {
13428                String pname = pmap.keyAt(ip);
13429                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
13430                final int N = uids.size();
13431                for (int i=0; i<N; i++) {
13432                    int puid = uids.keyAt(i);
13433                    ProcessRecord r = mProcessNames.get(pname, puid);
13434                    if (dumpPackage != null && (r == null
13435                            || !r.pkgList.containsKey(dumpPackage))) {
13436                        continue;
13437                    }
13438                    if (!printed) {
13439                        if (needSep) pw.println();
13440                        needSep = true;
13441                        pw.println("  Bad processes:");
13442                        printedAnything = true;
13443                    }
13444                    BadProcessInfo info = uids.valueAt(i);
13445                    pw.print("    Bad process "); pw.print(pname);
13446                            pw.print(" uid "); pw.print(puid);
13447                            pw.print(": crashed at time "); pw.println(info.time);
13448                    if (info.shortMsg != null) {
13449                        pw.print("      Short msg: "); pw.println(info.shortMsg);
13450                    }
13451                    if (info.longMsg != null) {
13452                        pw.print("      Long msg: "); pw.println(info.longMsg);
13453                    }
13454                    if (info.stack != null) {
13455                        pw.println("      Stack:");
13456                        int lastPos = 0;
13457                        for (int pos=0; pos<info.stack.length(); pos++) {
13458                            if (info.stack.charAt(pos) == '\n') {
13459                                pw.print("        ");
13460                                pw.write(info.stack, lastPos, pos-lastPos);
13461                                pw.println();
13462                                lastPos = pos+1;
13463                            }
13464                        }
13465                        if (lastPos < info.stack.length()) {
13466                            pw.print("        ");
13467                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
13468                            pw.println();
13469                        }
13470                    }
13471                }
13472            }
13473        }
13474
13475        if (dumpPackage == null) {
13476            pw.println();
13477            needSep = false;
13478            pw.println("  mStartedUsers:");
13479            for (int i=0; i<mStartedUsers.size(); i++) {
13480                UserState uss = mStartedUsers.valueAt(i);
13481                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
13482                        pw.print(": "); uss.dump("", pw);
13483            }
13484            pw.print("  mStartedUserArray: [");
13485            for (int i=0; i<mStartedUserArray.length; i++) {
13486                if (i > 0) pw.print(", ");
13487                pw.print(mStartedUserArray[i]);
13488            }
13489            pw.println("]");
13490            pw.print("  mUserLru: [");
13491            for (int i=0; i<mUserLru.size(); i++) {
13492                if (i > 0) pw.print(", ");
13493                pw.print(mUserLru.get(i));
13494            }
13495            pw.println("]");
13496            if (dumpAll) {
13497                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
13498            }
13499            synchronized (mUserProfileGroupIdsSelfLocked) {
13500                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
13501                    pw.println("  mUserProfileGroupIds:");
13502                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
13503                        pw.print("    User #");
13504                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
13505                        pw.print(" -> profile #");
13506                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
13507                    }
13508                }
13509            }
13510        }
13511        if (mHomeProcess != null && (dumpPackage == null
13512                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13513            if (needSep) {
13514                pw.println();
13515                needSep = false;
13516            }
13517            pw.println("  mHomeProcess: " + mHomeProcess);
13518        }
13519        if (mPreviousProcess != null && (dumpPackage == null
13520                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13521            if (needSep) {
13522                pw.println();
13523                needSep = false;
13524            }
13525            pw.println("  mPreviousProcess: " + mPreviousProcess);
13526        }
13527        if (dumpAll) {
13528            StringBuilder sb = new StringBuilder(128);
13529            sb.append("  mPreviousProcessVisibleTime: ");
13530            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13531            pw.println(sb);
13532        }
13533        if (mHeavyWeightProcess != null && (dumpPackage == null
13534                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13535            if (needSep) {
13536                pw.println();
13537                needSep = false;
13538            }
13539            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13540        }
13541        if (dumpPackage == null) {
13542            pw.println("  mConfiguration: " + mConfiguration);
13543        }
13544        if (dumpAll) {
13545            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13546            if (mCompatModePackages.getPackages().size() > 0) {
13547                boolean printed = false;
13548                for (Map.Entry<String, Integer> entry
13549                        : mCompatModePackages.getPackages().entrySet()) {
13550                    String pkg = entry.getKey();
13551                    int mode = entry.getValue();
13552                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
13553                        continue;
13554                    }
13555                    if (!printed) {
13556                        pw.println("  mScreenCompatPackages:");
13557                        printed = true;
13558                    }
13559                    pw.print("    "); pw.print(pkg); pw.print(": ");
13560                            pw.print(mode); pw.println();
13561                }
13562            }
13563        }
13564        if (dumpPackage == null) {
13565            pw.println("  mWakefulness="
13566                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
13567            pw.println("  mSleepTokens=" + mSleepTokens);
13568            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
13569                    + lockScreenShownToString());
13570            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
13571            if (mRunningVoice != null) {
13572                pw.println("  mRunningVoice=" + mRunningVoice);
13573                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
13574            }
13575        }
13576        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
13577                || mOrigWaitForDebugger) {
13578            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
13579                    || dumpPackage.equals(mOrigDebugApp)) {
13580                if (needSep) {
13581                    pw.println();
13582                    needSep = false;
13583                }
13584                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
13585                        + " mDebugTransient=" + mDebugTransient
13586                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
13587            }
13588        }
13589        if (mCurAppTimeTracker != null) {
13590            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
13591        }
13592        if (mMemWatchProcesses.getMap().size() > 0) {
13593            pw.println("  Mem watch processes:");
13594            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
13595                    = mMemWatchProcesses.getMap();
13596            for (int i=0; i<procs.size(); i++) {
13597                final String proc = procs.keyAt(i);
13598                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
13599                for (int j=0; j<uids.size(); j++) {
13600                    if (needSep) {
13601                        pw.println();
13602                        needSep = false;
13603                    }
13604                    StringBuilder sb = new StringBuilder();
13605                    sb.append("    ").append(proc).append('/');
13606                    UserHandle.formatUid(sb, uids.keyAt(j));
13607                    Pair<Long, String> val = uids.valueAt(j);
13608                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
13609                    if (val.second != null) {
13610                        sb.append(", report to ").append(val.second);
13611                    }
13612                    pw.println(sb.toString());
13613                }
13614            }
13615            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
13616            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
13617            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
13618                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
13619        }
13620        if (mOpenGlTraceApp != null) {
13621            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
13622                if (needSep) {
13623                    pw.println();
13624                    needSep = false;
13625                }
13626                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
13627            }
13628        }
13629        if (mTrackAllocationApp != null) {
13630            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
13631                if (needSep) {
13632                    pw.println();
13633                    needSep = false;
13634                }
13635                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
13636            }
13637        }
13638        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
13639                || mProfileFd != null) {
13640            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13641                if (needSep) {
13642                    pw.println();
13643                    needSep = false;
13644                }
13645                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13646                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13647                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13648                        + mAutoStopProfiler);
13649                pw.println("  mProfileType=" + mProfileType);
13650            }
13651        }
13652        if (dumpPackage == null) {
13653            if (mAlwaysFinishActivities || mController != null) {
13654                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
13655                        + " mController=" + mController);
13656            }
13657            if (dumpAll) {
13658                pw.println("  Total persistent processes: " + numPers);
13659                pw.println("  mProcessesReady=" + mProcessesReady
13660                        + " mSystemReady=" + mSystemReady
13661                        + " mBooted=" + mBooted
13662                        + " mFactoryTest=" + mFactoryTest);
13663                pw.println("  mBooting=" + mBooting
13664                        + " mCallFinishBooting=" + mCallFinishBooting
13665                        + " mBootAnimationComplete=" + mBootAnimationComplete);
13666                pw.print("  mLastPowerCheckRealtime=");
13667                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13668                        pw.println("");
13669                pw.print("  mLastPowerCheckUptime=");
13670                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13671                        pw.println("");
13672                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13673                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13674                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13675                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
13676                        + " (" + mLruProcesses.size() + " total)"
13677                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13678                        + " mNumServiceProcs=" + mNumServiceProcs
13679                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13680                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
13681                        + " mLastMemoryLevel" + mLastMemoryLevel
13682                        + " mLastNumProcesses" + mLastNumProcesses);
13683                long now = SystemClock.uptimeMillis();
13684                pw.print("  mLastIdleTime=");
13685                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
13686                        pw.print(" mLowRamSinceLastIdle=");
13687                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13688                        pw.println();
13689            }
13690        }
13691
13692        if (!printedAnything) {
13693            pw.println("  (nothing)");
13694        }
13695    }
13696
13697    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13698            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13699        if (mProcessesToGc.size() > 0) {
13700            boolean printed = false;
13701            long now = SystemClock.uptimeMillis();
13702            for (int i=0; i<mProcessesToGc.size(); i++) {
13703                ProcessRecord proc = mProcessesToGc.get(i);
13704                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13705                    continue;
13706                }
13707                if (!printed) {
13708                    if (needSep) pw.println();
13709                    needSep = true;
13710                    pw.println("  Processes that are waiting to GC:");
13711                    printed = true;
13712                }
13713                pw.print("    Process "); pw.println(proc);
13714                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13715                        pw.print(", last gced=");
13716                        pw.print(now-proc.lastRequestedGc);
13717                        pw.print(" ms ago, last lowMem=");
13718                        pw.print(now-proc.lastLowMemory);
13719                        pw.println(" ms ago");
13720
13721            }
13722        }
13723        return needSep;
13724    }
13725
13726    void printOomLevel(PrintWriter pw, String name, int adj) {
13727        pw.print("    ");
13728        if (adj >= 0) {
13729            pw.print(' ');
13730            if (adj < 10) pw.print(' ');
13731        } else {
13732            if (adj > -10) pw.print(' ');
13733        }
13734        pw.print(adj);
13735        pw.print(": ");
13736        pw.print(name);
13737        pw.print(" (");
13738        pw.print(mProcessList.getMemLevel(adj)/1024);
13739        pw.println(" kB)");
13740    }
13741
13742    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13743            int opti, boolean dumpAll) {
13744        boolean needSep = false;
13745
13746        if (mLruProcesses.size() > 0) {
13747            if (needSep) pw.println();
13748            needSep = true;
13749            pw.println("  OOM levels:");
13750            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13751            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13752            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13753            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13754            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13755            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13756            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13757            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13758            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13759            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13760            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13761            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13762            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13763            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13764
13765            if (needSep) pw.println();
13766            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13767                    pw.print(" total, non-act at ");
13768                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13769                    pw.print(", non-svc at ");
13770                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13771                    pw.println("):");
13772            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13773            needSep = true;
13774        }
13775
13776        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13777
13778        pw.println();
13779        pw.println("  mHomeProcess: " + mHomeProcess);
13780        pw.println("  mPreviousProcess: " + mPreviousProcess);
13781        if (mHeavyWeightProcess != null) {
13782            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13783        }
13784
13785        return true;
13786    }
13787
13788    /**
13789     * There are three ways to call this:
13790     *  - no provider specified: dump all the providers
13791     *  - a flattened component name that matched an existing provider was specified as the
13792     *    first arg: dump that one provider
13793     *  - the first arg isn't the flattened component name of an existing provider:
13794     *    dump all providers whose component contains the first arg as a substring
13795     */
13796    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13797            int opti, boolean dumpAll) {
13798        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13799    }
13800
13801    static class ItemMatcher {
13802        ArrayList<ComponentName> components;
13803        ArrayList<String> strings;
13804        ArrayList<Integer> objects;
13805        boolean all;
13806
13807        ItemMatcher() {
13808            all = true;
13809        }
13810
13811        void build(String name) {
13812            ComponentName componentName = ComponentName.unflattenFromString(name);
13813            if (componentName != null) {
13814                if (components == null) {
13815                    components = new ArrayList<ComponentName>();
13816                }
13817                components.add(componentName);
13818                all = false;
13819            } else {
13820                int objectId = 0;
13821                // Not a '/' separated full component name; maybe an object ID?
13822                try {
13823                    objectId = Integer.parseInt(name, 16);
13824                    if (objects == null) {
13825                        objects = new ArrayList<Integer>();
13826                    }
13827                    objects.add(objectId);
13828                    all = false;
13829                } catch (RuntimeException e) {
13830                    // Not an integer; just do string match.
13831                    if (strings == null) {
13832                        strings = new ArrayList<String>();
13833                    }
13834                    strings.add(name);
13835                    all = false;
13836                }
13837            }
13838        }
13839
13840        int build(String[] args, int opti) {
13841            for (; opti<args.length; opti++) {
13842                String name = args[opti];
13843                if ("--".equals(name)) {
13844                    return opti+1;
13845                }
13846                build(name);
13847            }
13848            return opti;
13849        }
13850
13851        boolean match(Object object, ComponentName comp) {
13852            if (all) {
13853                return true;
13854            }
13855            if (components != null) {
13856                for (int i=0; i<components.size(); i++) {
13857                    if (components.get(i).equals(comp)) {
13858                        return true;
13859                    }
13860                }
13861            }
13862            if (objects != null) {
13863                for (int i=0; i<objects.size(); i++) {
13864                    if (System.identityHashCode(object) == objects.get(i)) {
13865                        return true;
13866                    }
13867                }
13868            }
13869            if (strings != null) {
13870                String flat = comp.flattenToString();
13871                for (int i=0; i<strings.size(); i++) {
13872                    if (flat.contains(strings.get(i))) {
13873                        return true;
13874                    }
13875                }
13876            }
13877            return false;
13878        }
13879    }
13880
13881    /**
13882     * There are three things that cmd can be:
13883     *  - a flattened component name that matches an existing activity
13884     *  - the cmd arg isn't the flattened component name of an existing activity:
13885     *    dump all activity whose component contains the cmd as a substring
13886     *  - A hex number of the ActivityRecord object instance.
13887     */
13888    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13889            int opti, boolean dumpAll) {
13890        ArrayList<ActivityRecord> activities;
13891
13892        synchronized (this) {
13893            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13894        }
13895
13896        if (activities.size() <= 0) {
13897            return false;
13898        }
13899
13900        String[] newArgs = new String[args.length - opti];
13901        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13902
13903        TaskRecord lastTask = null;
13904        boolean needSep = false;
13905        for (int i=activities.size()-1; i>=0; i--) {
13906            ActivityRecord r = activities.get(i);
13907            if (needSep) {
13908                pw.println();
13909            }
13910            needSep = true;
13911            synchronized (this) {
13912                if (lastTask != r.task) {
13913                    lastTask = r.task;
13914                    pw.print("TASK "); pw.print(lastTask.affinity);
13915                            pw.print(" id="); pw.println(lastTask.taskId);
13916                    if (dumpAll) {
13917                        lastTask.dump(pw, "  ");
13918                    }
13919                }
13920            }
13921            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13922        }
13923        return true;
13924    }
13925
13926    /**
13927     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13928     * there is a thread associated with the activity.
13929     */
13930    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13931            final ActivityRecord r, String[] args, boolean dumpAll) {
13932        String innerPrefix = prefix + "  ";
13933        synchronized (this) {
13934            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13935                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13936                    pw.print(" pid=");
13937                    if (r.app != null) pw.println(r.app.pid);
13938                    else pw.println("(not running)");
13939            if (dumpAll) {
13940                r.dump(pw, innerPrefix);
13941            }
13942        }
13943        if (r.app != null && r.app.thread != null) {
13944            // flush anything that is already in the PrintWriter since the thread is going
13945            // to write to the file descriptor directly
13946            pw.flush();
13947            try {
13948                TransferPipe tp = new TransferPipe();
13949                try {
13950                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13951                            r.appToken, innerPrefix, args);
13952                    tp.go(fd);
13953                } finally {
13954                    tp.kill();
13955                }
13956            } catch (IOException e) {
13957                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13958            } catch (RemoteException e) {
13959                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13960            }
13961        }
13962    }
13963
13964    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13965            int opti, boolean dumpAll, String dumpPackage) {
13966        boolean needSep = false;
13967        boolean onlyHistory = false;
13968        boolean printedAnything = false;
13969
13970        if ("history".equals(dumpPackage)) {
13971            if (opti < args.length && "-s".equals(args[opti])) {
13972                dumpAll = false;
13973            }
13974            onlyHistory = true;
13975            dumpPackage = null;
13976        }
13977
13978        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13979        if (!onlyHistory && dumpAll) {
13980            if (mRegisteredReceivers.size() > 0) {
13981                boolean printed = false;
13982                Iterator it = mRegisteredReceivers.values().iterator();
13983                while (it.hasNext()) {
13984                    ReceiverList r = (ReceiverList)it.next();
13985                    if (dumpPackage != null && (r.app == null ||
13986                            !dumpPackage.equals(r.app.info.packageName))) {
13987                        continue;
13988                    }
13989                    if (!printed) {
13990                        pw.println("  Registered Receivers:");
13991                        needSep = true;
13992                        printed = true;
13993                        printedAnything = true;
13994                    }
13995                    pw.print("  * "); pw.println(r);
13996                    r.dump(pw, "    ");
13997                }
13998            }
13999
14000            if (mReceiverResolver.dump(pw, needSep ?
14001                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14002                    "    ", dumpPackage, false, false)) {
14003                needSep = true;
14004                printedAnything = true;
14005            }
14006        }
14007
14008        for (BroadcastQueue q : mBroadcastQueues) {
14009            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14010            printedAnything |= needSep;
14011        }
14012
14013        needSep = true;
14014
14015        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14016            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14017                if (needSep) {
14018                    pw.println();
14019                }
14020                needSep = true;
14021                printedAnything = true;
14022                pw.print("  Sticky broadcasts for user ");
14023                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14024                StringBuilder sb = new StringBuilder(128);
14025                for (Map.Entry<String, ArrayList<Intent>> ent
14026                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14027                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14028                    if (dumpAll) {
14029                        pw.println(":");
14030                        ArrayList<Intent> intents = ent.getValue();
14031                        final int N = intents.size();
14032                        for (int i=0; i<N; i++) {
14033                            sb.setLength(0);
14034                            sb.append("    Intent: ");
14035                            intents.get(i).toShortString(sb, false, true, false, false);
14036                            pw.println(sb.toString());
14037                            Bundle bundle = intents.get(i).getExtras();
14038                            if (bundle != null) {
14039                                pw.print("      ");
14040                                pw.println(bundle.toString());
14041                            }
14042                        }
14043                    } else {
14044                        pw.println("");
14045                    }
14046                }
14047            }
14048        }
14049
14050        if (!onlyHistory && dumpAll) {
14051            pw.println();
14052            for (BroadcastQueue queue : mBroadcastQueues) {
14053                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14054                        + queue.mBroadcastsScheduled);
14055            }
14056            pw.println("  mHandler:");
14057            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14058            needSep = true;
14059            printedAnything = true;
14060        }
14061
14062        if (!printedAnything) {
14063            pw.println("  (nothing)");
14064        }
14065    }
14066
14067    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14068            int opti, boolean dumpAll, String dumpPackage) {
14069        boolean needSep;
14070        boolean printedAnything = false;
14071
14072        ItemMatcher matcher = new ItemMatcher();
14073        matcher.build(args, opti);
14074
14075        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14076
14077        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14078        printedAnything |= needSep;
14079
14080        if (mLaunchingProviders.size() > 0) {
14081            boolean printed = false;
14082            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14083                ContentProviderRecord r = mLaunchingProviders.get(i);
14084                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14085                    continue;
14086                }
14087                if (!printed) {
14088                    if (needSep) pw.println();
14089                    needSep = true;
14090                    pw.println("  Launching content providers:");
14091                    printed = true;
14092                    printedAnything = true;
14093                }
14094                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14095                        pw.println(r);
14096            }
14097        }
14098
14099        if (!printedAnything) {
14100            pw.println("  (nothing)");
14101        }
14102    }
14103
14104    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14105            int opti, boolean dumpAll, String dumpPackage) {
14106        boolean needSep = false;
14107        boolean printedAnything = false;
14108
14109        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14110
14111        if (mGrantedUriPermissions.size() > 0) {
14112            boolean printed = false;
14113            int dumpUid = -2;
14114            if (dumpPackage != null) {
14115                try {
14116                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
14117                } catch (NameNotFoundException e) {
14118                    dumpUid = -1;
14119                }
14120            }
14121            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14122                int uid = mGrantedUriPermissions.keyAt(i);
14123                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14124                    continue;
14125                }
14126                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14127                if (!printed) {
14128                    if (needSep) pw.println();
14129                    needSep = true;
14130                    pw.println("  Granted Uri Permissions:");
14131                    printed = true;
14132                    printedAnything = true;
14133                }
14134                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14135                for (UriPermission perm : perms.values()) {
14136                    pw.print("    "); pw.println(perm);
14137                    if (dumpAll) {
14138                        perm.dump(pw, "      ");
14139                    }
14140                }
14141            }
14142        }
14143
14144        if (!printedAnything) {
14145            pw.println("  (nothing)");
14146        }
14147    }
14148
14149    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14150            int opti, boolean dumpAll, String dumpPackage) {
14151        boolean printed = false;
14152
14153        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14154
14155        if (mIntentSenderRecords.size() > 0) {
14156            Iterator<WeakReference<PendingIntentRecord>> it
14157                    = mIntentSenderRecords.values().iterator();
14158            while (it.hasNext()) {
14159                WeakReference<PendingIntentRecord> ref = it.next();
14160                PendingIntentRecord rec = ref != null ? ref.get(): null;
14161                if (dumpPackage != null && (rec == null
14162                        || !dumpPackage.equals(rec.key.packageName))) {
14163                    continue;
14164                }
14165                printed = true;
14166                if (rec != null) {
14167                    pw.print("  * "); pw.println(rec);
14168                    if (dumpAll) {
14169                        rec.dump(pw, "    ");
14170                    }
14171                } else {
14172                    pw.print("  * "); pw.println(ref);
14173                }
14174            }
14175        }
14176
14177        if (!printed) {
14178            pw.println("  (nothing)");
14179        }
14180    }
14181
14182    private static final int dumpProcessList(PrintWriter pw,
14183            ActivityManagerService service, List list,
14184            String prefix, String normalLabel, String persistentLabel,
14185            String dumpPackage) {
14186        int numPers = 0;
14187        final int N = list.size()-1;
14188        for (int i=N; i>=0; i--) {
14189            ProcessRecord r = (ProcessRecord)list.get(i);
14190            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14191                continue;
14192            }
14193            pw.println(String.format("%s%s #%2d: %s",
14194                    prefix, (r.persistent ? persistentLabel : normalLabel),
14195                    i, r.toString()));
14196            if (r.persistent) {
14197                numPers++;
14198            }
14199        }
14200        return numPers;
14201    }
14202
14203    private static final boolean dumpProcessOomList(PrintWriter pw,
14204            ActivityManagerService service, List<ProcessRecord> origList,
14205            String prefix, String normalLabel, String persistentLabel,
14206            boolean inclDetails, String dumpPackage) {
14207
14208        ArrayList<Pair<ProcessRecord, Integer>> list
14209                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14210        for (int i=0; i<origList.size(); i++) {
14211            ProcessRecord r = origList.get(i);
14212            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14213                continue;
14214            }
14215            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14216        }
14217
14218        if (list.size() <= 0) {
14219            return false;
14220        }
14221
14222        Comparator<Pair<ProcessRecord, Integer>> comparator
14223                = new Comparator<Pair<ProcessRecord, Integer>>() {
14224            @Override
14225            public int compare(Pair<ProcessRecord, Integer> object1,
14226                    Pair<ProcessRecord, Integer> object2) {
14227                if (object1.first.setAdj != object2.first.setAdj) {
14228                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14229                }
14230                if (object1.second.intValue() != object2.second.intValue()) {
14231                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14232                }
14233                return 0;
14234            }
14235        };
14236
14237        Collections.sort(list, comparator);
14238
14239        final long curRealtime = SystemClock.elapsedRealtime();
14240        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14241        final long curUptime = SystemClock.uptimeMillis();
14242        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14243
14244        for (int i=list.size()-1; i>=0; i--) {
14245            ProcessRecord r = list.get(i).first;
14246            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14247            char schedGroup;
14248            switch (r.setSchedGroup) {
14249                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
14250                    schedGroup = 'B';
14251                    break;
14252                case Process.THREAD_GROUP_DEFAULT:
14253                    schedGroup = 'F';
14254                    break;
14255                default:
14256                    schedGroup = '?';
14257                    break;
14258            }
14259            char foreground;
14260            if (r.foregroundActivities) {
14261                foreground = 'A';
14262            } else if (r.foregroundServices) {
14263                foreground = 'S';
14264            } else {
14265                foreground = ' ';
14266            }
14267            String procState = ProcessList.makeProcStateString(r.curProcState);
14268            pw.print(prefix);
14269            pw.print(r.persistent ? persistentLabel : normalLabel);
14270            pw.print(" #");
14271            int num = (origList.size()-1)-list.get(i).second;
14272            if (num < 10) pw.print(' ');
14273            pw.print(num);
14274            pw.print(": ");
14275            pw.print(oomAdj);
14276            pw.print(' ');
14277            pw.print(schedGroup);
14278            pw.print('/');
14279            pw.print(foreground);
14280            pw.print('/');
14281            pw.print(procState);
14282            pw.print(" trm:");
14283            if (r.trimMemoryLevel < 10) pw.print(' ');
14284            pw.print(r.trimMemoryLevel);
14285            pw.print(' ');
14286            pw.print(r.toShortString());
14287            pw.print(" (");
14288            pw.print(r.adjType);
14289            pw.println(')');
14290            if (r.adjSource != null || r.adjTarget != null) {
14291                pw.print(prefix);
14292                pw.print("    ");
14293                if (r.adjTarget instanceof ComponentName) {
14294                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14295                } else if (r.adjTarget != null) {
14296                    pw.print(r.adjTarget.toString());
14297                } else {
14298                    pw.print("{null}");
14299                }
14300                pw.print("<=");
14301                if (r.adjSource instanceof ProcessRecord) {
14302                    pw.print("Proc{");
14303                    pw.print(((ProcessRecord)r.adjSource).toShortString());
14304                    pw.println("}");
14305                } else if (r.adjSource != null) {
14306                    pw.println(r.adjSource.toString());
14307                } else {
14308                    pw.println("{null}");
14309                }
14310            }
14311            if (inclDetails) {
14312                pw.print(prefix);
14313                pw.print("    ");
14314                pw.print("oom: max="); pw.print(r.maxAdj);
14315                pw.print(" curRaw="); pw.print(r.curRawAdj);
14316                pw.print(" setRaw="); pw.print(r.setRawAdj);
14317                pw.print(" cur="); pw.print(r.curAdj);
14318                pw.print(" set="); pw.println(r.setAdj);
14319                pw.print(prefix);
14320                pw.print("    ");
14321                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14322                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14323                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14324                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14325                pw.println();
14326                pw.print(prefix);
14327                pw.print("    ");
14328                pw.print("cached="); pw.print(r.cached);
14329                pw.print(" empty="); pw.print(r.empty);
14330                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14331
14332                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14333                    if (r.lastWakeTime != 0) {
14334                        long wtime;
14335                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14336                        synchronized (stats) {
14337                            wtime = stats.getProcessWakeTime(r.info.uid,
14338                                    r.pid, curRealtime);
14339                        }
14340                        long timeUsed = wtime - r.lastWakeTime;
14341                        pw.print(prefix);
14342                        pw.print("    ");
14343                        pw.print("keep awake over ");
14344                        TimeUtils.formatDuration(realtimeSince, pw);
14345                        pw.print(" used ");
14346                        TimeUtils.formatDuration(timeUsed, pw);
14347                        pw.print(" (");
14348                        pw.print((timeUsed*100)/realtimeSince);
14349                        pw.println("%)");
14350                    }
14351                    if (r.lastCpuTime != 0) {
14352                        long timeUsed = r.curCpuTime - r.lastCpuTime;
14353                        pw.print(prefix);
14354                        pw.print("    ");
14355                        pw.print("run cpu over ");
14356                        TimeUtils.formatDuration(uptimeSince, pw);
14357                        pw.print(" used ");
14358                        TimeUtils.formatDuration(timeUsed, pw);
14359                        pw.print(" (");
14360                        pw.print((timeUsed*100)/uptimeSince);
14361                        pw.println("%)");
14362                    }
14363                }
14364            }
14365        }
14366        return true;
14367    }
14368
14369    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14370            String[] args) {
14371        ArrayList<ProcessRecord> procs;
14372        synchronized (this) {
14373            if (args != null && args.length > start
14374                    && args[start].charAt(0) != '-') {
14375                procs = new ArrayList<ProcessRecord>();
14376                int pid = -1;
14377                try {
14378                    pid = Integer.parseInt(args[start]);
14379                } catch (NumberFormatException e) {
14380                }
14381                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14382                    ProcessRecord proc = mLruProcesses.get(i);
14383                    if (proc.pid == pid) {
14384                        procs.add(proc);
14385                    } else if (allPkgs && proc.pkgList != null
14386                            && proc.pkgList.containsKey(args[start])) {
14387                        procs.add(proc);
14388                    } else if (proc.processName.equals(args[start])) {
14389                        procs.add(proc);
14390                    }
14391                }
14392                if (procs.size() <= 0) {
14393                    return null;
14394                }
14395            } else {
14396                procs = new ArrayList<ProcessRecord>(mLruProcesses);
14397            }
14398        }
14399        return procs;
14400    }
14401
14402    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
14403            PrintWriter pw, String[] args) {
14404        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14405        if (procs == null) {
14406            pw.println("No process found for: " + args[0]);
14407            return;
14408        }
14409
14410        long uptime = SystemClock.uptimeMillis();
14411        long realtime = SystemClock.elapsedRealtime();
14412        pw.println("Applications Graphics Acceleration Info:");
14413        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14414
14415        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14416            ProcessRecord r = procs.get(i);
14417            if (r.thread != null) {
14418                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
14419                pw.flush();
14420                try {
14421                    TransferPipe tp = new TransferPipe();
14422                    try {
14423                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
14424                        tp.go(fd);
14425                    } finally {
14426                        tp.kill();
14427                    }
14428                } catch (IOException e) {
14429                    pw.println("Failure while dumping the app: " + r);
14430                    pw.flush();
14431                } catch (RemoteException e) {
14432                    pw.println("Got a RemoteException while dumping the app " + r);
14433                    pw.flush();
14434                }
14435            }
14436        }
14437    }
14438
14439    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
14440        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14441        if (procs == null) {
14442            pw.println("No process found for: " + args[0]);
14443            return;
14444        }
14445
14446        pw.println("Applications Database Info:");
14447
14448        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14449            ProcessRecord r = procs.get(i);
14450            if (r.thread != null) {
14451                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
14452                pw.flush();
14453                try {
14454                    TransferPipe tp = new TransferPipe();
14455                    try {
14456                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
14457                        tp.go(fd);
14458                    } finally {
14459                        tp.kill();
14460                    }
14461                } catch (IOException e) {
14462                    pw.println("Failure while dumping the app: " + r);
14463                    pw.flush();
14464                } catch (RemoteException e) {
14465                    pw.println("Got a RemoteException while dumping the app " + r);
14466                    pw.flush();
14467                }
14468            }
14469        }
14470    }
14471
14472    final static class MemItem {
14473        final boolean isProc;
14474        final String label;
14475        final String shortLabel;
14476        final long pss;
14477        final int id;
14478        final boolean hasActivities;
14479        ArrayList<MemItem> subitems;
14480
14481        public MemItem(String _label, String _shortLabel, long _pss, int _id,
14482                boolean _hasActivities) {
14483            isProc = true;
14484            label = _label;
14485            shortLabel = _shortLabel;
14486            pss = _pss;
14487            id = _id;
14488            hasActivities = _hasActivities;
14489        }
14490
14491        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
14492            isProc = false;
14493            label = _label;
14494            shortLabel = _shortLabel;
14495            pss = _pss;
14496            id = _id;
14497            hasActivities = false;
14498        }
14499    }
14500
14501    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
14502            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
14503        if (sort && !isCompact) {
14504            Collections.sort(items, new Comparator<MemItem>() {
14505                @Override
14506                public int compare(MemItem lhs, MemItem rhs) {
14507                    if (lhs.pss < rhs.pss) {
14508                        return 1;
14509                    } else if (lhs.pss > rhs.pss) {
14510                        return -1;
14511                    }
14512                    return 0;
14513                }
14514            });
14515        }
14516
14517        for (int i=0; i<items.size(); i++) {
14518            MemItem mi = items.get(i);
14519            if (!isCompact) {
14520                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
14521            } else if (mi.isProc) {
14522                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
14523                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
14524                pw.println(mi.hasActivities ? ",a" : ",e");
14525            } else {
14526                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
14527                pw.println(mi.pss);
14528            }
14529            if (mi.subitems != null) {
14530                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
14531                        true, isCompact);
14532            }
14533        }
14534    }
14535
14536    // These are in KB.
14537    static final long[] DUMP_MEM_BUCKETS = new long[] {
14538        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
14539        120*1024, 160*1024, 200*1024,
14540        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
14541        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
14542    };
14543
14544    static final void appendMemBucket(StringBuilder out, long memKB, String label,
14545            boolean stackLike) {
14546        int start = label.lastIndexOf('.');
14547        if (start >= 0) start++;
14548        else start = 0;
14549        int end = label.length();
14550        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
14551            if (DUMP_MEM_BUCKETS[i] >= memKB) {
14552                long bucket = DUMP_MEM_BUCKETS[i]/1024;
14553                out.append(bucket);
14554                out.append(stackLike ? "MB." : "MB ");
14555                out.append(label, start, end);
14556                return;
14557            }
14558        }
14559        out.append(memKB/1024);
14560        out.append(stackLike ? "MB." : "MB ");
14561        out.append(label, start, end);
14562    }
14563
14564    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
14565            ProcessList.NATIVE_ADJ,
14566            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
14567            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
14568            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
14569            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
14570            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
14571            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
14572    };
14573    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
14574            "Native",
14575            "System", "Persistent", "Persistent Service", "Foreground",
14576            "Visible", "Perceptible",
14577            "Heavy Weight", "Backup",
14578            "A Services", "Home",
14579            "Previous", "B Services", "Cached"
14580    };
14581    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
14582            "native",
14583            "sys", "pers", "persvc", "fore",
14584            "vis", "percept",
14585            "heavy", "backup",
14586            "servicea", "home",
14587            "prev", "serviceb", "cached"
14588    };
14589
14590    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
14591            long realtime, boolean isCheckinRequest, boolean isCompact) {
14592        if (isCheckinRequest || isCompact) {
14593            // short checkin version
14594            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
14595        } else {
14596            pw.println("Applications Memory Usage (kB):");
14597            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14598        }
14599    }
14600
14601    private static final int KSM_SHARED = 0;
14602    private static final int KSM_SHARING = 1;
14603    private static final int KSM_UNSHARED = 2;
14604    private static final int KSM_VOLATILE = 3;
14605
14606    private final long[] getKsmInfo() {
14607        long[] longOut = new long[4];
14608        final int[] SINGLE_LONG_FORMAT = new int[] {
14609            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14610        };
14611        long[] longTmp = new long[1];
14612        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14613                SINGLE_LONG_FORMAT, null, longTmp, null);
14614        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14615        longTmp[0] = 0;
14616        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14617                SINGLE_LONG_FORMAT, null, longTmp, null);
14618        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14619        longTmp[0] = 0;
14620        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14621                SINGLE_LONG_FORMAT, null, longTmp, null);
14622        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14623        longTmp[0] = 0;
14624        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14625                SINGLE_LONG_FORMAT, null, longTmp, null);
14626        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14627        return longOut;
14628    }
14629
14630    final void dumpApplicationMemoryUsage(FileDescriptor fd,
14631            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
14632        boolean dumpDetails = false;
14633        boolean dumpFullDetails = false;
14634        boolean dumpDalvik = false;
14635        boolean dumpSummaryOnly = false;
14636        boolean oomOnly = false;
14637        boolean isCompact = false;
14638        boolean localOnly = false;
14639        boolean packages = false;
14640
14641        int opti = 0;
14642        while (opti < args.length) {
14643            String opt = args[opti];
14644            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14645                break;
14646            }
14647            opti++;
14648            if ("-a".equals(opt)) {
14649                dumpDetails = true;
14650                dumpFullDetails = true;
14651                dumpDalvik = true;
14652            } else if ("-d".equals(opt)) {
14653                dumpDalvik = true;
14654            } else if ("-c".equals(opt)) {
14655                isCompact = true;
14656            } else if ("-s".equals(opt)) {
14657                dumpDetails = true;
14658                dumpSummaryOnly = true;
14659            } else if ("--oom".equals(opt)) {
14660                oomOnly = true;
14661            } else if ("--local".equals(opt)) {
14662                localOnly = true;
14663            } else if ("--package".equals(opt)) {
14664                packages = true;
14665            } else if ("-h".equals(opt)) {
14666                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
14667                pw.println("  -a: include all available information for each process.");
14668                pw.println("  -d: include dalvik details.");
14669                pw.println("  -c: dump in a compact machine-parseable representation.");
14670                pw.println("  -s: dump only summary of application memory usage.");
14671                pw.println("  --oom: only show processes organized by oom adj.");
14672                pw.println("  --local: only collect details locally, don't call process.");
14673                pw.println("  --package: interpret process arg as package, dumping all");
14674                pw.println("             processes that have loaded that package.");
14675                pw.println("If [process] is specified it can be the name or ");
14676                pw.println("pid of a specific process to dump.");
14677                return;
14678            } else {
14679                pw.println("Unknown argument: " + opt + "; use -h for help");
14680            }
14681        }
14682
14683        final boolean isCheckinRequest = scanArgs(args, "--checkin");
14684        long uptime = SystemClock.uptimeMillis();
14685        long realtime = SystemClock.elapsedRealtime();
14686        final long[] tmpLong = new long[1];
14687
14688        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
14689        if (procs == null) {
14690            // No Java processes.  Maybe they want to print a native process.
14691            if (args != null && args.length > opti
14692                    && args[opti].charAt(0) != '-') {
14693                ArrayList<ProcessCpuTracker.Stats> nativeProcs
14694                        = new ArrayList<ProcessCpuTracker.Stats>();
14695                updateCpuStatsNow();
14696                int findPid = -1;
14697                try {
14698                    findPid = Integer.parseInt(args[opti]);
14699                } catch (NumberFormatException e) {
14700                }
14701                synchronized (mProcessCpuTracker) {
14702                    final int N = mProcessCpuTracker.countStats();
14703                    for (int i=0; i<N; i++) {
14704                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14705                        if (st.pid == findPid || (st.baseName != null
14706                                && st.baseName.equals(args[opti]))) {
14707                            nativeProcs.add(st);
14708                        }
14709                    }
14710                }
14711                if (nativeProcs.size() > 0) {
14712                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14713                            isCompact);
14714                    Debug.MemoryInfo mi = null;
14715                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14716                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14717                        final int pid = r.pid;
14718                        if (!isCheckinRequest && dumpDetails) {
14719                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14720                        }
14721                        if (mi == null) {
14722                            mi = new Debug.MemoryInfo();
14723                        }
14724                        if (dumpDetails || (!brief && !oomOnly)) {
14725                            Debug.getMemoryInfo(pid, mi);
14726                        } else {
14727                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14728                            mi.dalvikPrivateDirty = (int)tmpLong[0];
14729                        }
14730                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14731                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14732                        if (isCheckinRequest) {
14733                            pw.println();
14734                        }
14735                    }
14736                    return;
14737                }
14738            }
14739            pw.println("No process found for: " + args[opti]);
14740            return;
14741        }
14742
14743        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14744            dumpDetails = true;
14745        }
14746
14747        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14748
14749        String[] innerArgs = new String[args.length-opti];
14750        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14751
14752        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14753        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14754        long nativePss = 0;
14755        long dalvikPss = 0;
14756        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
14757                EmptyArray.LONG;
14758        long otherPss = 0;
14759        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14760
14761        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14762        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14763                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14764
14765        long totalPss = 0;
14766        long cachedPss = 0;
14767
14768        Debug.MemoryInfo mi = null;
14769        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14770            final ProcessRecord r = procs.get(i);
14771            final IApplicationThread thread;
14772            final int pid;
14773            final int oomAdj;
14774            final boolean hasActivities;
14775            synchronized (this) {
14776                thread = r.thread;
14777                pid = r.pid;
14778                oomAdj = r.getSetAdjWithServices();
14779                hasActivities = r.activities.size() > 0;
14780            }
14781            if (thread != null) {
14782                if (!isCheckinRequest && dumpDetails) {
14783                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14784                }
14785                if (mi == null) {
14786                    mi = new Debug.MemoryInfo();
14787                }
14788                if (dumpDetails || (!brief && !oomOnly)) {
14789                    Debug.getMemoryInfo(pid, mi);
14790                } else {
14791                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14792                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14793                }
14794                if (dumpDetails) {
14795                    if (localOnly) {
14796                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14797                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
14798                        if (isCheckinRequest) {
14799                            pw.println();
14800                        }
14801                    } else {
14802                        try {
14803                            pw.flush();
14804                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14805                                    dumpDalvik, dumpSummaryOnly, innerArgs);
14806                        } catch (RemoteException e) {
14807                            if (!isCheckinRequest) {
14808                                pw.println("Got RemoteException!");
14809                                pw.flush();
14810                            }
14811                        }
14812                    }
14813                }
14814
14815                final long myTotalPss = mi.getTotalPss();
14816                final long myTotalUss = mi.getTotalUss();
14817
14818                synchronized (this) {
14819                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14820                        // Record this for posterity if the process has been stable.
14821                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14822                    }
14823                }
14824
14825                if (!isCheckinRequest && mi != null) {
14826                    totalPss += myTotalPss;
14827                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14828                            (hasActivities ? " / activities)" : ")"),
14829                            r.processName, myTotalPss, pid, hasActivities);
14830                    procMems.add(pssItem);
14831                    procMemsMap.put(pid, pssItem);
14832
14833                    nativePss += mi.nativePss;
14834                    dalvikPss += mi.dalvikPss;
14835                    for (int j=0; j<dalvikSubitemPss.length; j++) {
14836                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
14837                    }
14838                    otherPss += mi.otherPss;
14839                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14840                        long mem = mi.getOtherPss(j);
14841                        miscPss[j] += mem;
14842                        otherPss -= mem;
14843                    }
14844
14845                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14846                        cachedPss += myTotalPss;
14847                    }
14848
14849                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14850                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14851                                || oomIndex == (oomPss.length-1)) {
14852                            oomPss[oomIndex] += myTotalPss;
14853                            if (oomProcs[oomIndex] == null) {
14854                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14855                            }
14856                            oomProcs[oomIndex].add(pssItem);
14857                            break;
14858                        }
14859                    }
14860                }
14861            }
14862        }
14863
14864        long nativeProcTotalPss = 0;
14865
14866        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14867            // If we are showing aggregations, also look for native processes to
14868            // include so that our aggregations are more accurate.
14869            updateCpuStatsNow();
14870            mi = null;
14871            synchronized (mProcessCpuTracker) {
14872                final int N = mProcessCpuTracker.countStats();
14873                for (int i=0; i<N; i++) {
14874                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14875                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14876                        if (mi == null) {
14877                            mi = new Debug.MemoryInfo();
14878                        }
14879                        if (!brief && !oomOnly) {
14880                            Debug.getMemoryInfo(st.pid, mi);
14881                        } else {
14882                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14883                            mi.nativePrivateDirty = (int)tmpLong[0];
14884                        }
14885
14886                        final long myTotalPss = mi.getTotalPss();
14887                        totalPss += myTotalPss;
14888                        nativeProcTotalPss += myTotalPss;
14889
14890                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14891                                st.name, myTotalPss, st.pid, false);
14892                        procMems.add(pssItem);
14893
14894                        nativePss += mi.nativePss;
14895                        dalvikPss += mi.dalvikPss;
14896                        for (int j=0; j<dalvikSubitemPss.length; j++) {
14897                            dalvikSubitemPss[j] += mi.getOtherPss(
14898                                    Debug.MemoryInfo.NUM_OTHER_STATS + j);
14899                        }
14900                        otherPss += mi.otherPss;
14901                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14902                            long mem = mi.getOtherPss(j);
14903                            miscPss[j] += mem;
14904                            otherPss -= mem;
14905                        }
14906                        oomPss[0] += myTotalPss;
14907                        if (oomProcs[0] == null) {
14908                            oomProcs[0] = new ArrayList<MemItem>();
14909                        }
14910                        oomProcs[0].add(pssItem);
14911                    }
14912                }
14913            }
14914
14915            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14916
14917            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14918            final MemItem dalvikItem = new MemItem("Dalvik", "Dalvik", dalvikPss, -2);
14919            if (dalvikSubitemPss.length > 0) {
14920                dalvikItem.subitems = new ArrayList<MemItem>();
14921                for (int j=0; j<dalvikSubitemPss.length; j++) {
14922                    final String name = Debug.MemoryInfo.getOtherLabel(
14923                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
14924                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j], j));
14925                }
14926            }
14927            catMems.add(dalvikItem);
14928            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14929            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14930                String label = Debug.MemoryInfo.getOtherLabel(j);
14931                catMems.add(new MemItem(label, label, miscPss[j], j));
14932            }
14933
14934            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14935            for (int j=0; j<oomPss.length; j++) {
14936                if (oomPss[j] != 0) {
14937                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14938                            : DUMP_MEM_OOM_LABEL[j];
14939                    MemItem item = new MemItem(label, label, oomPss[j],
14940                            DUMP_MEM_OOM_ADJ[j]);
14941                    item.subitems = oomProcs[j];
14942                    oomMems.add(item);
14943                }
14944            }
14945
14946            if (!brief && !oomOnly && !isCompact) {
14947                pw.println();
14948                pw.println("Total PSS by process:");
14949                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14950                pw.println();
14951            }
14952            if (!isCompact) {
14953                pw.println("Total PSS by OOM adjustment:");
14954            }
14955            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14956            if (!brief && !oomOnly) {
14957                PrintWriter out = categoryPw != null ? categoryPw : pw;
14958                if (!isCompact) {
14959                    out.println();
14960                    out.println("Total PSS by category:");
14961                }
14962                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14963            }
14964            if (!isCompact) {
14965                pw.println();
14966            }
14967            MemInfoReader memInfo = new MemInfoReader();
14968            memInfo.readMemInfo();
14969            if (nativeProcTotalPss > 0) {
14970                synchronized (this) {
14971                    final long cachedKb = memInfo.getCachedSizeKb();
14972                    final long freeKb = memInfo.getFreeSizeKb();
14973                    final long zramKb = memInfo.getZramTotalSizeKb();
14974                    final long kernelKb = memInfo.getKernelUsedSizeKb();
14975                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
14976                            kernelKb*1024, nativeProcTotalPss*1024);
14977                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
14978                            nativeProcTotalPss);
14979                }
14980            }
14981            if (!brief) {
14982                if (!isCompact) {
14983                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14984                    pw.print(" kB (status ");
14985                    switch (mLastMemoryLevel) {
14986                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14987                            pw.println("normal)");
14988                            break;
14989                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14990                            pw.println("moderate)");
14991                            break;
14992                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14993                            pw.println("low)");
14994                            break;
14995                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14996                            pw.println("critical)");
14997                            break;
14998                        default:
14999                            pw.print(mLastMemoryLevel);
15000                            pw.println(")");
15001                            break;
15002                    }
15003                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
15004                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
15005                            pw.print(cachedPss); pw.print(" cached pss + ");
15006                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
15007                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
15008                } else {
15009                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15010                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15011                            + memInfo.getFreeSizeKb()); pw.print(",");
15012                    pw.println(totalPss - cachedPss);
15013                }
15014            }
15015            if (!isCompact) {
15016                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
15017                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
15018                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
15019                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
15020                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
15021                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15022                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
15023            }
15024            if (!brief) {
15025                if (memInfo.getZramTotalSizeKb() != 0) {
15026                    if (!isCompact) {
15027                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
15028                                pw.print(" kB physical used for ");
15029                                pw.print(memInfo.getSwapTotalSizeKb()
15030                                        - memInfo.getSwapFreeSizeKb());
15031                                pw.print(" kB in swap (");
15032                                pw.print(memInfo.getSwapTotalSizeKb());
15033                                pw.println(" kB total swap)");
15034                    } else {
15035                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15036                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15037                                pw.println(memInfo.getSwapFreeSizeKb());
15038                    }
15039                }
15040                final long[] ksm = getKsmInfo();
15041                if (!isCompact) {
15042                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15043                            || ksm[KSM_VOLATILE] != 0) {
15044                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
15045                                pw.print(" kB saved from shared ");
15046                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
15047                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
15048                                pw.print(" kB unshared; ");
15049                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
15050                    }
15051                    pw.print("   Tuning: ");
15052                    pw.print(ActivityManager.staticGetMemoryClass());
15053                    pw.print(" (large ");
15054                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15055                    pw.print("), oom ");
15056                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15057                    pw.print(" kB");
15058                    pw.print(", restore limit ");
15059                    pw.print(mProcessList.getCachedRestoreThresholdKb());
15060                    pw.print(" kB");
15061                    if (ActivityManager.isLowRamDeviceStatic()) {
15062                        pw.print(" (low-ram)");
15063                    }
15064                    if (ActivityManager.isHighEndGfx()) {
15065                        pw.print(" (high-end-gfx)");
15066                    }
15067                    pw.println();
15068                } else {
15069                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15070                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15071                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15072                    pw.print("tuning,");
15073                    pw.print(ActivityManager.staticGetMemoryClass());
15074                    pw.print(',');
15075                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15076                    pw.print(',');
15077                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15078                    if (ActivityManager.isLowRamDeviceStatic()) {
15079                        pw.print(",low-ram");
15080                    }
15081                    if (ActivityManager.isHighEndGfx()) {
15082                        pw.print(",high-end-gfx");
15083                    }
15084                    pw.println();
15085                }
15086            }
15087        }
15088    }
15089
15090    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15091            long memtrack, String name) {
15092        sb.append("  ");
15093        sb.append(ProcessList.makeOomAdjString(oomAdj));
15094        sb.append(' ');
15095        sb.append(ProcessList.makeProcStateString(procState));
15096        sb.append(' ');
15097        ProcessList.appendRamKb(sb, pss);
15098        sb.append(" kB: ");
15099        sb.append(name);
15100        if (memtrack > 0) {
15101            sb.append(" (");
15102            sb.append(memtrack);
15103            sb.append(" kB memtrack)");
15104        }
15105    }
15106
15107    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15108        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15109        sb.append(" (pid ");
15110        sb.append(mi.pid);
15111        sb.append(") ");
15112        sb.append(mi.adjType);
15113        sb.append('\n');
15114        if (mi.adjReason != null) {
15115            sb.append("                      ");
15116            sb.append(mi.adjReason);
15117            sb.append('\n');
15118        }
15119    }
15120
15121    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15122        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15123        for (int i=0, N=memInfos.size(); i<N; i++) {
15124            ProcessMemInfo mi = memInfos.get(i);
15125            infoMap.put(mi.pid, mi);
15126        }
15127        updateCpuStatsNow();
15128        long[] memtrackTmp = new long[1];
15129        synchronized (mProcessCpuTracker) {
15130            final int N = mProcessCpuTracker.countStats();
15131            for (int i=0; i<N; i++) {
15132                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15133                if (st.vsize > 0) {
15134                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
15135                    if (pss > 0) {
15136                        if (infoMap.indexOfKey(st.pid) < 0) {
15137                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15138                                    ProcessList.NATIVE_ADJ, -1, "native", null);
15139                            mi.pss = pss;
15140                            mi.memtrack = memtrackTmp[0];
15141                            memInfos.add(mi);
15142                        }
15143                    }
15144                }
15145            }
15146        }
15147
15148        long totalPss = 0;
15149        long totalMemtrack = 0;
15150        for (int i=0, N=memInfos.size(); i<N; i++) {
15151            ProcessMemInfo mi = memInfos.get(i);
15152            if (mi.pss == 0) {
15153                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15154                mi.memtrack = memtrackTmp[0];
15155            }
15156            totalPss += mi.pss;
15157            totalMemtrack += mi.memtrack;
15158        }
15159        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15160            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15161                if (lhs.oomAdj != rhs.oomAdj) {
15162                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15163                }
15164                if (lhs.pss != rhs.pss) {
15165                    return lhs.pss < rhs.pss ? 1 : -1;
15166                }
15167                return 0;
15168            }
15169        });
15170
15171        StringBuilder tag = new StringBuilder(128);
15172        StringBuilder stack = new StringBuilder(128);
15173        tag.append("Low on memory -- ");
15174        appendMemBucket(tag, totalPss, "total", false);
15175        appendMemBucket(stack, totalPss, "total", true);
15176
15177        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15178        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15179        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15180
15181        boolean firstLine = true;
15182        int lastOomAdj = Integer.MIN_VALUE;
15183        long extraNativeRam = 0;
15184        long extraNativeMemtrack = 0;
15185        long cachedPss = 0;
15186        for (int i=0, N=memInfos.size(); i<N; i++) {
15187            ProcessMemInfo mi = memInfos.get(i);
15188
15189            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15190                cachedPss += mi.pss;
15191            }
15192
15193            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15194                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15195                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15196                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15197                if (lastOomAdj != mi.oomAdj) {
15198                    lastOomAdj = mi.oomAdj;
15199                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15200                        tag.append(" / ");
15201                    }
15202                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15203                        if (firstLine) {
15204                            stack.append(":");
15205                            firstLine = false;
15206                        }
15207                        stack.append("\n\t at ");
15208                    } else {
15209                        stack.append("$");
15210                    }
15211                } else {
15212                    tag.append(" ");
15213                    stack.append("$");
15214                }
15215                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15216                    appendMemBucket(tag, mi.pss, mi.name, false);
15217                }
15218                appendMemBucket(stack, mi.pss, mi.name, true);
15219                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15220                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15221                    stack.append("(");
15222                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15223                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15224                            stack.append(DUMP_MEM_OOM_LABEL[k]);
15225                            stack.append(":");
15226                            stack.append(DUMP_MEM_OOM_ADJ[k]);
15227                        }
15228                    }
15229                    stack.append(")");
15230                }
15231            }
15232
15233            appendMemInfo(fullNativeBuilder, mi);
15234            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15235                // The short form only has native processes that are >= 512K.
15236                if (mi.pss >= 512) {
15237                    appendMemInfo(shortNativeBuilder, mi);
15238                } else {
15239                    extraNativeRam += mi.pss;
15240                    extraNativeMemtrack += mi.memtrack;
15241                }
15242            } else {
15243                // Short form has all other details, but if we have collected RAM
15244                // from smaller native processes let's dump a summary of that.
15245                if (extraNativeRam > 0) {
15246                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15247                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15248                    shortNativeBuilder.append('\n');
15249                    extraNativeRam = 0;
15250                }
15251                appendMemInfo(fullJavaBuilder, mi);
15252            }
15253        }
15254
15255        fullJavaBuilder.append("           ");
15256        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15257        fullJavaBuilder.append(" kB: TOTAL");
15258        if (totalMemtrack > 0) {
15259            fullJavaBuilder.append(" (");
15260            fullJavaBuilder.append(totalMemtrack);
15261            fullJavaBuilder.append(" kB memtrack)");
15262        } else {
15263        }
15264        fullJavaBuilder.append("\n");
15265
15266        MemInfoReader memInfo = new MemInfoReader();
15267        memInfo.readMemInfo();
15268        final long[] infos = memInfo.getRawInfo();
15269
15270        StringBuilder memInfoBuilder = new StringBuilder(1024);
15271        Debug.getMemInfo(infos);
15272        memInfoBuilder.append("  MemInfo: ");
15273        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
15274        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
15275        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
15276        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
15277        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
15278        memInfoBuilder.append("           ");
15279        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
15280        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
15281        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
15282        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
15283        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15284            memInfoBuilder.append("  ZRAM: ");
15285            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
15286            memInfoBuilder.append(" kB RAM, ");
15287            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
15288            memInfoBuilder.append(" kB swap total, ");
15289            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
15290            memInfoBuilder.append(" kB swap free\n");
15291        }
15292        final long[] ksm = getKsmInfo();
15293        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15294                || ksm[KSM_VOLATILE] != 0) {
15295            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
15296            memInfoBuilder.append(" kB saved from shared ");
15297            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
15298            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
15299            memInfoBuilder.append(" kB unshared; ");
15300            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
15301        }
15302        memInfoBuilder.append("  Free RAM: ");
15303        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
15304                + memInfo.getFreeSizeKb());
15305        memInfoBuilder.append(" kB\n");
15306        memInfoBuilder.append("  Used RAM: ");
15307        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
15308        memInfoBuilder.append(" kB\n");
15309        memInfoBuilder.append("  Lost RAM: ");
15310        memInfoBuilder.append(memInfo.getTotalSizeKb()
15311                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15312                - memInfo.getKernelUsedSizeKb());
15313        memInfoBuilder.append(" kB\n");
15314        Slog.i(TAG, "Low on memory:");
15315        Slog.i(TAG, shortNativeBuilder.toString());
15316        Slog.i(TAG, fullJavaBuilder.toString());
15317        Slog.i(TAG, memInfoBuilder.toString());
15318
15319        StringBuilder dropBuilder = new StringBuilder(1024);
15320        /*
15321        StringWriter oomSw = new StringWriter();
15322        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
15323        StringWriter catSw = new StringWriter();
15324        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15325        String[] emptyArgs = new String[] { };
15326        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
15327        oomPw.flush();
15328        String oomString = oomSw.toString();
15329        */
15330        dropBuilder.append("Low on memory:");
15331        dropBuilder.append(stack);
15332        dropBuilder.append('\n');
15333        dropBuilder.append(fullNativeBuilder);
15334        dropBuilder.append(fullJavaBuilder);
15335        dropBuilder.append('\n');
15336        dropBuilder.append(memInfoBuilder);
15337        dropBuilder.append('\n');
15338        /*
15339        dropBuilder.append(oomString);
15340        dropBuilder.append('\n');
15341        */
15342        StringWriter catSw = new StringWriter();
15343        synchronized (ActivityManagerService.this) {
15344            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15345            String[] emptyArgs = new String[] { };
15346            catPw.println();
15347            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
15348            catPw.println();
15349            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
15350                    false, false, null);
15351            catPw.println();
15352            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
15353            catPw.flush();
15354        }
15355        dropBuilder.append(catSw.toString());
15356        addErrorToDropBox("lowmem", null, "system_server", null,
15357                null, tag.toString(), dropBuilder.toString(), null, null);
15358        //Slog.i(TAG, "Sent to dropbox:");
15359        //Slog.i(TAG, dropBuilder.toString());
15360        synchronized (ActivityManagerService.this) {
15361            long now = SystemClock.uptimeMillis();
15362            if (mLastMemUsageReportTime < now) {
15363                mLastMemUsageReportTime = now;
15364            }
15365        }
15366    }
15367
15368    /**
15369     * Searches array of arguments for the specified string
15370     * @param args array of argument strings
15371     * @param value value to search for
15372     * @return true if the value is contained in the array
15373     */
15374    private static boolean scanArgs(String[] args, String value) {
15375        if (args != null) {
15376            for (String arg : args) {
15377                if (value.equals(arg)) {
15378                    return true;
15379                }
15380            }
15381        }
15382        return false;
15383    }
15384
15385    private final boolean removeDyingProviderLocked(ProcessRecord proc,
15386            ContentProviderRecord cpr, boolean always) {
15387        final boolean inLaunching = mLaunchingProviders.contains(cpr);
15388
15389        if (!inLaunching || always) {
15390            synchronized (cpr) {
15391                cpr.launchingApp = null;
15392                cpr.notifyAll();
15393            }
15394            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
15395            String names[] = cpr.info.authority.split(";");
15396            for (int j = 0; j < names.length; j++) {
15397                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
15398            }
15399        }
15400
15401        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
15402            ContentProviderConnection conn = cpr.connections.get(i);
15403            if (conn.waiting) {
15404                // If this connection is waiting for the provider, then we don't
15405                // need to mess with its process unless we are always removing
15406                // or for some reason the provider is not currently launching.
15407                if (inLaunching && !always) {
15408                    continue;
15409                }
15410            }
15411            ProcessRecord capp = conn.client;
15412            conn.dead = true;
15413            if (conn.stableCount > 0) {
15414                if (!capp.persistent && capp.thread != null
15415                        && capp.pid != 0
15416                        && capp.pid != MY_PID) {
15417                    capp.kill("depends on provider "
15418                            + cpr.name.flattenToShortString()
15419                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
15420                }
15421            } else if (capp.thread != null && conn.provider.provider != null) {
15422                try {
15423                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
15424                } catch (RemoteException e) {
15425                }
15426                // In the protocol here, we don't expect the client to correctly
15427                // clean up this connection, we'll just remove it.
15428                cpr.connections.remove(i);
15429                if (conn.client.conProviders.remove(conn)) {
15430                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
15431                }
15432            }
15433        }
15434
15435        if (inLaunching && always) {
15436            mLaunchingProviders.remove(cpr);
15437        }
15438        return inLaunching;
15439    }
15440
15441    /**
15442     * Main code for cleaning up a process when it has gone away.  This is
15443     * called both as a result of the process dying, or directly when stopping
15444     * a process when running in single process mode.
15445     *
15446     * @return Returns true if the given process has been restarted, so the
15447     * app that was passed in must remain on the process lists.
15448     */
15449    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
15450            boolean restarting, boolean allowRestart, int index) {
15451        if (index >= 0) {
15452            removeLruProcessLocked(app);
15453            ProcessList.remove(app.pid);
15454        }
15455
15456        mProcessesToGc.remove(app);
15457        mPendingPssProcesses.remove(app);
15458
15459        // Dismiss any open dialogs.
15460        if (app.crashDialog != null && !app.forceCrashReport) {
15461            app.crashDialog.dismiss();
15462            app.crashDialog = null;
15463        }
15464        if (app.anrDialog != null) {
15465            app.anrDialog.dismiss();
15466            app.anrDialog = null;
15467        }
15468        if (app.waitDialog != null) {
15469            app.waitDialog.dismiss();
15470            app.waitDialog = null;
15471        }
15472
15473        app.crashing = false;
15474        app.notResponding = false;
15475
15476        app.resetPackageList(mProcessStats);
15477        app.unlinkDeathRecipient();
15478        app.makeInactive(mProcessStats);
15479        app.waitingToKill = null;
15480        app.forcingToForeground = null;
15481        updateProcessForegroundLocked(app, false, false);
15482        app.foregroundActivities = false;
15483        app.hasShownUi = false;
15484        app.treatLikeActivity = false;
15485        app.hasAboveClient = false;
15486        app.hasClientActivities = false;
15487
15488        mServices.killServicesLocked(app, allowRestart);
15489
15490        boolean restart = false;
15491
15492        // Remove published content providers.
15493        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
15494            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
15495            final boolean always = app.bad || !allowRestart;
15496            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
15497            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
15498                // We left the provider in the launching list, need to
15499                // restart it.
15500                restart = true;
15501            }
15502
15503            cpr.provider = null;
15504            cpr.proc = null;
15505        }
15506        app.pubProviders.clear();
15507
15508        // Take care of any launching providers waiting for this process.
15509        if (checkAppInLaunchingProvidersLocked(app, false)) {
15510            restart = true;
15511        }
15512
15513        // Unregister from connected content providers.
15514        if (!app.conProviders.isEmpty()) {
15515            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
15516                ContentProviderConnection conn = app.conProviders.get(i);
15517                conn.provider.connections.remove(conn);
15518                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
15519                        conn.provider.name);
15520            }
15521            app.conProviders.clear();
15522        }
15523
15524        // At this point there may be remaining entries in mLaunchingProviders
15525        // where we were the only one waiting, so they are no longer of use.
15526        // Look for these and clean up if found.
15527        // XXX Commented out for now.  Trying to figure out a way to reproduce
15528        // the actual situation to identify what is actually going on.
15529        if (false) {
15530            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15531                ContentProviderRecord cpr = mLaunchingProviders.get(i);
15532                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
15533                    synchronized (cpr) {
15534                        cpr.launchingApp = null;
15535                        cpr.notifyAll();
15536                    }
15537                }
15538            }
15539        }
15540
15541        skipCurrentReceiverLocked(app);
15542
15543        // Unregister any receivers.
15544        for (int i = app.receivers.size() - 1; i >= 0; i--) {
15545            removeReceiverLocked(app.receivers.valueAt(i));
15546        }
15547        app.receivers.clear();
15548
15549        // If the app is undergoing backup, tell the backup manager about it
15550        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
15551            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
15552                    + mBackupTarget.appInfo + " died during backup");
15553            try {
15554                IBackupManager bm = IBackupManager.Stub.asInterface(
15555                        ServiceManager.getService(Context.BACKUP_SERVICE));
15556                bm.agentDisconnected(app.info.packageName);
15557            } catch (RemoteException e) {
15558                // can't happen; backup manager is local
15559            }
15560        }
15561
15562        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
15563            ProcessChangeItem item = mPendingProcessChanges.get(i);
15564            if (item.pid == app.pid) {
15565                mPendingProcessChanges.remove(i);
15566                mAvailProcessChanges.add(item);
15567            }
15568        }
15569        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
15570
15571        // If the caller is restarting this app, then leave it in its
15572        // current lists and let the caller take care of it.
15573        if (restarting) {
15574            return false;
15575        }
15576
15577        if (!app.persistent || app.isolated) {
15578            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
15579                    "Removing non-persistent process during cleanup: " + app);
15580            removeProcessNameLocked(app.processName, app.uid);
15581            if (mHeavyWeightProcess == app) {
15582                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
15583                        mHeavyWeightProcess.userId, 0));
15584                mHeavyWeightProcess = null;
15585            }
15586        } else if (!app.removed) {
15587            // This app is persistent, so we need to keep its record around.
15588            // If it is not already on the pending app list, add it there
15589            // and start a new process for it.
15590            if (mPersistentStartingProcesses.indexOf(app) < 0) {
15591                mPersistentStartingProcesses.add(app);
15592                restart = true;
15593            }
15594        }
15595        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
15596                TAG_CLEANUP, "Clean-up removing on hold: " + app);
15597        mProcessesOnHold.remove(app);
15598
15599        if (app == mHomeProcess) {
15600            mHomeProcess = null;
15601        }
15602        if (app == mPreviousProcess) {
15603            mPreviousProcess = null;
15604        }
15605
15606        if (restart && !app.isolated) {
15607            // We have components that still need to be running in the
15608            // process, so re-launch it.
15609            if (index < 0) {
15610                ProcessList.remove(app.pid);
15611            }
15612            addProcessNameLocked(app);
15613            startProcessLocked(app, "restart", app.processName);
15614            return true;
15615        } else if (app.pid > 0 && app.pid != MY_PID) {
15616            // Goodbye!
15617            boolean removed;
15618            synchronized (mPidsSelfLocked) {
15619                mPidsSelfLocked.remove(app.pid);
15620                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
15621            }
15622            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
15623            if (app.isolated) {
15624                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
15625            }
15626            app.setPid(0);
15627        }
15628        return false;
15629    }
15630
15631    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
15632        // Look through the content providers we are waiting to have launched,
15633        // and if any run in this process then either schedule a restart of
15634        // the process or kill the client waiting for it if this process has
15635        // gone bad.
15636        boolean restart = false;
15637        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15638            ContentProviderRecord cpr = mLaunchingProviders.get(i);
15639            if (cpr.launchingApp == app) {
15640                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
15641                    restart = true;
15642                } else {
15643                    removeDyingProviderLocked(app, cpr, true);
15644                }
15645            }
15646        }
15647        return restart;
15648    }
15649
15650    // =========================================================
15651    // SERVICES
15652    // =========================================================
15653
15654    @Override
15655    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
15656            int flags) {
15657        enforceNotIsolatedCaller("getServices");
15658        synchronized (this) {
15659            return mServices.getRunningServiceInfoLocked(maxNum, flags);
15660        }
15661    }
15662
15663    @Override
15664    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
15665        enforceNotIsolatedCaller("getRunningServiceControlPanel");
15666        synchronized (this) {
15667            return mServices.getRunningServiceControlPanelLocked(name);
15668        }
15669    }
15670
15671    @Override
15672    public ComponentName startService(IApplicationThread caller, Intent service,
15673            String resolvedType, String callingPackage, int userId)
15674            throws TransactionTooLargeException {
15675        enforceNotIsolatedCaller("startService");
15676        // Refuse possible leaked file descriptors
15677        if (service != null && service.hasFileDescriptors() == true) {
15678            throw new IllegalArgumentException("File descriptors passed in Intent");
15679        }
15680
15681        if (callingPackage == null) {
15682            throw new IllegalArgumentException("callingPackage cannot be null");
15683        }
15684
15685        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15686                "startService: " + service + " type=" + resolvedType);
15687        synchronized(this) {
15688            final int callingPid = Binder.getCallingPid();
15689            final int callingUid = Binder.getCallingUid();
15690            final long origId = Binder.clearCallingIdentity();
15691            ComponentName res = mServices.startServiceLocked(caller, service,
15692                    resolvedType, callingPid, callingUid, callingPackage, userId);
15693            Binder.restoreCallingIdentity(origId);
15694            return res;
15695        }
15696    }
15697
15698    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
15699            String callingPackage, int userId)
15700            throws TransactionTooLargeException {
15701        synchronized(this) {
15702            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15703                    "startServiceInPackage: " + service + " type=" + resolvedType);
15704            final long origId = Binder.clearCallingIdentity();
15705            ComponentName res = mServices.startServiceLocked(null, service,
15706                    resolvedType, -1, uid, callingPackage, userId);
15707            Binder.restoreCallingIdentity(origId);
15708            return res;
15709        }
15710    }
15711
15712    @Override
15713    public int stopService(IApplicationThread caller, Intent service,
15714            String resolvedType, int userId) {
15715        enforceNotIsolatedCaller("stopService");
15716        // Refuse possible leaked file descriptors
15717        if (service != null && service.hasFileDescriptors() == true) {
15718            throw new IllegalArgumentException("File descriptors passed in Intent");
15719        }
15720
15721        synchronized(this) {
15722            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
15723        }
15724    }
15725
15726    @Override
15727    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
15728        enforceNotIsolatedCaller("peekService");
15729        // Refuse possible leaked file descriptors
15730        if (service != null && service.hasFileDescriptors() == true) {
15731            throw new IllegalArgumentException("File descriptors passed in Intent");
15732        }
15733
15734        if (callingPackage == null) {
15735            throw new IllegalArgumentException("callingPackage cannot be null");
15736        }
15737
15738        synchronized(this) {
15739            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
15740        }
15741    }
15742
15743    @Override
15744    public boolean stopServiceToken(ComponentName className, IBinder token,
15745            int startId) {
15746        synchronized(this) {
15747            return mServices.stopServiceTokenLocked(className, token, startId);
15748        }
15749    }
15750
15751    @Override
15752    public void setServiceForeground(ComponentName className, IBinder token,
15753            int id, Notification notification, boolean removeNotification) {
15754        synchronized(this) {
15755            mServices.setServiceForegroundLocked(className, token, id, notification,
15756                    removeNotification);
15757        }
15758    }
15759
15760    @Override
15761    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15762            boolean requireFull, String name, String callerPackage) {
15763        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15764                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15765    }
15766
15767    int unsafeConvertIncomingUser(int userId) {
15768        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15769                ? mCurrentUserId : userId;
15770    }
15771
15772    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15773            int allowMode, String name, String callerPackage) {
15774        final int callingUserId = UserHandle.getUserId(callingUid);
15775        if (callingUserId == userId) {
15776            return userId;
15777        }
15778
15779        // Note that we may be accessing mCurrentUserId outside of a lock...
15780        // shouldn't be a big deal, if this is being called outside
15781        // of a locked context there is intrinsically a race with
15782        // the value the caller will receive and someone else changing it.
15783        // We assume that USER_CURRENT_OR_SELF will use the current user; later
15784        // we will switch to the calling user if access to the current user fails.
15785        int targetUserId = unsafeConvertIncomingUser(userId);
15786
15787        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15788            final boolean allow;
15789            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15790                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15791                // If the caller has this permission, they always pass go.  And collect $200.
15792                allow = true;
15793            } else if (allowMode == ALLOW_FULL_ONLY) {
15794                // We require full access, sucks to be you.
15795                allow = false;
15796            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15797                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15798                // If the caller does not have either permission, they are always doomed.
15799                allow = false;
15800            } else if (allowMode == ALLOW_NON_FULL) {
15801                // We are blanket allowing non-full access, you lucky caller!
15802                allow = true;
15803            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15804                // We may or may not allow this depending on whether the two users are
15805                // in the same profile.
15806                synchronized (mUserProfileGroupIdsSelfLocked) {
15807                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15808                            UserInfo.NO_PROFILE_GROUP_ID);
15809                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15810                            UserInfo.NO_PROFILE_GROUP_ID);
15811                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15812                            && callingProfile == targetProfile;
15813                }
15814            } else {
15815                throw new IllegalArgumentException("Unknown mode: " + allowMode);
15816            }
15817            if (!allow) {
15818                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15819                    // In this case, they would like to just execute as their
15820                    // owner user instead of failing.
15821                    targetUserId = callingUserId;
15822                } else {
15823                    StringBuilder builder = new StringBuilder(128);
15824                    builder.append("Permission Denial: ");
15825                    builder.append(name);
15826                    if (callerPackage != null) {
15827                        builder.append(" from ");
15828                        builder.append(callerPackage);
15829                    }
15830                    builder.append(" asks to run as user ");
15831                    builder.append(userId);
15832                    builder.append(" but is calling from user ");
15833                    builder.append(UserHandle.getUserId(callingUid));
15834                    builder.append("; this requires ");
15835                    builder.append(INTERACT_ACROSS_USERS_FULL);
15836                    if (allowMode != ALLOW_FULL_ONLY) {
15837                        builder.append(" or ");
15838                        builder.append(INTERACT_ACROSS_USERS);
15839                    }
15840                    String msg = builder.toString();
15841                    Slog.w(TAG, msg);
15842                    throw new SecurityException(msg);
15843                }
15844            }
15845        }
15846        if (!allowAll && targetUserId < 0) {
15847            throw new IllegalArgumentException(
15848                    "Call does not support special user #" + targetUserId);
15849        }
15850        // Check shell permission
15851        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15852            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15853                    targetUserId)) {
15854                throw new SecurityException("Shell does not have permission to access user "
15855                        + targetUserId + "\n " + Debug.getCallers(3));
15856            }
15857        }
15858        return targetUserId;
15859    }
15860
15861    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15862            String className, int flags) {
15863        boolean result = false;
15864        // For apps that don't have pre-defined UIDs, check for permission
15865        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15866            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15867                if (ActivityManager.checkUidPermission(
15868                        INTERACT_ACROSS_USERS,
15869                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15870                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15871                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15872                            + " requests FLAG_SINGLE_USER, but app does not hold "
15873                            + INTERACT_ACROSS_USERS;
15874                    Slog.w(TAG, msg);
15875                    throw new SecurityException(msg);
15876                }
15877                // Permission passed
15878                result = true;
15879            }
15880        } else if ("system".equals(componentProcessName)) {
15881            result = true;
15882        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15883            // Phone app and persistent apps are allowed to export singleuser providers.
15884            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15885                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15886        }
15887        if (DEBUG_MU) Slog.v(TAG_MU,
15888                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
15889                + Integer.toHexString(flags) + ") = " + result);
15890        return result;
15891    }
15892
15893    /**
15894     * Checks to see if the caller is in the same app as the singleton
15895     * component, or the component is in a special app. It allows special apps
15896     * to export singleton components but prevents exporting singleton
15897     * components for regular apps.
15898     */
15899    boolean isValidSingletonCall(int callingUid, int componentUid) {
15900        int componentAppId = UserHandle.getAppId(componentUid);
15901        return UserHandle.isSameApp(callingUid, componentUid)
15902                || componentAppId == Process.SYSTEM_UID
15903                || componentAppId == Process.PHONE_UID
15904                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15905                        == PackageManager.PERMISSION_GRANTED;
15906    }
15907
15908    public int bindService(IApplicationThread caller, IBinder token, Intent service,
15909            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
15910            int userId) throws TransactionTooLargeException {
15911        enforceNotIsolatedCaller("bindService");
15912
15913        // Refuse possible leaked file descriptors
15914        if (service != null && service.hasFileDescriptors() == true) {
15915            throw new IllegalArgumentException("File descriptors passed in Intent");
15916        }
15917
15918        if (callingPackage == null) {
15919            throw new IllegalArgumentException("callingPackage cannot be null");
15920        }
15921
15922        synchronized(this) {
15923            return mServices.bindServiceLocked(caller, token, service,
15924                    resolvedType, connection, flags, callingPackage, userId);
15925        }
15926    }
15927
15928    public boolean unbindService(IServiceConnection connection) {
15929        synchronized (this) {
15930            return mServices.unbindServiceLocked(connection);
15931        }
15932    }
15933
15934    public void publishService(IBinder token, Intent intent, IBinder service) {
15935        // Refuse possible leaked file descriptors
15936        if (intent != null && intent.hasFileDescriptors() == true) {
15937            throw new IllegalArgumentException("File descriptors passed in Intent");
15938        }
15939
15940        synchronized(this) {
15941            if (!(token instanceof ServiceRecord)) {
15942                throw new IllegalArgumentException("Invalid service token");
15943            }
15944            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15945        }
15946    }
15947
15948    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15949        // Refuse possible leaked file descriptors
15950        if (intent != null && intent.hasFileDescriptors() == true) {
15951            throw new IllegalArgumentException("File descriptors passed in Intent");
15952        }
15953
15954        synchronized(this) {
15955            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15956        }
15957    }
15958
15959    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15960        synchronized(this) {
15961            if (!(token instanceof ServiceRecord)) {
15962                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
15963                throw new IllegalArgumentException("Invalid service token");
15964            }
15965            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15966        }
15967    }
15968
15969    // =========================================================
15970    // BACKUP AND RESTORE
15971    // =========================================================
15972
15973    // Cause the target app to be launched if necessary and its backup agent
15974    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15975    // activity manager to announce its creation.
15976    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15977        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
15978                "bindBackupAgent: app=" + app + " mode=" + backupMode);
15979        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15980
15981        synchronized(this) {
15982            // !!! TODO: currently no check here that we're already bound
15983            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15984            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15985            synchronized (stats) {
15986                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15987            }
15988
15989            // Backup agent is now in use, its package can't be stopped.
15990            try {
15991                AppGlobals.getPackageManager().setPackageStoppedState(
15992                        app.packageName, false, UserHandle.getUserId(app.uid));
15993            } catch (RemoteException e) {
15994            } catch (IllegalArgumentException e) {
15995                Slog.w(TAG, "Failed trying to unstop package "
15996                        + app.packageName + ": " + e);
15997            }
15998
15999            BackupRecord r = new BackupRecord(ss, app, backupMode);
16000            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16001                    ? new ComponentName(app.packageName, app.backupAgentName)
16002                    : new ComponentName("android", "FullBackupAgent");
16003            // startProcessLocked() returns existing proc's record if it's already running
16004            ProcessRecord proc = startProcessLocked(app.processName, app,
16005                    false, 0, "backup", hostingName, false, false, false);
16006            if (proc == null) {
16007                Slog.e(TAG, "Unable to start backup agent process " + r);
16008                return false;
16009            }
16010
16011            r.app = proc;
16012            mBackupTarget = r;
16013            mBackupAppName = app.packageName;
16014
16015            // Try not to kill the process during backup
16016            updateOomAdjLocked(proc);
16017
16018            // If the process is already attached, schedule the creation of the backup agent now.
16019            // If it is not yet live, this will be done when it attaches to the framework.
16020            if (proc.thread != null) {
16021                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16022                try {
16023                    proc.thread.scheduleCreateBackupAgent(app,
16024                            compatibilityInfoForPackageLocked(app), backupMode);
16025                } catch (RemoteException e) {
16026                    // Will time out on the backup manager side
16027                }
16028            } else {
16029                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16030            }
16031            // Invariants: at this point, the target app process exists and the application
16032            // is either already running or in the process of coming up.  mBackupTarget and
16033            // mBackupAppName describe the app, so that when it binds back to the AM we
16034            // know that it's scheduled for a backup-agent operation.
16035        }
16036
16037        return true;
16038    }
16039
16040    @Override
16041    public void clearPendingBackup() {
16042        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16043        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16044
16045        synchronized (this) {
16046            mBackupTarget = null;
16047            mBackupAppName = null;
16048        }
16049    }
16050
16051    // A backup agent has just come up
16052    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16053        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16054                + " = " + agent);
16055
16056        synchronized(this) {
16057            if (!agentPackageName.equals(mBackupAppName)) {
16058                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16059                return;
16060            }
16061        }
16062
16063        long oldIdent = Binder.clearCallingIdentity();
16064        try {
16065            IBackupManager bm = IBackupManager.Stub.asInterface(
16066                    ServiceManager.getService(Context.BACKUP_SERVICE));
16067            bm.agentConnected(agentPackageName, agent);
16068        } catch (RemoteException e) {
16069            // can't happen; the backup manager service is local
16070        } catch (Exception e) {
16071            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16072            e.printStackTrace();
16073        } finally {
16074            Binder.restoreCallingIdentity(oldIdent);
16075        }
16076    }
16077
16078    // done with this agent
16079    public void unbindBackupAgent(ApplicationInfo appInfo) {
16080        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16081        if (appInfo == null) {
16082            Slog.w(TAG, "unbind backup agent for null app");
16083            return;
16084        }
16085
16086        synchronized(this) {
16087            try {
16088                if (mBackupAppName == null) {
16089                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16090                    return;
16091                }
16092
16093                if (!mBackupAppName.equals(appInfo.packageName)) {
16094                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16095                    return;
16096                }
16097
16098                // Not backing this app up any more; reset its OOM adjustment
16099                final ProcessRecord proc = mBackupTarget.app;
16100                updateOomAdjLocked(proc);
16101
16102                // If the app crashed during backup, 'thread' will be null here
16103                if (proc.thread != null) {
16104                    try {
16105                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16106                                compatibilityInfoForPackageLocked(appInfo));
16107                    } catch (Exception e) {
16108                        Slog.e(TAG, "Exception when unbinding backup agent:");
16109                        e.printStackTrace();
16110                    }
16111                }
16112            } finally {
16113                mBackupTarget = null;
16114                mBackupAppName = null;
16115            }
16116        }
16117    }
16118    // =========================================================
16119    // BROADCASTS
16120    // =========================================================
16121
16122    boolean isPendingBroadcastProcessLocked(int pid) {
16123        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16124                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16125    }
16126
16127    void skipPendingBroadcastLocked(int pid) {
16128            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16129            for (BroadcastQueue queue : mBroadcastQueues) {
16130                queue.skipPendingBroadcastLocked(pid);
16131            }
16132    }
16133
16134    // The app just attached; send any pending broadcasts that it should receive
16135    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16136        boolean didSomething = false;
16137        for (BroadcastQueue queue : mBroadcastQueues) {
16138            didSomething |= queue.sendPendingBroadcastsLocked(app);
16139        }
16140        return didSomething;
16141    }
16142
16143    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16144            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16145        enforceNotIsolatedCaller("registerReceiver");
16146        ArrayList<Intent> stickyIntents = null;
16147        ProcessRecord callerApp = null;
16148        int callingUid;
16149        int callingPid;
16150        synchronized(this) {
16151            if (caller != null) {
16152                callerApp = getRecordForAppLocked(caller);
16153                if (callerApp == null) {
16154                    throw new SecurityException(
16155                            "Unable to find app for caller " + caller
16156                            + " (pid=" + Binder.getCallingPid()
16157                            + ") when registering receiver " + receiver);
16158                }
16159                if (callerApp.info.uid != Process.SYSTEM_UID &&
16160                        !callerApp.pkgList.containsKey(callerPackage) &&
16161                        !"android".equals(callerPackage)) {
16162                    throw new SecurityException("Given caller package " + callerPackage
16163                            + " is not running in process " + callerApp);
16164                }
16165                callingUid = callerApp.info.uid;
16166                callingPid = callerApp.pid;
16167            } else {
16168                callerPackage = null;
16169                callingUid = Binder.getCallingUid();
16170                callingPid = Binder.getCallingPid();
16171            }
16172
16173            userId = handleIncomingUser(callingPid, callingUid, userId,
16174                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16175
16176            Iterator<String> actions = filter.actionsIterator();
16177            if (actions == null) {
16178                ArrayList<String> noAction = new ArrayList<String>(1);
16179                noAction.add(null);
16180                actions = noAction.iterator();
16181            }
16182
16183            // Collect stickies of users
16184            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16185            while (actions.hasNext()) {
16186                String action = actions.next();
16187                for (int id : userIds) {
16188                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16189                    if (stickies != null) {
16190                        ArrayList<Intent> intents = stickies.get(action);
16191                        if (intents != null) {
16192                            if (stickyIntents == null) {
16193                                stickyIntents = new ArrayList<Intent>();
16194                            }
16195                            stickyIntents.addAll(intents);
16196                        }
16197                    }
16198                }
16199            }
16200        }
16201
16202        ArrayList<Intent> allSticky = null;
16203        if (stickyIntents != null) {
16204            final ContentResolver resolver = mContext.getContentResolver();
16205            // Look for any matching sticky broadcasts...
16206            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16207                Intent intent = stickyIntents.get(i);
16208                // If intent has scheme "content", it will need to acccess
16209                // provider that needs to lock mProviderMap in ActivityThread
16210                // and also it may need to wait application response, so we
16211                // cannot lock ActivityManagerService here.
16212                if (filter.match(resolver, intent, true, TAG) >= 0) {
16213                    if (allSticky == null) {
16214                        allSticky = new ArrayList<Intent>();
16215                    }
16216                    allSticky.add(intent);
16217                }
16218            }
16219        }
16220
16221        // The first sticky in the list is returned directly back to the client.
16222        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16223        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16224        if (receiver == null) {
16225            return sticky;
16226        }
16227
16228        synchronized (this) {
16229            if (callerApp != null && (callerApp.thread == null
16230                    || callerApp.thread.asBinder() != caller.asBinder())) {
16231                // Original caller already died
16232                return null;
16233            }
16234            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16235            if (rl == null) {
16236                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16237                        userId, receiver);
16238                if (rl.app != null) {
16239                    rl.app.receivers.add(rl);
16240                } else {
16241                    try {
16242                        receiver.asBinder().linkToDeath(rl, 0);
16243                    } catch (RemoteException e) {
16244                        return sticky;
16245                    }
16246                    rl.linkedToDeath = true;
16247                }
16248                mRegisteredReceivers.put(receiver.asBinder(), rl);
16249            } else if (rl.uid != callingUid) {
16250                throw new IllegalArgumentException(
16251                        "Receiver requested to register for uid " + callingUid
16252                        + " was previously registered for uid " + rl.uid);
16253            } else if (rl.pid != callingPid) {
16254                throw new IllegalArgumentException(
16255                        "Receiver requested to register for pid " + callingPid
16256                        + " was previously registered for pid " + rl.pid);
16257            } else if (rl.userId != userId) {
16258                throw new IllegalArgumentException(
16259                        "Receiver requested to register for user " + userId
16260                        + " was previously registered for user " + rl.userId);
16261            }
16262            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16263                    permission, callingUid, userId);
16264            rl.add(bf);
16265            if (!bf.debugCheck()) {
16266                Slog.w(TAG, "==> For Dynamic broadcast");
16267            }
16268            mReceiverResolver.addFilter(bf);
16269
16270            // Enqueue broadcasts for all existing stickies that match
16271            // this filter.
16272            if (allSticky != null) {
16273                ArrayList receivers = new ArrayList();
16274                receivers.add(bf);
16275
16276                final int stickyCount = allSticky.size();
16277                for (int i = 0; i < stickyCount; i++) {
16278                    Intent intent = allSticky.get(i);
16279                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16280                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16281                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16282                            null, 0, null, null, false, true, true, -1);
16283                    queue.enqueueParallelBroadcastLocked(r);
16284                    queue.scheduleBroadcastsLocked();
16285                }
16286            }
16287
16288            return sticky;
16289        }
16290    }
16291
16292    public void unregisterReceiver(IIntentReceiver receiver) {
16293        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16294
16295        final long origId = Binder.clearCallingIdentity();
16296        try {
16297            boolean doTrim = false;
16298
16299            synchronized(this) {
16300                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16301                if (rl != null) {
16302                    final BroadcastRecord r = rl.curBroadcast;
16303                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16304                        final boolean doNext = r.queue.finishReceiverLocked(
16305                                r, r.resultCode, r.resultData, r.resultExtras,
16306                                r.resultAbort, false);
16307                        if (doNext) {
16308                            doTrim = true;
16309                            r.queue.processNextBroadcast(false);
16310                        }
16311                    }
16312
16313                    if (rl.app != null) {
16314                        rl.app.receivers.remove(rl);
16315                    }
16316                    removeReceiverLocked(rl);
16317                    if (rl.linkedToDeath) {
16318                        rl.linkedToDeath = false;
16319                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
16320                    }
16321                }
16322            }
16323
16324            // If we actually concluded any broadcasts, we might now be able
16325            // to trim the recipients' apps from our working set
16326            if (doTrim) {
16327                trimApplications();
16328                return;
16329            }
16330
16331        } finally {
16332            Binder.restoreCallingIdentity(origId);
16333        }
16334    }
16335
16336    void removeReceiverLocked(ReceiverList rl) {
16337        mRegisteredReceivers.remove(rl.receiver.asBinder());
16338        for (int i = rl.size() - 1; i >= 0; i--) {
16339            mReceiverResolver.removeFilter(rl.get(i));
16340        }
16341    }
16342
16343    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16344        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16345            ProcessRecord r = mLruProcesses.get(i);
16346            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16347                try {
16348                    r.thread.dispatchPackageBroadcast(cmd, packages);
16349                } catch (RemoteException ex) {
16350                }
16351            }
16352        }
16353    }
16354
16355    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16356            int callingUid, int[] users) {
16357        List<ResolveInfo> receivers = null;
16358        try {
16359            HashSet<ComponentName> singleUserReceivers = null;
16360            boolean scannedFirstReceivers = false;
16361            for (int user : users) {
16362                // Skip users that have Shell restrictions
16363                if (callingUid == Process.SHELL_UID
16364                        && getUserManagerLocked().hasUserRestriction(
16365                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
16366                    continue;
16367                }
16368                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16369                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
16370                if (user != UserHandle.USER_OWNER && newReceivers != null) {
16371                    // If this is not the primary user, we need to check for
16372                    // any receivers that should be filtered out.
16373                    for (int i=0; i<newReceivers.size(); i++) {
16374                        ResolveInfo ri = newReceivers.get(i);
16375                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
16376                            newReceivers.remove(i);
16377                            i--;
16378                        }
16379                    }
16380                }
16381                if (newReceivers != null && newReceivers.size() == 0) {
16382                    newReceivers = null;
16383                }
16384                if (receivers == null) {
16385                    receivers = newReceivers;
16386                } else if (newReceivers != null) {
16387                    // We need to concatenate the additional receivers
16388                    // found with what we have do far.  This would be easy,
16389                    // but we also need to de-dup any receivers that are
16390                    // singleUser.
16391                    if (!scannedFirstReceivers) {
16392                        // Collect any single user receivers we had already retrieved.
16393                        scannedFirstReceivers = true;
16394                        for (int i=0; i<receivers.size(); i++) {
16395                            ResolveInfo ri = receivers.get(i);
16396                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16397                                ComponentName cn = new ComponentName(
16398                                        ri.activityInfo.packageName, ri.activityInfo.name);
16399                                if (singleUserReceivers == null) {
16400                                    singleUserReceivers = new HashSet<ComponentName>();
16401                                }
16402                                singleUserReceivers.add(cn);
16403                            }
16404                        }
16405                    }
16406                    // Add the new results to the existing results, tracking
16407                    // and de-dupping single user receivers.
16408                    for (int i=0; i<newReceivers.size(); i++) {
16409                        ResolveInfo ri = newReceivers.get(i);
16410                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16411                            ComponentName cn = new ComponentName(
16412                                    ri.activityInfo.packageName, ri.activityInfo.name);
16413                            if (singleUserReceivers == null) {
16414                                singleUserReceivers = new HashSet<ComponentName>();
16415                            }
16416                            if (!singleUserReceivers.contains(cn)) {
16417                                singleUserReceivers.add(cn);
16418                                receivers.add(ri);
16419                            }
16420                        } else {
16421                            receivers.add(ri);
16422                        }
16423                    }
16424                }
16425            }
16426        } catch (RemoteException ex) {
16427            // pm is in same process, this will never happen.
16428        }
16429        return receivers;
16430    }
16431
16432    private final int broadcastIntentLocked(ProcessRecord callerApp,
16433            String callerPackage, Intent intent, String resolvedType,
16434            IIntentReceiver resultTo, int resultCode, String resultData,
16435            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle options,
16436            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
16437        intent = new Intent(intent);
16438
16439        // By default broadcasts do not go to stopped apps.
16440        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
16441
16442        // If we have not finished booting, don't allow this to launch new processes.
16443        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
16444            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16445        }
16446
16447        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
16448                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
16449                + " ordered=" + ordered + " userid=" + userId);
16450        if ((resultTo != null) && !ordered) {
16451            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
16452        }
16453
16454        userId = handleIncomingUser(callingPid, callingUid, userId,
16455                true, ALLOW_NON_FULL, "broadcast", callerPackage);
16456
16457        // Make sure that the user who is receiving this broadcast is running.
16458        // If not, we will just skip it. Make an exception for shutdown broadcasts
16459        // and upgrade steps.
16460
16461        if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
16462            if ((callingUid != Process.SYSTEM_UID
16463                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
16464                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
16465                Slog.w(TAG, "Skipping broadcast of " + intent
16466                        + ": user " + userId + " is stopped");
16467                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
16468            }
16469        }
16470
16471        BroadcastOptions brOptions = null;
16472        if (options != null) {
16473            brOptions = new BroadcastOptions(options);
16474            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
16475                // See if the caller is allowed to do this.  Note we are checking against
16476                // the actual real caller (not whoever provided the operation as say a
16477                // PendingIntent), because that who is actually supplied the arguments.
16478                if (checkComponentPermission(
16479                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
16480                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
16481                        != PackageManager.PERMISSION_GRANTED) {
16482                    String msg = "Permission Denial: " + intent.getAction()
16483                            + " broadcast from " + callerPackage + " (pid=" + callingPid
16484                            + ", uid=" + callingUid + ")"
16485                            + " requires "
16486                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
16487                    Slog.w(TAG, msg);
16488                    throw new SecurityException(msg);
16489                }
16490            }
16491        }
16492
16493        /*
16494         * Prevent non-system code (defined here to be non-persistent
16495         * processes) from sending protected broadcasts.
16496         */
16497        int callingAppId = UserHandle.getAppId(callingUid);
16498        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
16499            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
16500            || callingAppId == Process.NFC_UID || callingUid == 0) {
16501            // Always okay.
16502        } else if (callerApp == null || !callerApp.persistent) {
16503            try {
16504                if (AppGlobals.getPackageManager().isProtectedBroadcast(
16505                        intent.getAction())) {
16506                    String msg = "Permission Denial: not allowed to send broadcast "
16507                            + intent.getAction() + " from pid="
16508                            + callingPid + ", uid=" + callingUid;
16509                    Slog.w(TAG, msg);
16510                    throw new SecurityException(msg);
16511                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
16512                    // Special case for compatibility: we don't want apps to send this,
16513                    // but historically it has not been protected and apps may be using it
16514                    // to poke their own app widget.  So, instead of making it protected,
16515                    // just limit it to the caller.
16516                    if (callerApp == null) {
16517                        String msg = "Permission Denial: not allowed to send broadcast "
16518                                + intent.getAction() + " from unknown caller.";
16519                        Slog.w(TAG, msg);
16520                        throw new SecurityException(msg);
16521                    } else if (intent.getComponent() != null) {
16522                        // They are good enough to send to an explicit component...  verify
16523                        // it is being sent to the calling app.
16524                        if (!intent.getComponent().getPackageName().equals(
16525                                callerApp.info.packageName)) {
16526                            String msg = "Permission Denial: not allowed to send broadcast "
16527                                    + intent.getAction() + " to "
16528                                    + intent.getComponent().getPackageName() + " from "
16529                                    + callerApp.info.packageName;
16530                            Slog.w(TAG, msg);
16531                            throw new SecurityException(msg);
16532                        }
16533                    } else {
16534                        // Limit broadcast to their own package.
16535                        intent.setPackage(callerApp.info.packageName);
16536                    }
16537                }
16538            } catch (RemoteException e) {
16539                Slog.w(TAG, "Remote exception", e);
16540                return ActivityManager.BROADCAST_SUCCESS;
16541            }
16542        }
16543
16544        final String action = intent.getAction();
16545        if (action != null) {
16546            switch (action) {
16547                case Intent.ACTION_UID_REMOVED:
16548                case Intent.ACTION_PACKAGE_REMOVED:
16549                case Intent.ACTION_PACKAGE_CHANGED:
16550                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16551                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16552                    // Handle special intents: if this broadcast is from the package
16553                    // manager about a package being removed, we need to remove all of
16554                    // its activities from the history stack.
16555                    if (checkComponentPermission(
16556                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
16557                            callingPid, callingUid, -1, true)
16558                            != PackageManager.PERMISSION_GRANTED) {
16559                        String msg = "Permission Denial: " + intent.getAction()
16560                                + " broadcast from " + callerPackage + " (pid=" + callingPid
16561                                + ", uid=" + callingUid + ")"
16562                                + " requires "
16563                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
16564                        Slog.w(TAG, msg);
16565                        throw new SecurityException(msg);
16566                    }
16567                    switch (action) {
16568                        case Intent.ACTION_UID_REMOVED:
16569                            final Bundle intentExtras = intent.getExtras();
16570                            final int uid = intentExtras != null
16571                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
16572                            if (uid >= 0) {
16573                                mBatteryStatsService.removeUid(uid);
16574                                mAppOpsService.uidRemoved(uid);
16575                            }
16576                            break;
16577                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16578                            // If resources are unavailable just force stop all those packages
16579                            // and flush the attribute cache as well.
16580                            String list[] =
16581                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16582                            if (list != null && list.length > 0) {
16583                                for (int i = 0; i < list.length; i++) {
16584                                    forceStopPackageLocked(list[i], -1, false, true, true,
16585                                            false, false, userId, "storage unmount");
16586                                }
16587                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16588                                sendPackageBroadcastLocked(
16589                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
16590                                        userId);
16591                            }
16592                            break;
16593                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16594                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16595                            break;
16596                        case Intent.ACTION_PACKAGE_REMOVED:
16597                        case Intent.ACTION_PACKAGE_CHANGED:
16598                            Uri data = intent.getData();
16599                            String ssp;
16600                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
16601                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
16602                                boolean fullUninstall = removed &&
16603                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16604                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
16605                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
16606                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
16607                                            false, true, true, false, fullUninstall, userId,
16608                                            removed ? "pkg removed" : "pkg changed");
16609                                }
16610                                if (removed) {
16611                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
16612                                            new String[] {ssp}, userId);
16613                                    if (fullUninstall) {
16614                                        mAppOpsService.packageRemoved(
16615                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
16616
16617                                        // Remove all permissions granted from/to this package
16618                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
16619
16620                                        removeTasksByPackageNameLocked(ssp, userId);
16621                                        mBatteryStatsService.notePackageUninstalled(ssp);
16622                                    }
16623                                } else {
16624                                    cleanupDisabledPackageComponentsLocked(ssp, userId,
16625                                            intent.getStringArrayExtra(
16626                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
16627                                }
16628                            }
16629                            break;
16630                    }
16631                    break;
16632                case Intent.ACTION_PACKAGE_ADDED:
16633                    // Special case for adding a package: by default turn on compatibility mode.
16634                    Uri data = intent.getData();
16635                    String ssp;
16636                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
16637                        final boolean replacing =
16638                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16639                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
16640
16641                        try {
16642                            ApplicationInfo ai = AppGlobals.getPackageManager().
16643                                    getApplicationInfo(ssp, 0, 0);
16644                            mBatteryStatsService.notePackageInstalled(ssp,
16645                                    ai != null ? ai.versionCode : 0);
16646                        } catch (RemoteException e) {
16647                        }
16648                    }
16649                    break;
16650                case Intent.ACTION_TIMEZONE_CHANGED:
16651                    // If this is the time zone changed action, queue up a message that will reset
16652                    // the timezone of all currently running processes. This message will get
16653                    // queued up before the broadcast happens.
16654                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
16655                    break;
16656                case Intent.ACTION_TIME_CHANGED:
16657                    // If the user set the time, let all running processes know.
16658                    final int is24Hour =
16659                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
16660                                    : 0;
16661                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
16662                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16663                    synchronized (stats) {
16664                        stats.noteCurrentTimeChangedLocked();
16665                    }
16666                    break;
16667                case Intent.ACTION_CLEAR_DNS_CACHE:
16668                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
16669                    break;
16670                case Proxy.PROXY_CHANGE_ACTION:
16671                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
16672                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
16673                    break;
16674            }
16675        }
16676
16677        // Add to the sticky list if requested.
16678        if (sticky) {
16679            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
16680                    callingPid, callingUid)
16681                    != PackageManager.PERMISSION_GRANTED) {
16682                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
16683                        + callingPid + ", uid=" + callingUid
16684                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16685                Slog.w(TAG, msg);
16686                throw new SecurityException(msg);
16687            }
16688            if (requiredPermissions != null && requiredPermissions.length > 0) {
16689                Slog.w(TAG, "Can't broadcast sticky intent " + intent
16690                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
16691                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
16692            }
16693            if (intent.getComponent() != null) {
16694                throw new SecurityException(
16695                        "Sticky broadcasts can't target a specific component");
16696            }
16697            // We use userId directly here, since the "all" target is maintained
16698            // as a separate set of sticky broadcasts.
16699            if (userId != UserHandle.USER_ALL) {
16700                // But first, if this is not a broadcast to all users, then
16701                // make sure it doesn't conflict with an existing broadcast to
16702                // all users.
16703                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
16704                        UserHandle.USER_ALL);
16705                if (stickies != null) {
16706                    ArrayList<Intent> list = stickies.get(intent.getAction());
16707                    if (list != null) {
16708                        int N = list.size();
16709                        int i;
16710                        for (i=0; i<N; i++) {
16711                            if (intent.filterEquals(list.get(i))) {
16712                                throw new IllegalArgumentException(
16713                                        "Sticky broadcast " + intent + " for user "
16714                                        + userId + " conflicts with existing global broadcast");
16715                            }
16716                        }
16717                    }
16718                }
16719            }
16720            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16721            if (stickies == null) {
16722                stickies = new ArrayMap<>();
16723                mStickyBroadcasts.put(userId, stickies);
16724            }
16725            ArrayList<Intent> list = stickies.get(intent.getAction());
16726            if (list == null) {
16727                list = new ArrayList<>();
16728                stickies.put(intent.getAction(), list);
16729            }
16730            final int stickiesCount = list.size();
16731            int i;
16732            for (i = 0; i < stickiesCount; i++) {
16733                if (intent.filterEquals(list.get(i))) {
16734                    // This sticky already exists, replace it.
16735                    list.set(i, new Intent(intent));
16736                    break;
16737                }
16738            }
16739            if (i >= stickiesCount) {
16740                list.add(new Intent(intent));
16741            }
16742        }
16743
16744        int[] users;
16745        if (userId == UserHandle.USER_ALL) {
16746            // Caller wants broadcast to go to all started users.
16747            users = mStartedUserArray;
16748        } else {
16749            // Caller wants broadcast to go to one specific user.
16750            users = new int[] {userId};
16751        }
16752
16753        // Figure out who all will receive this broadcast.
16754        List receivers = null;
16755        List<BroadcastFilter> registeredReceivers = null;
16756        // Need to resolve the intent to interested receivers...
16757        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
16758                 == 0) {
16759            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
16760        }
16761        if (intent.getComponent() == null) {
16762            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
16763                // Query one target user at a time, excluding shell-restricted users
16764                UserManagerService ums = getUserManagerLocked();
16765                for (int i = 0; i < users.length; i++) {
16766                    if (ums.hasUserRestriction(
16767                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
16768                        continue;
16769                    }
16770                    List<BroadcastFilter> registeredReceiversForUser =
16771                            mReceiverResolver.queryIntent(intent,
16772                                    resolvedType, false, users[i]);
16773                    if (registeredReceivers == null) {
16774                        registeredReceivers = registeredReceiversForUser;
16775                    } else if (registeredReceiversForUser != null) {
16776                        registeredReceivers.addAll(registeredReceiversForUser);
16777                    }
16778                }
16779            } else {
16780                registeredReceivers = mReceiverResolver.queryIntent(intent,
16781                        resolvedType, false, userId);
16782            }
16783        }
16784
16785        final boolean replacePending =
16786                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16787
16788        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
16789                + " replacePending=" + replacePending);
16790
16791        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16792        if (!ordered && NR > 0) {
16793            // If we are not serializing this broadcast, then send the
16794            // registered receivers separately so they don't wait for the
16795            // components to be launched.
16796            final BroadcastQueue queue = broadcastQueueForIntent(intent);
16797            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16798                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
16799                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
16800                    resultExtras, ordered, sticky, false, userId);
16801            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
16802            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16803            if (!replaced) {
16804                queue.enqueueParallelBroadcastLocked(r);
16805                queue.scheduleBroadcastsLocked();
16806            }
16807            registeredReceivers = null;
16808            NR = 0;
16809        }
16810
16811        // Merge into one list.
16812        int ir = 0;
16813        if (receivers != null) {
16814            // A special case for PACKAGE_ADDED: do not allow the package
16815            // being added to see this broadcast.  This prevents them from
16816            // using this as a back door to get run as soon as they are
16817            // installed.  Maybe in the future we want to have a special install
16818            // broadcast or such for apps, but we'd like to deliberately make
16819            // this decision.
16820            String skipPackages[] = null;
16821            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16822                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16823                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16824                Uri data = intent.getData();
16825                if (data != null) {
16826                    String pkgName = data.getSchemeSpecificPart();
16827                    if (pkgName != null) {
16828                        skipPackages = new String[] { pkgName };
16829                    }
16830                }
16831            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16832                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16833            }
16834            if (skipPackages != null && (skipPackages.length > 0)) {
16835                for (String skipPackage : skipPackages) {
16836                    if (skipPackage != null) {
16837                        int NT = receivers.size();
16838                        for (int it=0; it<NT; it++) {
16839                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
16840                            if (curt.activityInfo.packageName.equals(skipPackage)) {
16841                                receivers.remove(it);
16842                                it--;
16843                                NT--;
16844                            }
16845                        }
16846                    }
16847                }
16848            }
16849
16850            int NT = receivers != null ? receivers.size() : 0;
16851            int it = 0;
16852            ResolveInfo curt = null;
16853            BroadcastFilter curr = null;
16854            while (it < NT && ir < NR) {
16855                if (curt == null) {
16856                    curt = (ResolveInfo)receivers.get(it);
16857                }
16858                if (curr == null) {
16859                    curr = registeredReceivers.get(ir);
16860                }
16861                if (curr.getPriority() >= curt.priority) {
16862                    // Insert this broadcast record into the final list.
16863                    receivers.add(it, curr);
16864                    ir++;
16865                    curr = null;
16866                    it++;
16867                    NT++;
16868                } else {
16869                    // Skip to the next ResolveInfo in the final list.
16870                    it++;
16871                    curt = null;
16872                }
16873            }
16874        }
16875        while (ir < NR) {
16876            if (receivers == null) {
16877                receivers = new ArrayList();
16878            }
16879            receivers.add(registeredReceivers.get(ir));
16880            ir++;
16881        }
16882
16883        if ((receivers != null && receivers.size() > 0)
16884                || resultTo != null) {
16885            BroadcastQueue queue = broadcastQueueForIntent(intent);
16886            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16887                    callerPackage, callingPid, callingUid, resolvedType,
16888                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
16889                    resultData, resultExtras, ordered, sticky, false, userId);
16890
16891            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
16892                    + ": prev had " + queue.mOrderedBroadcasts.size());
16893            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
16894                    "Enqueueing broadcast " + r.intent.getAction());
16895
16896            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16897            if (!replaced) {
16898                queue.enqueueOrderedBroadcastLocked(r);
16899                queue.scheduleBroadcastsLocked();
16900            }
16901        }
16902
16903        return ActivityManager.BROADCAST_SUCCESS;
16904    }
16905
16906    final Intent verifyBroadcastLocked(Intent intent) {
16907        // Refuse possible leaked file descriptors
16908        if (intent != null && intent.hasFileDescriptors() == true) {
16909            throw new IllegalArgumentException("File descriptors passed in Intent");
16910        }
16911
16912        int flags = intent.getFlags();
16913
16914        if (!mProcessesReady) {
16915            // if the caller really truly claims to know what they're doing, go
16916            // ahead and allow the broadcast without launching any receivers
16917            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16918                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
16919            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16920                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16921                        + " before boot completion");
16922                throw new IllegalStateException("Cannot broadcast before boot completed");
16923            }
16924        }
16925
16926        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16927            throw new IllegalArgumentException(
16928                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16929        }
16930
16931        return intent;
16932    }
16933
16934    public final int broadcastIntent(IApplicationThread caller,
16935            Intent intent, String resolvedType, IIntentReceiver resultTo,
16936            int resultCode, String resultData, Bundle resultExtras,
16937            String[] requiredPermissions, int appOp, Bundle options,
16938            boolean serialized, boolean sticky, int userId) {
16939        enforceNotIsolatedCaller("broadcastIntent");
16940        synchronized(this) {
16941            intent = verifyBroadcastLocked(intent);
16942
16943            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16944            final int callingPid = Binder.getCallingPid();
16945            final int callingUid = Binder.getCallingUid();
16946            final long origId = Binder.clearCallingIdentity();
16947            int res = broadcastIntentLocked(callerApp,
16948                    callerApp != null ? callerApp.info.packageName : null,
16949                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
16950                    requiredPermissions, appOp, null, serialized, sticky,
16951                    callingPid, callingUid, userId);
16952            Binder.restoreCallingIdentity(origId);
16953            return res;
16954        }
16955    }
16956
16957
16958    int broadcastIntentInPackage(String packageName, int uid,
16959            Intent intent, String resolvedType, IIntentReceiver resultTo,
16960            int resultCode, String resultData, Bundle resultExtras,
16961            String requiredPermission, Bundle options, boolean serialized, boolean sticky,
16962            int userId) {
16963        synchronized(this) {
16964            intent = verifyBroadcastLocked(intent);
16965
16966            final long origId = Binder.clearCallingIdentity();
16967            String[] requiredPermissions = requiredPermission == null ? null
16968                    : new String[] {requiredPermission};
16969            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16970                    resultTo, resultCode, resultData, resultExtras,
16971                    requiredPermissions, AppOpsManager.OP_NONE, options, serialized,
16972                    sticky, -1, uid, userId);
16973            Binder.restoreCallingIdentity(origId);
16974            return res;
16975        }
16976    }
16977
16978    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16979        // Refuse possible leaked file descriptors
16980        if (intent != null && intent.hasFileDescriptors() == true) {
16981            throw new IllegalArgumentException("File descriptors passed in Intent");
16982        }
16983
16984        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16985                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16986
16987        synchronized(this) {
16988            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16989                    != PackageManager.PERMISSION_GRANTED) {
16990                String msg = "Permission Denial: unbroadcastIntent() from pid="
16991                        + Binder.getCallingPid()
16992                        + ", uid=" + Binder.getCallingUid()
16993                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16994                Slog.w(TAG, msg);
16995                throw new SecurityException(msg);
16996            }
16997            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16998            if (stickies != null) {
16999                ArrayList<Intent> list = stickies.get(intent.getAction());
17000                if (list != null) {
17001                    int N = list.size();
17002                    int i;
17003                    for (i=0; i<N; i++) {
17004                        if (intent.filterEquals(list.get(i))) {
17005                            list.remove(i);
17006                            break;
17007                        }
17008                    }
17009                    if (list.size() <= 0) {
17010                        stickies.remove(intent.getAction());
17011                    }
17012                }
17013                if (stickies.size() <= 0) {
17014                    mStickyBroadcasts.remove(userId);
17015                }
17016            }
17017        }
17018    }
17019
17020    void backgroundServicesFinishedLocked(int userId) {
17021        for (BroadcastQueue queue : mBroadcastQueues) {
17022            queue.backgroundServicesFinishedLocked(userId);
17023        }
17024    }
17025
17026    public void finishReceiver(IBinder who, int resultCode, String resultData,
17027            Bundle resultExtras, boolean resultAbort, int flags) {
17028        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17029
17030        // Refuse possible leaked file descriptors
17031        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17032            throw new IllegalArgumentException("File descriptors passed in Bundle");
17033        }
17034
17035        final long origId = Binder.clearCallingIdentity();
17036        try {
17037            boolean doNext = false;
17038            BroadcastRecord r;
17039
17040            synchronized(this) {
17041                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17042                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17043                r = queue.getMatchingOrderedReceiver(who);
17044                if (r != null) {
17045                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17046                        resultData, resultExtras, resultAbort, true);
17047                }
17048            }
17049
17050            if (doNext) {
17051                r.queue.processNextBroadcast(false);
17052            }
17053            trimApplications();
17054        } finally {
17055            Binder.restoreCallingIdentity(origId);
17056        }
17057    }
17058
17059    // =========================================================
17060    // INSTRUMENTATION
17061    // =========================================================
17062
17063    public boolean startInstrumentation(ComponentName className,
17064            String profileFile, int flags, Bundle arguments,
17065            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17066            int userId, String abiOverride) {
17067        enforceNotIsolatedCaller("startInstrumentation");
17068        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17069                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17070        // Refuse possible leaked file descriptors
17071        if (arguments != null && arguments.hasFileDescriptors()) {
17072            throw new IllegalArgumentException("File descriptors passed in Bundle");
17073        }
17074
17075        synchronized(this) {
17076            InstrumentationInfo ii = null;
17077            ApplicationInfo ai = null;
17078            try {
17079                ii = mContext.getPackageManager().getInstrumentationInfo(
17080                    className, STOCK_PM_FLAGS);
17081                ai = AppGlobals.getPackageManager().getApplicationInfo(
17082                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17083            } catch (PackageManager.NameNotFoundException e) {
17084            } catch (RemoteException e) {
17085            }
17086            if (ii == null) {
17087                reportStartInstrumentationFailure(watcher, className,
17088                        "Unable to find instrumentation info for: " + className);
17089                return false;
17090            }
17091            if (ai == null) {
17092                reportStartInstrumentationFailure(watcher, className,
17093                        "Unable to find instrumentation target package: " + ii.targetPackage);
17094                return false;
17095            }
17096
17097            int match = mContext.getPackageManager().checkSignatures(
17098                    ii.targetPackage, ii.packageName);
17099            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17100                String msg = "Permission Denial: starting instrumentation "
17101                        + className + " from pid="
17102                        + Binder.getCallingPid()
17103                        + ", uid=" + Binder.getCallingPid()
17104                        + " not allowed because package " + ii.packageName
17105                        + " does not have a signature matching the target "
17106                        + ii.targetPackage;
17107                reportStartInstrumentationFailure(watcher, className, msg);
17108                throw new SecurityException(msg);
17109            }
17110
17111            final long origId = Binder.clearCallingIdentity();
17112            // Instrumentation can kill and relaunch even persistent processes
17113            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17114                    "start instr");
17115            ProcessRecord app = addAppLocked(ai, false, abiOverride);
17116            app.instrumentationClass = className;
17117            app.instrumentationInfo = ai;
17118            app.instrumentationProfileFile = profileFile;
17119            app.instrumentationArguments = arguments;
17120            app.instrumentationWatcher = watcher;
17121            app.instrumentationUiAutomationConnection = uiAutomationConnection;
17122            app.instrumentationResultClass = className;
17123            Binder.restoreCallingIdentity(origId);
17124        }
17125
17126        return true;
17127    }
17128
17129    /**
17130     * Report errors that occur while attempting to start Instrumentation.  Always writes the
17131     * error to the logs, but if somebody is watching, send the report there too.  This enables
17132     * the "am" command to report errors with more information.
17133     *
17134     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17135     * @param cn The component name of the instrumentation.
17136     * @param report The error report.
17137     */
17138    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
17139            ComponentName cn, String report) {
17140        Slog.w(TAG, report);
17141        try {
17142            if (watcher != null) {
17143                Bundle results = new Bundle();
17144                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17145                results.putString("Error", report);
17146                watcher.instrumentationStatus(cn, -1, results);
17147            }
17148        } catch (RemoteException e) {
17149            Slog.w(TAG, e);
17150        }
17151    }
17152
17153    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17154        if (app.instrumentationWatcher != null) {
17155            try {
17156                // NOTE:  IInstrumentationWatcher *must* be oneway here
17157                app.instrumentationWatcher.instrumentationFinished(
17158                    app.instrumentationClass,
17159                    resultCode,
17160                    results);
17161            } catch (RemoteException e) {
17162            }
17163        }
17164
17165        // Can't call out of the system process with a lock held, so post a message.
17166        mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17167                app.instrumentationUiAutomationConnection).sendToTarget();
17168
17169        app.instrumentationWatcher = null;
17170        app.instrumentationUiAutomationConnection = null;
17171        app.instrumentationClass = null;
17172        app.instrumentationInfo = null;
17173        app.instrumentationProfileFile = null;
17174        app.instrumentationArguments = null;
17175
17176        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17177                "finished inst");
17178    }
17179
17180    public void finishInstrumentation(IApplicationThread target,
17181            int resultCode, Bundle results) {
17182        int userId = UserHandle.getCallingUserId();
17183        // Refuse possible leaked file descriptors
17184        if (results != null && results.hasFileDescriptors()) {
17185            throw new IllegalArgumentException("File descriptors passed in Intent");
17186        }
17187
17188        synchronized(this) {
17189            ProcessRecord app = getRecordForAppLocked(target);
17190            if (app == null) {
17191                Slog.w(TAG, "finishInstrumentation: no app for " + target);
17192                return;
17193            }
17194            final long origId = Binder.clearCallingIdentity();
17195            finishInstrumentationLocked(app, resultCode, results);
17196            Binder.restoreCallingIdentity(origId);
17197        }
17198    }
17199
17200    // =========================================================
17201    // CONFIGURATION
17202    // =========================================================
17203
17204    public ConfigurationInfo getDeviceConfigurationInfo() {
17205        ConfigurationInfo config = new ConfigurationInfo();
17206        synchronized (this) {
17207            config.reqTouchScreen = mConfiguration.touchscreen;
17208            config.reqKeyboardType = mConfiguration.keyboard;
17209            config.reqNavigation = mConfiguration.navigation;
17210            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17211                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17212                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17213            }
17214            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17215                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17216                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17217            }
17218            config.reqGlEsVersion = GL_ES_VERSION;
17219        }
17220        return config;
17221    }
17222
17223    ActivityStack getFocusedStack() {
17224        return mStackSupervisor.getFocusedStack();
17225    }
17226
17227    @Override
17228    public int getFocusedStackId() throws RemoteException {
17229        ActivityStack focusedStack = getFocusedStack();
17230        if (focusedStack != null) {
17231            return focusedStack.getStackId();
17232        }
17233        return -1;
17234    }
17235
17236    public Configuration getConfiguration() {
17237        Configuration ci;
17238        synchronized(this) {
17239            ci = new Configuration(mConfiguration);
17240            ci.userSetLocale = false;
17241        }
17242        return ci;
17243    }
17244
17245    public void updatePersistentConfiguration(Configuration values) {
17246        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17247                "updateConfiguration()");
17248        enforceWriteSettingsPermission("updateConfiguration()");
17249        if (values == null) {
17250            throw new NullPointerException("Configuration must not be null");
17251        }
17252
17253        synchronized(this) {
17254            final long origId = Binder.clearCallingIdentity();
17255            updateConfigurationLocked(values, null, true, false);
17256            Binder.restoreCallingIdentity(origId);
17257        }
17258    }
17259
17260    private void enforceWriteSettingsPermission(String func) {
17261        int uid = Binder.getCallingUid();
17262        if (uid == Process.ROOT_UID) {
17263            return;
17264        }
17265
17266        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
17267                Settings.getPackageNameForUid(mContext, uid), false)) {
17268            return;
17269        }
17270
17271        String msg = "Permission Denial: " + func + " from pid="
17272                + Binder.getCallingPid()
17273                + ", uid=" + uid
17274                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
17275        Slog.w(TAG, msg);
17276        throw new SecurityException(msg);
17277    }
17278
17279    public void updateConfiguration(Configuration values) {
17280        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17281                "updateConfiguration()");
17282
17283        synchronized(this) {
17284            if (values == null && mWindowManager != null) {
17285                // sentinel: fetch the current configuration from the window manager
17286                values = mWindowManager.computeNewConfiguration();
17287            }
17288
17289            if (mWindowManager != null) {
17290                mProcessList.applyDisplaySize(mWindowManager);
17291            }
17292
17293            final long origId = Binder.clearCallingIdentity();
17294            if (values != null) {
17295                Settings.System.clearConfiguration(values);
17296            }
17297            updateConfigurationLocked(values, null, false, false);
17298            Binder.restoreCallingIdentity(origId);
17299        }
17300    }
17301
17302    /**
17303     * Do either or both things: (1) change the current configuration, and (2)
17304     * make sure the given activity is running with the (now) current
17305     * configuration.  Returns true if the activity has been left running, or
17306     * false if <var>starting</var> is being destroyed to match the new
17307     * configuration.
17308     * @param persistent TODO
17309     */
17310    boolean updateConfigurationLocked(Configuration values,
17311            ActivityRecord starting, boolean persistent, boolean initLocale) {
17312        int changes = 0;
17313
17314        if (values != null) {
17315            Configuration newConfig = new Configuration(mConfiguration);
17316            changes = newConfig.updateFrom(values);
17317            if (changes != 0) {
17318                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
17319                        "Updating configuration to: " + values);
17320
17321                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
17322
17323                if (!initLocale && values.locale != null && values.userSetLocale) {
17324                    final String languageTag = values.locale.toLanguageTag();
17325                    SystemProperties.set("persist.sys.locale", languageTag);
17326                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
17327                            values.locale));
17328                }
17329
17330                mConfigurationSeq++;
17331                if (mConfigurationSeq <= 0) {
17332                    mConfigurationSeq = 1;
17333                }
17334                newConfig.seq = mConfigurationSeq;
17335                mConfiguration = newConfig;
17336                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
17337                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
17338                //mUsageStatsService.noteStartConfig(newConfig);
17339
17340                final Configuration configCopy = new Configuration(mConfiguration);
17341
17342                // TODO: If our config changes, should we auto dismiss any currently
17343                // showing dialogs?
17344                mShowDialogs = shouldShowDialogs(newConfig);
17345
17346                AttributeCache ac = AttributeCache.instance();
17347                if (ac != null) {
17348                    ac.updateConfiguration(configCopy);
17349                }
17350
17351                // Make sure all resources in our process are updated
17352                // right now, so that anyone who is going to retrieve
17353                // resource values after we return will be sure to get
17354                // the new ones.  This is especially important during
17355                // boot, where the first config change needs to guarantee
17356                // all resources have that config before following boot
17357                // code is executed.
17358                mSystemThread.applyConfigurationToResources(configCopy);
17359
17360                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
17361                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
17362                    msg.obj = new Configuration(configCopy);
17363                    mHandler.sendMessage(msg);
17364                }
17365
17366                for (int i=mLruProcesses.size()-1; i>=0; i--) {
17367                    ProcessRecord app = mLruProcesses.get(i);
17368                    try {
17369                        if (app.thread != null) {
17370                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
17371                                    + app.processName + " new config " + mConfiguration);
17372                            app.thread.scheduleConfigurationChanged(configCopy);
17373                        }
17374                    } catch (Exception e) {
17375                    }
17376                }
17377                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
17378                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17379                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
17380                        | Intent.FLAG_RECEIVER_FOREGROUND);
17381                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
17382                        null, AppOpsManager.OP_NONE, null, false, false,
17383                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17384                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
17385                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
17386                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17387                    if (!mProcessesReady) {
17388                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17389                    }
17390                    broadcastIntentLocked(null, null, intent,
17391                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17392                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17393                }
17394            }
17395        }
17396
17397        boolean kept = true;
17398        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
17399        // mainStack is null during startup.
17400        if (mainStack != null) {
17401            if (changes != 0 && starting == null) {
17402                // If the configuration changed, and the caller is not already
17403                // in the process of starting an activity, then find the top
17404                // activity to check if its configuration needs to change.
17405                starting = mainStack.topRunningActivityLocked(null);
17406            }
17407
17408            if (starting != null) {
17409                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
17410                // And we need to make sure at this point that all other activities
17411                // are made visible with the correct configuration.
17412                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
17413            }
17414        }
17415
17416        if (values != null && mWindowManager != null) {
17417            mWindowManager.setNewConfiguration(mConfiguration);
17418        }
17419
17420        return kept;
17421    }
17422
17423    /**
17424     * Decide based on the configuration whether we should shouw the ANR,
17425     * crash, etc dialogs.  The idea is that if there is no affordnace to
17426     * press the on-screen buttons, we shouldn't show the dialog.
17427     *
17428     * A thought: SystemUI might also want to get told about this, the Power
17429     * dialog / global actions also might want different behaviors.
17430     */
17431    private static final boolean shouldShowDialogs(Configuration config) {
17432        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
17433                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
17434                && config.navigation == Configuration.NAVIGATION_NONAV);
17435    }
17436
17437    @Override
17438    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
17439        synchronized (this) {
17440            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
17441            if (srec != null) {
17442                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
17443            }
17444        }
17445        return false;
17446    }
17447
17448    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
17449            Intent resultData) {
17450
17451        synchronized (this) {
17452            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
17453            if (r != null) {
17454                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
17455            }
17456            return false;
17457        }
17458    }
17459
17460    public int getLaunchedFromUid(IBinder activityToken) {
17461        ActivityRecord srec;
17462        synchronized (this) {
17463            srec = ActivityRecord.forTokenLocked(activityToken);
17464        }
17465        if (srec == null) {
17466            return -1;
17467        }
17468        return srec.launchedFromUid;
17469    }
17470
17471    public String getLaunchedFromPackage(IBinder activityToken) {
17472        ActivityRecord srec;
17473        synchronized (this) {
17474            srec = ActivityRecord.forTokenLocked(activityToken);
17475        }
17476        if (srec == null) {
17477            return null;
17478        }
17479        return srec.launchedFromPackage;
17480    }
17481
17482    // =========================================================
17483    // LIFETIME MANAGEMENT
17484    // =========================================================
17485
17486    // Returns which broadcast queue the app is the current [or imminent] receiver
17487    // on, or 'null' if the app is not an active broadcast recipient.
17488    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
17489        BroadcastRecord r = app.curReceiver;
17490        if (r != null) {
17491            return r.queue;
17492        }
17493
17494        // It's not the current receiver, but it might be starting up to become one
17495        synchronized (this) {
17496            for (BroadcastQueue queue : mBroadcastQueues) {
17497                r = queue.mPendingBroadcast;
17498                if (r != null && r.curApp == app) {
17499                    // found it; report which queue it's in
17500                    return queue;
17501                }
17502            }
17503        }
17504
17505        return null;
17506    }
17507
17508    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17509            ComponentName targetComponent, String targetProcess) {
17510        if (!mTrackingAssociations) {
17511            return null;
17512        }
17513        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17514                = mAssociations.get(targetUid);
17515        if (components == null) {
17516            components = new ArrayMap<>();
17517            mAssociations.put(targetUid, components);
17518        }
17519        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17520        if (sourceUids == null) {
17521            sourceUids = new SparseArray<>();
17522            components.put(targetComponent, sourceUids);
17523        }
17524        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17525        if (sourceProcesses == null) {
17526            sourceProcesses = new ArrayMap<>();
17527            sourceUids.put(sourceUid, sourceProcesses);
17528        }
17529        Association ass = sourceProcesses.get(sourceProcess);
17530        if (ass == null) {
17531            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
17532                    targetProcess);
17533            sourceProcesses.put(sourceProcess, ass);
17534        }
17535        ass.mCount++;
17536        ass.mNesting++;
17537        if (ass.mNesting == 1) {
17538            ass.mStartTime = SystemClock.uptimeMillis();
17539        }
17540        return ass;
17541    }
17542
17543    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17544            ComponentName targetComponent) {
17545        if (!mTrackingAssociations) {
17546            return;
17547        }
17548        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17549                = mAssociations.get(targetUid);
17550        if (components == null) {
17551            return;
17552        }
17553        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17554        if (sourceUids == null) {
17555            return;
17556        }
17557        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17558        if (sourceProcesses == null) {
17559            return;
17560        }
17561        Association ass = sourceProcesses.get(sourceProcess);
17562        if (ass == null || ass.mNesting <= 0) {
17563            return;
17564        }
17565        ass.mNesting--;
17566        if (ass.mNesting == 0) {
17567            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
17568        }
17569    }
17570
17571    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
17572            boolean doingAll, long now) {
17573        if (mAdjSeq == app.adjSeq) {
17574            // This adjustment has already been computed.
17575            return app.curRawAdj;
17576        }
17577
17578        if (app.thread == null) {
17579            app.adjSeq = mAdjSeq;
17580            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17581            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17582            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
17583        }
17584
17585        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
17586        app.adjSource = null;
17587        app.adjTarget = null;
17588        app.empty = false;
17589        app.cached = false;
17590
17591        final int activitiesSize = app.activities.size();
17592
17593        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17594            // The max adjustment doesn't allow this app to be anything
17595            // below foreground, so it is not worth doing work for it.
17596            app.adjType = "fixed";
17597            app.adjSeq = mAdjSeq;
17598            app.curRawAdj = app.maxAdj;
17599            app.foregroundActivities = false;
17600            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
17601            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
17602            // System processes can do UI, and when they do we want to have
17603            // them trim their memory after the user leaves the UI.  To
17604            // facilitate this, here we need to determine whether or not it
17605            // is currently showing UI.
17606            app.systemNoUi = true;
17607            if (app == TOP_APP) {
17608                app.systemNoUi = false;
17609            } else if (activitiesSize > 0) {
17610                for (int j = 0; j < activitiesSize; j++) {
17611                    final ActivityRecord r = app.activities.get(j);
17612                    if (r.visible) {
17613                        app.systemNoUi = false;
17614                    }
17615                }
17616            }
17617            if (!app.systemNoUi) {
17618                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
17619            }
17620            return (app.curAdj=app.maxAdj);
17621        }
17622
17623        app.systemNoUi = false;
17624
17625        final int PROCESS_STATE_TOP = mTopProcessState;
17626
17627        // Determine the importance of the process, starting with most
17628        // important to least, and assign an appropriate OOM adjustment.
17629        int adj;
17630        int schedGroup;
17631        int procState;
17632        boolean foregroundActivities = false;
17633        BroadcastQueue queue;
17634        if (app == TOP_APP) {
17635            // The last app on the list is the foreground app.
17636            adj = ProcessList.FOREGROUND_APP_ADJ;
17637            schedGroup = Process.THREAD_GROUP_DEFAULT;
17638            app.adjType = "top-activity";
17639            foregroundActivities = true;
17640            procState = PROCESS_STATE_TOP;
17641        } else if (app.instrumentationClass != null) {
17642            // Don't want to kill running instrumentation.
17643            adj = ProcessList.FOREGROUND_APP_ADJ;
17644            schedGroup = Process.THREAD_GROUP_DEFAULT;
17645            app.adjType = "instrumentation";
17646            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17647        } else if ((queue = isReceivingBroadcast(app)) != null) {
17648            // An app that is currently receiving a broadcast also
17649            // counts as being in the foreground for OOM killer purposes.
17650            // It's placed in a sched group based on the nature of the
17651            // broadcast as reflected by which queue it's active in.
17652            adj = ProcessList.FOREGROUND_APP_ADJ;
17653            schedGroup = (queue == mFgBroadcastQueue)
17654                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17655            app.adjType = "broadcast";
17656            procState = ActivityManager.PROCESS_STATE_RECEIVER;
17657        } else if (app.executingServices.size() > 0) {
17658            // An app that is currently executing a service callback also
17659            // counts as being in the foreground.
17660            adj = ProcessList.FOREGROUND_APP_ADJ;
17661            schedGroup = app.execServicesFg ?
17662                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17663            app.adjType = "exec-service";
17664            procState = ActivityManager.PROCESS_STATE_SERVICE;
17665            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
17666        } else {
17667            // As far as we know the process is empty.  We may change our mind later.
17668            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17669            // At this point we don't actually know the adjustment.  Use the cached adj
17670            // value that the caller wants us to.
17671            adj = cachedAdj;
17672            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17673            app.cached = true;
17674            app.empty = true;
17675            app.adjType = "cch-empty";
17676        }
17677
17678        // Examine all activities if not already foreground.
17679        if (!foregroundActivities && activitiesSize > 0) {
17680            for (int j = 0; j < activitiesSize; j++) {
17681                final ActivityRecord r = app.activities.get(j);
17682                if (r.app != app) {
17683                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
17684                            + app + "?!? Using " + r.app + " instead.");
17685                    continue;
17686                }
17687                if (r.visible) {
17688                    // App has a visible activity; only upgrade adjustment.
17689                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17690                        adj = ProcessList.VISIBLE_APP_ADJ;
17691                        app.adjType = "visible";
17692                    }
17693                    if (procState > PROCESS_STATE_TOP) {
17694                        procState = PROCESS_STATE_TOP;
17695                    }
17696                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17697                    app.cached = false;
17698                    app.empty = false;
17699                    foregroundActivities = true;
17700                    break;
17701                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
17702                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17703                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17704                        app.adjType = "pausing";
17705                    }
17706                    if (procState > PROCESS_STATE_TOP) {
17707                        procState = PROCESS_STATE_TOP;
17708                    }
17709                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17710                    app.cached = false;
17711                    app.empty = false;
17712                    foregroundActivities = true;
17713                } else if (r.state == ActivityState.STOPPING) {
17714                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17715                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17716                        app.adjType = "stopping";
17717                    }
17718                    // For the process state, we will at this point consider the
17719                    // process to be cached.  It will be cached either as an activity
17720                    // or empty depending on whether the activity is finishing.  We do
17721                    // this so that we can treat the process as cached for purposes of
17722                    // memory trimming (determing current memory level, trim command to
17723                    // send to process) since there can be an arbitrary number of stopping
17724                    // processes and they should soon all go into the cached state.
17725                    if (!r.finishing) {
17726                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17727                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17728                        }
17729                    }
17730                    app.cached = false;
17731                    app.empty = false;
17732                    foregroundActivities = true;
17733                } else {
17734                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17735                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17736                        app.adjType = "cch-act";
17737                    }
17738                }
17739            }
17740        }
17741
17742        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17743            if (app.foregroundServices) {
17744                // The user is aware of this app, so make it visible.
17745                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17746                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17747                app.cached = false;
17748                app.adjType = "fg-service";
17749                schedGroup = Process.THREAD_GROUP_DEFAULT;
17750            } else if (app.forcingToForeground != null) {
17751                // The user is aware of this app, so make it visible.
17752                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17753                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17754                app.cached = false;
17755                app.adjType = "force-fg";
17756                app.adjSource = app.forcingToForeground;
17757                schedGroup = Process.THREAD_GROUP_DEFAULT;
17758            }
17759        }
17760
17761        if (app == mHeavyWeightProcess) {
17762            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
17763                // We don't want to kill the current heavy-weight process.
17764                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
17765                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17766                app.cached = false;
17767                app.adjType = "heavy";
17768            }
17769            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17770                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
17771            }
17772        }
17773
17774        if (app == mHomeProcess) {
17775            if (adj > ProcessList.HOME_APP_ADJ) {
17776                // This process is hosting what we currently consider to be the
17777                // home app, so we don't want to let it go into the background.
17778                adj = ProcessList.HOME_APP_ADJ;
17779                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17780                app.cached = false;
17781                app.adjType = "home";
17782            }
17783            if (procState > ActivityManager.PROCESS_STATE_HOME) {
17784                procState = ActivityManager.PROCESS_STATE_HOME;
17785            }
17786        }
17787
17788        if (app == mPreviousProcess && app.activities.size() > 0) {
17789            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
17790                // This was the previous process that showed UI to the user.
17791                // We want to try to keep it around more aggressively, to give
17792                // a good experience around switching between two apps.
17793                adj = ProcessList.PREVIOUS_APP_ADJ;
17794                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17795                app.cached = false;
17796                app.adjType = "previous";
17797            }
17798            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17799                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17800            }
17801        }
17802
17803        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
17804                + " reason=" + app.adjType);
17805
17806        // By default, we use the computed adjustment.  It may be changed if
17807        // there are applications dependent on our services or providers, but
17808        // this gives us a baseline and makes sure we don't get into an
17809        // infinite recursion.
17810        app.adjSeq = mAdjSeq;
17811        app.curRawAdj = adj;
17812        app.hasStartedServices = false;
17813
17814        if (mBackupTarget != null && app == mBackupTarget.app) {
17815            // If possible we want to avoid killing apps while they're being backed up
17816            if (adj > ProcessList.BACKUP_APP_ADJ) {
17817                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
17818                adj = ProcessList.BACKUP_APP_ADJ;
17819                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17820                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17821                }
17822                app.adjType = "backup";
17823                app.cached = false;
17824            }
17825            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
17826                procState = ActivityManager.PROCESS_STATE_BACKUP;
17827            }
17828        }
17829
17830        boolean mayBeTop = false;
17831
17832        for (int is = app.services.size()-1;
17833                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17834                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17835                        || procState > ActivityManager.PROCESS_STATE_TOP);
17836                is--) {
17837            ServiceRecord s = app.services.valueAt(is);
17838            if (s.startRequested) {
17839                app.hasStartedServices = true;
17840                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
17841                    procState = ActivityManager.PROCESS_STATE_SERVICE;
17842                }
17843                if (app.hasShownUi && app != mHomeProcess) {
17844                    // If this process has shown some UI, let it immediately
17845                    // go to the LRU list because it may be pretty heavy with
17846                    // UI stuff.  We'll tag it with a label just to help
17847                    // debug and understand what is going on.
17848                    if (adj > ProcessList.SERVICE_ADJ) {
17849                        app.adjType = "cch-started-ui-services";
17850                    }
17851                } else {
17852                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17853                        // This service has seen some activity within
17854                        // recent memory, so we will keep its process ahead
17855                        // of the background processes.
17856                        if (adj > ProcessList.SERVICE_ADJ) {
17857                            adj = ProcessList.SERVICE_ADJ;
17858                            app.adjType = "started-services";
17859                            app.cached = false;
17860                        }
17861                    }
17862                    // If we have let the service slide into the background
17863                    // state, still have some text describing what it is doing
17864                    // even though the service no longer has an impact.
17865                    if (adj > ProcessList.SERVICE_ADJ) {
17866                        app.adjType = "cch-started-services";
17867                    }
17868                }
17869            }
17870            for (int conni = s.connections.size()-1;
17871                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17872                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17873                            || procState > ActivityManager.PROCESS_STATE_TOP);
17874                    conni--) {
17875                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17876                for (int i = 0;
17877                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17878                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17879                                || procState > ActivityManager.PROCESS_STATE_TOP);
17880                        i++) {
17881                    // XXX should compute this based on the max of
17882                    // all connected clients.
17883                    ConnectionRecord cr = clist.get(i);
17884                    if (cr.binding.client == app) {
17885                        // Binding to ourself is not interesting.
17886                        continue;
17887                    }
17888                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17889                        ProcessRecord client = cr.binding.client;
17890                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
17891                                TOP_APP, doingAll, now);
17892                        int clientProcState = client.curProcState;
17893                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17894                            // If the other app is cached for any reason, for purposes here
17895                            // we are going to consider it empty.  The specific cached state
17896                            // doesn't propagate except under certain conditions.
17897                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17898                        }
17899                        String adjType = null;
17900                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17901                            // Not doing bind OOM management, so treat
17902                            // this guy more like a started service.
17903                            if (app.hasShownUi && app != mHomeProcess) {
17904                                // If this process has shown some UI, let it immediately
17905                                // go to the LRU list because it may be pretty heavy with
17906                                // UI stuff.  We'll tag it with a label just to help
17907                                // debug and understand what is going on.
17908                                if (adj > clientAdj) {
17909                                    adjType = "cch-bound-ui-services";
17910                                }
17911                                app.cached = false;
17912                                clientAdj = adj;
17913                                clientProcState = procState;
17914                            } else {
17915                                if (now >= (s.lastActivity
17916                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17917                                    // This service has not seen activity within
17918                                    // recent memory, so allow it to drop to the
17919                                    // LRU list if there is no other reason to keep
17920                                    // it around.  We'll also tag it with a label just
17921                                    // to help debug and undertand what is going on.
17922                                    if (adj > clientAdj) {
17923                                        adjType = "cch-bound-services";
17924                                    }
17925                                    clientAdj = adj;
17926                                }
17927                            }
17928                        }
17929                        if (adj > clientAdj) {
17930                            // If this process has recently shown UI, and
17931                            // the process that is binding to it is less
17932                            // important than being visible, then we don't
17933                            // care about the binding as much as we care
17934                            // about letting this process get into the LRU
17935                            // list to be killed and restarted if needed for
17936                            // memory.
17937                            if (app.hasShownUi && app != mHomeProcess
17938                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17939                                adjType = "cch-bound-ui-services";
17940                            } else {
17941                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17942                                        |Context.BIND_IMPORTANT)) != 0) {
17943                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17944                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17945                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17946                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17947                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17948                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17949                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17950                                    adj = clientAdj;
17951                                } else {
17952                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17953                                        adj = ProcessList.VISIBLE_APP_ADJ;
17954                                    }
17955                                }
17956                                if (!client.cached) {
17957                                    app.cached = false;
17958                                }
17959                                adjType = "service";
17960                            }
17961                        }
17962                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17963                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17964                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17965                            }
17966                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17967                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17968                                    // Special handling of clients who are in the top state.
17969                                    // We *may* want to consider this process to be in the
17970                                    // top state as well, but only if there is not another
17971                                    // reason for it to be running.  Being on the top is a
17972                                    // special state, meaning you are specifically running
17973                                    // for the current top app.  If the process is already
17974                                    // running in the background for some other reason, it
17975                                    // is more important to continue considering it to be
17976                                    // in the background state.
17977                                    mayBeTop = true;
17978                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17979                                } else {
17980                                    // Special handling for above-top states (persistent
17981                                    // processes).  These should not bring the current process
17982                                    // into the top state, since they are not on top.  Instead
17983                                    // give them the best state after that.
17984                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
17985                                        clientProcState =
17986                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
17987                                    } else if (mWakefulness
17988                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
17989                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
17990                                                    != 0) {
17991                                        clientProcState =
17992                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
17993                                    } else {
17994                                        clientProcState =
17995                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17996                                    }
17997                                }
17998                            }
17999                        } else {
18000                            if (clientProcState <
18001                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18002                                clientProcState =
18003                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18004                            }
18005                        }
18006                        if (procState > clientProcState) {
18007                            procState = clientProcState;
18008                        }
18009                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18010                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18011                            app.pendingUiClean = true;
18012                        }
18013                        if (adjType != null) {
18014                            app.adjType = adjType;
18015                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18016                                    .REASON_SERVICE_IN_USE;
18017                            app.adjSource = cr.binding.client;
18018                            app.adjSourceProcState = clientProcState;
18019                            app.adjTarget = s.name;
18020                        }
18021                    }
18022                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18023                        app.treatLikeActivity = true;
18024                    }
18025                    final ActivityRecord a = cr.activity;
18026                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18027                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18028                                (a.visible || a.state == ActivityState.RESUMED
18029                                 || a.state == ActivityState.PAUSING)) {
18030                            adj = ProcessList.FOREGROUND_APP_ADJ;
18031                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18032                                schedGroup = Process.THREAD_GROUP_DEFAULT;
18033                            }
18034                            app.cached = false;
18035                            app.adjType = "service";
18036                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18037                                    .REASON_SERVICE_IN_USE;
18038                            app.adjSource = a;
18039                            app.adjSourceProcState = procState;
18040                            app.adjTarget = s.name;
18041                        }
18042                    }
18043                }
18044            }
18045        }
18046
18047        for (int provi = app.pubProviders.size()-1;
18048                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18049                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18050                        || procState > ActivityManager.PROCESS_STATE_TOP);
18051                provi--) {
18052            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18053            for (int i = cpr.connections.size()-1;
18054                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18055                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18056                            || procState > ActivityManager.PROCESS_STATE_TOP);
18057                    i--) {
18058                ContentProviderConnection conn = cpr.connections.get(i);
18059                ProcessRecord client = conn.client;
18060                if (client == app) {
18061                    // Being our own client is not interesting.
18062                    continue;
18063                }
18064                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18065                int clientProcState = client.curProcState;
18066                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18067                    // If the other app is cached for any reason, for purposes here
18068                    // we are going to consider it empty.
18069                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18070                }
18071                if (adj > clientAdj) {
18072                    if (app.hasShownUi && app != mHomeProcess
18073                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18074                        app.adjType = "cch-ui-provider";
18075                    } else {
18076                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18077                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18078                        app.adjType = "provider";
18079                    }
18080                    app.cached &= client.cached;
18081                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18082                            .REASON_PROVIDER_IN_USE;
18083                    app.adjSource = client;
18084                    app.adjSourceProcState = clientProcState;
18085                    app.adjTarget = cpr.name;
18086                }
18087                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18088                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18089                        // Special handling of clients who are in the top state.
18090                        // We *may* want to consider this process to be in the
18091                        // top state as well, but only if there is not another
18092                        // reason for it to be running.  Being on the top is a
18093                        // special state, meaning you are specifically running
18094                        // for the current top app.  If the process is already
18095                        // running in the background for some other reason, it
18096                        // is more important to continue considering it to be
18097                        // in the background state.
18098                        mayBeTop = true;
18099                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18100                    } else {
18101                        // Special handling for above-top states (persistent
18102                        // processes).  These should not bring the current process
18103                        // into the top state, since they are not on top.  Instead
18104                        // give them the best state after that.
18105                        clientProcState =
18106                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18107                    }
18108                }
18109                if (procState > clientProcState) {
18110                    procState = clientProcState;
18111                }
18112                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18113                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18114                }
18115            }
18116            // If the provider has external (non-framework) process
18117            // dependencies, ensure that its adjustment is at least
18118            // FOREGROUND_APP_ADJ.
18119            if (cpr.hasExternalProcessHandles()) {
18120                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
18121                    adj = ProcessList.FOREGROUND_APP_ADJ;
18122                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18123                    app.cached = false;
18124                    app.adjType = "provider";
18125                    app.adjTarget = cpr.name;
18126                }
18127                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18128                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18129                }
18130            }
18131        }
18132
18133        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
18134            // A client of one of our services or providers is in the top state.  We
18135            // *may* want to be in the top state, but not if we are already running in
18136            // the background for some other reason.  For the decision here, we are going
18137            // to pick out a few specific states that we want to remain in when a client
18138            // is top (states that tend to be longer-term) and otherwise allow it to go
18139            // to the top state.
18140            switch (procState) {
18141                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
18142                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
18143                case ActivityManager.PROCESS_STATE_SERVICE:
18144                    // These all are longer-term states, so pull them up to the top
18145                    // of the background states, but not all the way to the top state.
18146                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18147                    break;
18148                default:
18149                    // Otherwise, top is a better choice, so take it.
18150                    procState = ActivityManager.PROCESS_STATE_TOP;
18151                    break;
18152            }
18153        }
18154
18155        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
18156            if (app.hasClientActivities) {
18157                // This is a cached process, but with client activities.  Mark it so.
18158                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
18159                app.adjType = "cch-client-act";
18160            } else if (app.treatLikeActivity) {
18161                // This is a cached process, but somebody wants us to treat it like it has
18162                // an activity, okay!
18163                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18164                app.adjType = "cch-as-act";
18165            }
18166        }
18167
18168        if (adj == ProcessList.SERVICE_ADJ) {
18169            if (doingAll) {
18170                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
18171                mNewNumServiceProcs++;
18172                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
18173                if (!app.serviceb) {
18174                    // This service isn't far enough down on the LRU list to
18175                    // normally be a B service, but if we are low on RAM and it
18176                    // is large we want to force it down since we would prefer to
18177                    // keep launcher over it.
18178                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
18179                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
18180                        app.serviceHighRam = true;
18181                        app.serviceb = true;
18182                        //Slog.i(TAG, "ADJ " + app + " high ram!");
18183                    } else {
18184                        mNewNumAServiceProcs++;
18185                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
18186                    }
18187                } else {
18188                    app.serviceHighRam = false;
18189                }
18190            }
18191            if (app.serviceb) {
18192                adj = ProcessList.SERVICE_B_ADJ;
18193            }
18194        }
18195
18196        app.curRawAdj = adj;
18197
18198        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
18199        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
18200        if (adj > app.maxAdj) {
18201            adj = app.maxAdj;
18202            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
18203                schedGroup = Process.THREAD_GROUP_DEFAULT;
18204            }
18205        }
18206
18207        // Do final modification to adj.  Everything we do between here and applying
18208        // the final setAdj must be done in this function, because we will also use
18209        // it when computing the final cached adj later.  Note that we don't need to
18210        // worry about this for max adj above, since max adj will always be used to
18211        // keep it out of the cached vaues.
18212        app.curAdj = app.modifyRawOomAdj(adj);
18213        app.curSchedGroup = schedGroup;
18214        app.curProcState = procState;
18215        app.foregroundActivities = foregroundActivities;
18216
18217        return app.curRawAdj;
18218    }
18219
18220    /**
18221     * Record new PSS sample for a process.
18222     */
18223    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long now) {
18224        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024);
18225        proc.lastPssTime = now;
18226        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
18227        if (DEBUG_PSS) Slog.d(TAG_PSS,
18228                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
18229                + " state=" + ProcessList.makeProcStateString(procState));
18230        if (proc.initialIdlePss == 0) {
18231            proc.initialIdlePss = pss;
18232        }
18233        proc.lastPss = pss;
18234        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
18235            proc.lastCachedPss = pss;
18236        }
18237
18238        final SparseArray<Pair<Long, String>> watchUids
18239                = mMemWatchProcesses.getMap().get(proc.processName);
18240        Long check = null;
18241        if (watchUids != null) {
18242            Pair<Long, String> val = watchUids.get(proc.uid);
18243            if (val == null) {
18244                val = watchUids.get(0);
18245            }
18246            if (val != null) {
18247                check = val.first;
18248            }
18249        }
18250        if (check != null) {
18251            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
18252                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18253                if (!isDebuggable) {
18254                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
18255                        isDebuggable = true;
18256                    }
18257                }
18258                if (isDebuggable) {
18259                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
18260                    final ProcessRecord myProc = proc;
18261                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
18262                    mMemWatchDumpProcName = proc.processName;
18263                    mMemWatchDumpFile = heapdumpFile.toString();
18264                    mMemWatchDumpPid = proc.pid;
18265                    mMemWatchDumpUid = proc.uid;
18266                    BackgroundThread.getHandler().post(new Runnable() {
18267                        @Override
18268                        public void run() {
18269                            revokeUriPermission(ActivityThread.currentActivityThread()
18270                                            .getApplicationThread(),
18271                                    DumpHeapActivity.JAVA_URI,
18272                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
18273                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
18274                                    UserHandle.myUserId());
18275                            ParcelFileDescriptor fd = null;
18276                            try {
18277                                heapdumpFile.delete();
18278                                fd = ParcelFileDescriptor.open(heapdumpFile,
18279                                        ParcelFileDescriptor.MODE_CREATE |
18280                                                ParcelFileDescriptor.MODE_TRUNCATE |
18281                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
18282                                                ParcelFileDescriptor.MODE_APPEND);
18283                                IApplicationThread thread = myProc.thread;
18284                                if (thread != null) {
18285                                    try {
18286                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
18287                                                "Requesting dump heap from "
18288                                                + myProc + " to " + heapdumpFile);
18289                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
18290                                    } catch (RemoteException e) {
18291                                    }
18292                                }
18293                            } catch (FileNotFoundException e) {
18294                                e.printStackTrace();
18295                            } finally {
18296                                if (fd != null) {
18297                                    try {
18298                                        fd.close();
18299                                    } catch (IOException e) {
18300                                    }
18301                                }
18302                            }
18303                        }
18304                    });
18305                } else {
18306                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
18307                            + ", but debugging not enabled");
18308                }
18309            }
18310        }
18311    }
18312
18313    /**
18314     * Schedule PSS collection of a process.
18315     */
18316    void requestPssLocked(ProcessRecord proc, int procState) {
18317        if (mPendingPssProcesses.contains(proc)) {
18318            return;
18319        }
18320        if (mPendingPssProcesses.size() == 0) {
18321            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18322        }
18323        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
18324        proc.pssProcState = procState;
18325        mPendingPssProcesses.add(proc);
18326    }
18327
18328    /**
18329     * Schedule PSS collection of all processes.
18330     */
18331    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
18332        if (!always) {
18333            if (now < (mLastFullPssTime +
18334                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
18335                return;
18336            }
18337        }
18338        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
18339        mLastFullPssTime = now;
18340        mFullPssPending = true;
18341        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
18342        mPendingPssProcesses.clear();
18343        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18344            ProcessRecord app = mLruProcesses.get(i);
18345            if (app.thread == null
18346                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
18347                continue;
18348            }
18349            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
18350                app.pssProcState = app.setProcState;
18351                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18352                        mTestPssMode, isSleeping(), now);
18353                mPendingPssProcesses.add(app);
18354            }
18355        }
18356        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18357    }
18358
18359    public void setTestPssMode(boolean enabled) {
18360        synchronized (this) {
18361            mTestPssMode = enabled;
18362            if (enabled) {
18363                // Whenever we enable the mode, we want to take a snapshot all of current
18364                // process mem use.
18365                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
18366            }
18367        }
18368    }
18369
18370    /**
18371     * Ask a given process to GC right now.
18372     */
18373    final void performAppGcLocked(ProcessRecord app) {
18374        try {
18375            app.lastRequestedGc = SystemClock.uptimeMillis();
18376            if (app.thread != null) {
18377                if (app.reportLowMemory) {
18378                    app.reportLowMemory = false;
18379                    app.thread.scheduleLowMemory();
18380                } else {
18381                    app.thread.processInBackground();
18382                }
18383            }
18384        } catch (Exception e) {
18385            // whatever.
18386        }
18387    }
18388
18389    /**
18390     * Returns true if things are idle enough to perform GCs.
18391     */
18392    private final boolean canGcNowLocked() {
18393        boolean processingBroadcasts = false;
18394        for (BroadcastQueue q : mBroadcastQueues) {
18395            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
18396                processingBroadcasts = true;
18397            }
18398        }
18399        return !processingBroadcasts
18400                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
18401    }
18402
18403    /**
18404     * Perform GCs on all processes that are waiting for it, but only
18405     * if things are idle.
18406     */
18407    final void performAppGcsLocked() {
18408        final int N = mProcessesToGc.size();
18409        if (N <= 0) {
18410            return;
18411        }
18412        if (canGcNowLocked()) {
18413            while (mProcessesToGc.size() > 0) {
18414                ProcessRecord proc = mProcessesToGc.remove(0);
18415                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
18416                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
18417                            <= SystemClock.uptimeMillis()) {
18418                        // To avoid spamming the system, we will GC processes one
18419                        // at a time, waiting a few seconds between each.
18420                        performAppGcLocked(proc);
18421                        scheduleAppGcsLocked();
18422                        return;
18423                    } else {
18424                        // It hasn't been long enough since we last GCed this
18425                        // process...  put it in the list to wait for its time.
18426                        addProcessToGcListLocked(proc);
18427                        break;
18428                    }
18429                }
18430            }
18431
18432            scheduleAppGcsLocked();
18433        }
18434    }
18435
18436    /**
18437     * If all looks good, perform GCs on all processes waiting for them.
18438     */
18439    final void performAppGcsIfAppropriateLocked() {
18440        if (canGcNowLocked()) {
18441            performAppGcsLocked();
18442            return;
18443        }
18444        // Still not idle, wait some more.
18445        scheduleAppGcsLocked();
18446    }
18447
18448    /**
18449     * Schedule the execution of all pending app GCs.
18450     */
18451    final void scheduleAppGcsLocked() {
18452        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
18453
18454        if (mProcessesToGc.size() > 0) {
18455            // Schedule a GC for the time to the next process.
18456            ProcessRecord proc = mProcessesToGc.get(0);
18457            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
18458
18459            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
18460            long now = SystemClock.uptimeMillis();
18461            if (when < (now+GC_TIMEOUT)) {
18462                when = now + GC_TIMEOUT;
18463            }
18464            mHandler.sendMessageAtTime(msg, when);
18465        }
18466    }
18467
18468    /**
18469     * Add a process to the array of processes waiting to be GCed.  Keeps the
18470     * list in sorted order by the last GC time.  The process can't already be
18471     * on the list.
18472     */
18473    final void addProcessToGcListLocked(ProcessRecord proc) {
18474        boolean added = false;
18475        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
18476            if (mProcessesToGc.get(i).lastRequestedGc <
18477                    proc.lastRequestedGc) {
18478                added = true;
18479                mProcessesToGc.add(i+1, proc);
18480                break;
18481            }
18482        }
18483        if (!added) {
18484            mProcessesToGc.add(0, proc);
18485        }
18486    }
18487
18488    /**
18489     * Set up to ask a process to GC itself.  This will either do it
18490     * immediately, or put it on the list of processes to gc the next
18491     * time things are idle.
18492     */
18493    final void scheduleAppGcLocked(ProcessRecord app) {
18494        long now = SystemClock.uptimeMillis();
18495        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
18496            return;
18497        }
18498        if (!mProcessesToGc.contains(app)) {
18499            addProcessToGcListLocked(app);
18500            scheduleAppGcsLocked();
18501        }
18502    }
18503
18504    final void checkExcessivePowerUsageLocked(boolean doKills) {
18505        updateCpuStatsNow();
18506
18507        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18508        boolean doWakeKills = doKills;
18509        boolean doCpuKills = doKills;
18510        if (mLastPowerCheckRealtime == 0) {
18511            doWakeKills = false;
18512        }
18513        if (mLastPowerCheckUptime == 0) {
18514            doCpuKills = false;
18515        }
18516        if (stats.isScreenOn()) {
18517            doWakeKills = false;
18518        }
18519        final long curRealtime = SystemClock.elapsedRealtime();
18520        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
18521        final long curUptime = SystemClock.uptimeMillis();
18522        final long uptimeSince = curUptime - mLastPowerCheckUptime;
18523        mLastPowerCheckRealtime = curRealtime;
18524        mLastPowerCheckUptime = curUptime;
18525        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
18526            doWakeKills = false;
18527        }
18528        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
18529            doCpuKills = false;
18530        }
18531        int i = mLruProcesses.size();
18532        while (i > 0) {
18533            i--;
18534            ProcessRecord app = mLruProcesses.get(i);
18535            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18536                long wtime;
18537                synchronized (stats) {
18538                    wtime = stats.getProcessWakeTime(app.info.uid,
18539                            app.pid, curRealtime);
18540                }
18541                long wtimeUsed = wtime - app.lastWakeTime;
18542                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
18543                if (DEBUG_POWER) {
18544                    StringBuilder sb = new StringBuilder(128);
18545                    sb.append("Wake for ");
18546                    app.toShortString(sb);
18547                    sb.append(": over ");
18548                    TimeUtils.formatDuration(realtimeSince, sb);
18549                    sb.append(" used ");
18550                    TimeUtils.formatDuration(wtimeUsed, sb);
18551                    sb.append(" (");
18552                    sb.append((wtimeUsed*100)/realtimeSince);
18553                    sb.append("%)");
18554                    Slog.i(TAG_POWER, sb.toString());
18555                    sb.setLength(0);
18556                    sb.append("CPU for ");
18557                    app.toShortString(sb);
18558                    sb.append(": over ");
18559                    TimeUtils.formatDuration(uptimeSince, sb);
18560                    sb.append(" used ");
18561                    TimeUtils.formatDuration(cputimeUsed, sb);
18562                    sb.append(" (");
18563                    sb.append((cputimeUsed*100)/uptimeSince);
18564                    sb.append("%)");
18565                    Slog.i(TAG_POWER, sb.toString());
18566                }
18567                // If a process has held a wake lock for more
18568                // than 50% of the time during this period,
18569                // that sounds bad.  Kill!
18570                if (doWakeKills && realtimeSince > 0
18571                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
18572                    synchronized (stats) {
18573                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
18574                                realtimeSince, wtimeUsed);
18575                    }
18576                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
18577                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
18578                } else if (doCpuKills && uptimeSince > 0
18579                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
18580                    synchronized (stats) {
18581                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
18582                                uptimeSince, cputimeUsed);
18583                    }
18584                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
18585                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
18586                } else {
18587                    app.lastWakeTime = wtime;
18588                    app.lastCpuTime = app.curCpuTime;
18589                }
18590            }
18591        }
18592    }
18593
18594    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now) {
18595        boolean success = true;
18596
18597        if (app.curRawAdj != app.setRawAdj) {
18598            app.setRawAdj = app.curRawAdj;
18599        }
18600
18601        int changes = 0;
18602
18603        if (app.curAdj != app.setAdj) {
18604            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
18605            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18606                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
18607                    + app.adjType);
18608            app.setAdj = app.curAdj;
18609        }
18610
18611        if (app.setSchedGroup != app.curSchedGroup) {
18612            app.setSchedGroup = app.curSchedGroup;
18613            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18614                    "Setting process group of " + app.processName
18615                    + " to " + app.curSchedGroup);
18616            if (app.waitingToKill != null && app.curReceiver == null
18617                    && app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
18618                app.kill(app.waitingToKill, true);
18619                success = false;
18620            } else {
18621                if (true) {
18622                    long oldId = Binder.clearCallingIdentity();
18623                    try {
18624                        Process.setProcessGroup(app.pid, app.curSchedGroup);
18625                    } catch (Exception e) {
18626                        Slog.w(TAG, "Failed setting process group of " + app.pid
18627                                + " to " + app.curSchedGroup);
18628                        e.printStackTrace();
18629                    } finally {
18630                        Binder.restoreCallingIdentity(oldId);
18631                    }
18632                } else {
18633                    if (app.thread != null) {
18634                        try {
18635                            app.thread.setSchedulingGroup(app.curSchedGroup);
18636                        } catch (RemoteException e) {
18637                        }
18638                    }
18639                }
18640                Process.setSwappiness(app.pid,
18641                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
18642            }
18643        }
18644        if (app.repForegroundActivities != app.foregroundActivities) {
18645            app.repForegroundActivities = app.foregroundActivities;
18646            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
18647        }
18648        if (app.repProcState != app.curProcState) {
18649            app.repProcState = app.curProcState;
18650            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
18651            if (app.thread != null) {
18652                try {
18653                    if (false) {
18654                        //RuntimeException h = new RuntimeException("here");
18655                        Slog.i(TAG, "Sending new process state " + app.repProcState
18656                                + " to " + app /*, h*/);
18657                    }
18658                    app.thread.setProcessState(app.repProcState);
18659                } catch (RemoteException e) {
18660                }
18661            }
18662        }
18663        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
18664                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
18665            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
18666                // Experimental code to more aggressively collect pss while
18667                // running test...  the problem is that this tends to collect
18668                // the data right when a process is transitioning between process
18669                // states, which well tend to give noisy data.
18670                long start = SystemClock.uptimeMillis();
18671                long pss = Debug.getPss(app.pid, mTmpLong, null);
18672                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], now);
18673                mPendingPssProcesses.remove(app);
18674                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
18675                        + " to " + app.curProcState + ": "
18676                        + (SystemClock.uptimeMillis()-start) + "ms");
18677            }
18678            app.lastStateTime = now;
18679            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18680                    mTestPssMode, isSleeping(), now);
18681            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
18682                    + ProcessList.makeProcStateString(app.setProcState) + " to "
18683                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
18684                    + (app.nextPssTime-now) + ": " + app);
18685        } else {
18686            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
18687                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
18688                    mTestPssMode)))) {
18689                requestPssLocked(app, app.setProcState);
18690                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
18691                        mTestPssMode, isSleeping(), now);
18692            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
18693                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
18694        }
18695        if (app.setProcState != app.curProcState) {
18696            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18697                    "Proc state change of " + app.processName
18698                    + " to " + app.curProcState);
18699            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
18700            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
18701            if (setImportant && !curImportant) {
18702                // This app is no longer something we consider important enough to allow to
18703                // use arbitrary amounts of battery power.  Note
18704                // its current wake lock time to later know to kill it if
18705                // it is not behaving well.
18706                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18707                synchronized (stats) {
18708                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
18709                            app.pid, SystemClock.elapsedRealtime());
18710                }
18711                app.lastCpuTime = app.curCpuTime;
18712
18713            }
18714            // Inform UsageStats of important process state change
18715            // Must be called before updating setProcState
18716            maybeUpdateUsageStatsLocked(app);
18717
18718            app.setProcState = app.curProcState;
18719            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18720                app.notCachedSinceIdle = false;
18721            }
18722            if (!doingAll) {
18723                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
18724            } else {
18725                app.procStateChanged = true;
18726            }
18727        }
18728
18729        if (changes != 0) {
18730            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18731                    "Changes in " + app + ": " + changes);
18732            int i = mPendingProcessChanges.size()-1;
18733            ProcessChangeItem item = null;
18734            while (i >= 0) {
18735                item = mPendingProcessChanges.get(i);
18736                if (item.pid == app.pid) {
18737                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18738                            "Re-using existing item: " + item);
18739                    break;
18740                }
18741                i--;
18742            }
18743            if (i < 0) {
18744                // No existing item in pending changes; need a new one.
18745                final int NA = mAvailProcessChanges.size();
18746                if (NA > 0) {
18747                    item = mAvailProcessChanges.remove(NA-1);
18748                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18749                            "Retrieving available item: " + item);
18750                } else {
18751                    item = new ProcessChangeItem();
18752                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18753                            "Allocating new item: " + item);
18754                }
18755                item.changes = 0;
18756                item.pid = app.pid;
18757                item.uid = app.info.uid;
18758                if (mPendingProcessChanges.size() == 0) {
18759                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18760                            "*** Enqueueing dispatch processes changed!");
18761                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
18762                }
18763                mPendingProcessChanges.add(item);
18764            }
18765            item.changes |= changes;
18766            item.processState = app.repProcState;
18767            item.foregroundActivities = app.repForegroundActivities;
18768            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18769                    "Item " + Integer.toHexString(System.identityHashCode(item))
18770                    + " " + app.toShortString() + ": changes=" + item.changes
18771                    + " procState=" + item.processState
18772                    + " foreground=" + item.foregroundActivities
18773                    + " type=" + app.adjType + " source=" + app.adjSource
18774                    + " target=" + app.adjTarget);
18775        }
18776
18777        return success;
18778    }
18779
18780    private final void enqueueUidChangeLocked(UidRecord uidRec, boolean gone) {
18781        if (uidRec.pendingChange == null) {
18782            if (mPendingUidChanges.size() == 0) {
18783                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18784                        "*** Enqueueing dispatch uid changed!");
18785                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_MSG).sendToTarget();
18786            }
18787            final int NA = mAvailUidChanges.size();
18788            if (NA > 0) {
18789                uidRec.pendingChange = mAvailUidChanges.remove(NA-1);
18790                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18791                        "Retrieving available item: " + uidRec.pendingChange);
18792            } else {
18793                uidRec.pendingChange = new UidRecord.ChangeItem();
18794                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18795                        "Allocating new item: " + uidRec.pendingChange);
18796            }
18797            uidRec.pendingChange.uidRecord = uidRec;
18798            uidRec.pendingChange.uid = uidRec.uid;
18799            mPendingUidChanges.add(uidRec.pendingChange);
18800        }
18801        uidRec.pendingChange.gone = gone;
18802        uidRec.pendingChange.processState = uidRec.setProcState;
18803    }
18804
18805    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
18806            String authority) {
18807        if (app == null) return;
18808        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18809            UserState userState = mStartedUsers.get(app.userId);
18810            if (userState == null) return;
18811            final long now = SystemClock.elapsedRealtime();
18812            Long lastReported = userState.mProviderLastReportedFg.get(authority);
18813            if (lastReported == null || lastReported < now - 60 * 1000L) {
18814                mUsageStatsService.reportContentProviderUsage(
18815                        authority, providerPkgName, app.userId);
18816                userState.mProviderLastReportedFg.put(authority, now);
18817            }
18818        }
18819    }
18820
18821    private void maybeUpdateUsageStatsLocked(ProcessRecord app) {
18822        if (DEBUG_USAGE_STATS) {
18823            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
18824                    + "] state changes: old = " + app.setProcState + ", new = "
18825                    + app.curProcState);
18826        }
18827        if (mUsageStatsService == null) {
18828            return;
18829        }
18830        boolean isInteraction;
18831        // To avoid some abuse patterns, we are going to be careful about what we consider
18832        // to be an app interaction.  Being the top activity doesn't count while the display
18833        // is sleeping, nor do short foreground services.
18834        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
18835            isInteraction = true;
18836            app.fgInteractionTime = 0;
18837        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
18838            final long now = SystemClock.elapsedRealtime();
18839            if (app.fgInteractionTime == 0) {
18840                app.fgInteractionTime = now;
18841                isInteraction = false;
18842            } else {
18843                isInteraction = now > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
18844            }
18845        } else {
18846            isInteraction = app.curProcState
18847                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18848            app.fgInteractionTime = 0;
18849        }
18850        if (isInteraction && !app.reportedInteraction) {
18851            String[] packages = app.getPackageList();
18852            if (packages != null) {
18853                for (int i = 0; i < packages.length; i++) {
18854                    mUsageStatsService.reportEvent(packages[i], app.userId,
18855                            UsageEvents.Event.SYSTEM_INTERACTION);
18856                }
18857            }
18858        }
18859        app.reportedInteraction = isInteraction;
18860    }
18861
18862    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
18863        if (proc.thread != null) {
18864            if (proc.baseProcessTracker != null) {
18865                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
18866            }
18867            if (proc.repProcState >= 0) {
18868                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
18869                        proc.repProcState);
18870            }
18871        }
18872    }
18873
18874    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
18875            ProcessRecord TOP_APP, boolean doingAll, long now) {
18876        if (app.thread == null) {
18877            return false;
18878        }
18879
18880        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
18881
18882        return applyOomAdjLocked(app, doingAll, now);
18883    }
18884
18885    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
18886            boolean oomAdj) {
18887        if (isForeground != proc.foregroundServices) {
18888            proc.foregroundServices = isForeground;
18889            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
18890                    proc.info.uid);
18891            if (isForeground) {
18892                if (curProcs == null) {
18893                    curProcs = new ArrayList<ProcessRecord>();
18894                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
18895                }
18896                if (!curProcs.contains(proc)) {
18897                    curProcs.add(proc);
18898                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
18899                            proc.info.packageName, proc.info.uid);
18900                }
18901            } else {
18902                if (curProcs != null) {
18903                    if (curProcs.remove(proc)) {
18904                        mBatteryStatsService.noteEvent(
18905                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
18906                                proc.info.packageName, proc.info.uid);
18907                        if (curProcs.size() <= 0) {
18908                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
18909                        }
18910                    }
18911                }
18912            }
18913            if (oomAdj) {
18914                updateOomAdjLocked();
18915            }
18916        }
18917    }
18918
18919    private final ActivityRecord resumedAppLocked() {
18920        ActivityRecord act = mStackSupervisor.resumedAppLocked();
18921        String pkg;
18922        int uid;
18923        if (act != null) {
18924            pkg = act.packageName;
18925            uid = act.info.applicationInfo.uid;
18926        } else {
18927            pkg = null;
18928            uid = -1;
18929        }
18930        // Has the UID or resumed package name changed?
18931        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
18932                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
18933            if (mCurResumedPackage != null) {
18934                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
18935                        mCurResumedPackage, mCurResumedUid);
18936            }
18937            mCurResumedPackage = pkg;
18938            mCurResumedUid = uid;
18939            if (mCurResumedPackage != null) {
18940                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
18941                        mCurResumedPackage, mCurResumedUid);
18942            }
18943        }
18944        return act;
18945    }
18946
18947    final boolean updateOomAdjLocked(ProcessRecord app) {
18948        final ActivityRecord TOP_ACT = resumedAppLocked();
18949        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18950        final boolean wasCached = app.cached;
18951
18952        mAdjSeq++;
18953
18954        // This is the desired cached adjusment we want to tell it to use.
18955        // If our app is currently cached, we know it, and that is it.  Otherwise,
18956        // we don't know it yet, and it needs to now be cached we will then
18957        // need to do a complete oom adj.
18958        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
18959                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
18960        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
18961                SystemClock.uptimeMillis());
18962        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
18963            // Changed to/from cached state, so apps after it in the LRU
18964            // list may also be changed.
18965            updateOomAdjLocked();
18966        }
18967        return success;
18968    }
18969
18970    final void updateOomAdjLocked() {
18971        final ActivityRecord TOP_ACT = resumedAppLocked();
18972        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18973        final long now = SystemClock.uptimeMillis();
18974        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
18975        final int N = mLruProcesses.size();
18976
18977        if (false) {
18978            RuntimeException e = new RuntimeException();
18979            e.fillInStackTrace();
18980            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
18981        }
18982
18983        // Reset state in all uid records.
18984        for (int i=mActiveUids.size()-1; i>=0; i--) {
18985            final UidRecord uidRec = mActiveUids.valueAt(i);
18986            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18987                    "Starting update of " + uidRec);
18988            uidRec.reset();
18989        }
18990
18991        mAdjSeq++;
18992        mNewNumServiceProcs = 0;
18993        mNewNumAServiceProcs = 0;
18994
18995        final int emptyProcessLimit;
18996        final int cachedProcessLimit;
18997        if (mProcessLimit <= 0) {
18998            emptyProcessLimit = cachedProcessLimit = 0;
18999        } else if (mProcessLimit == 1) {
19000            emptyProcessLimit = 1;
19001            cachedProcessLimit = 0;
19002        } else {
19003            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
19004            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19005        }
19006
19007        // Let's determine how many processes we have running vs.
19008        // how many slots we have for background processes; we may want
19009        // to put multiple processes in a slot of there are enough of
19010        // them.
19011        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19012                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19013        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19014        if (numEmptyProcs > cachedProcessLimit) {
19015            // If there are more empty processes than our limit on cached
19016            // processes, then use the cached process limit for the factor.
19017            // This ensures that the really old empty processes get pushed
19018            // down to the bottom, so if we are running low on memory we will
19019            // have a better chance at keeping around more cached processes
19020            // instead of a gazillion empty processes.
19021            numEmptyProcs = cachedProcessLimit;
19022        }
19023        int emptyFactor = numEmptyProcs/numSlots;
19024        if (emptyFactor < 1) emptyFactor = 1;
19025        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
19026        if (cachedFactor < 1) cachedFactor = 1;
19027        int stepCached = 0;
19028        int stepEmpty = 0;
19029        int numCached = 0;
19030        int numEmpty = 0;
19031        int numTrimming = 0;
19032
19033        mNumNonCachedProcs = 0;
19034        mNumCachedHiddenProcs = 0;
19035
19036        // First update the OOM adjustment for each of the
19037        // application processes based on their current state.
19038        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19039        int nextCachedAdj = curCachedAdj+1;
19040        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
19041        int nextEmptyAdj = curEmptyAdj+2;
19042        for (int i=N-1; i>=0; i--) {
19043            ProcessRecord app = mLruProcesses.get(i);
19044            if (!app.killedByAm && app.thread != null) {
19045                app.procStateChanged = false;
19046                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19047
19048                // If we haven't yet assigned the final cached adj
19049                // to the process, do that now.
19050                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
19051                    switch (app.curProcState) {
19052                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19053                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19054                            // This process is a cached process holding activities...
19055                            // assign it the next cached value for that type, and then
19056                            // step that cached level.
19057                            app.curRawAdj = curCachedAdj;
19058                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
19059                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
19060                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
19061                                    + ")");
19062                            if (curCachedAdj != nextCachedAdj) {
19063                                stepCached++;
19064                                if (stepCached >= cachedFactor) {
19065                                    stepCached = 0;
19066                                    curCachedAdj = nextCachedAdj;
19067                                    nextCachedAdj += 2;
19068                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19069                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
19070                                    }
19071                                }
19072                            }
19073                            break;
19074                        default:
19075                            // For everything else, assign next empty cached process
19076                            // level and bump that up.  Note that this means that
19077                            // long-running services that have dropped down to the
19078                            // cached level will be treated as empty (since their process
19079                            // state is still as a service), which is what we want.
19080                            app.curRawAdj = curEmptyAdj;
19081                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
19082                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
19083                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
19084                                    + ")");
19085                            if (curEmptyAdj != nextEmptyAdj) {
19086                                stepEmpty++;
19087                                if (stepEmpty >= emptyFactor) {
19088                                    stepEmpty = 0;
19089                                    curEmptyAdj = nextEmptyAdj;
19090                                    nextEmptyAdj += 2;
19091                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19092                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
19093                                    }
19094                                }
19095                            }
19096                            break;
19097                    }
19098                }
19099
19100                applyOomAdjLocked(app, true, now);
19101
19102                // Count the number of process types.
19103                switch (app.curProcState) {
19104                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19105                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19106                        mNumCachedHiddenProcs++;
19107                        numCached++;
19108                        if (numCached > cachedProcessLimit) {
19109                            app.kill("cached #" + numCached, true);
19110                        }
19111                        break;
19112                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
19113                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
19114                                && app.lastActivityTime < oldTime) {
19115                            app.kill("empty for "
19116                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
19117                                    / 1000) + "s", true);
19118                        } else {
19119                            numEmpty++;
19120                            if (numEmpty > emptyProcessLimit) {
19121                                app.kill("empty #" + numEmpty, true);
19122                            }
19123                        }
19124                        break;
19125                    default:
19126                        mNumNonCachedProcs++;
19127                        break;
19128                }
19129
19130                if (app.isolated && app.services.size() <= 0) {
19131                    // If this is an isolated process, and there are no
19132                    // services running in it, then the process is no longer
19133                    // needed.  We agressively kill these because we can by
19134                    // definition not re-use the same process again, and it is
19135                    // good to avoid having whatever code was running in them
19136                    // left sitting around after no longer needed.
19137                    app.kill("isolated not needed", true);
19138                } else {
19139                    // Keeping this process, update its uid.
19140                    final UidRecord uidRec = app.uidRecord;
19141                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
19142                        uidRec.curProcState = app.curProcState;
19143                    }
19144                }
19145
19146                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19147                        && !app.killedByAm) {
19148                    numTrimming++;
19149                }
19150            }
19151        }
19152
19153        mNumServiceProcs = mNewNumServiceProcs;
19154
19155        // Now determine the memory trimming level of background processes.
19156        // Unfortunately we need to start at the back of the list to do this
19157        // properly.  We only do this if the number of background apps we
19158        // are managing to keep around is less than half the maximum we desire;
19159        // if we are keeping a good number around, we'll let them use whatever
19160        // memory they want.
19161        final int numCachedAndEmpty = numCached + numEmpty;
19162        int memFactor;
19163        if (numCached <= ProcessList.TRIM_CACHED_APPS
19164                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
19165            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
19166                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
19167            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
19168                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
19169            } else {
19170                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
19171            }
19172        } else {
19173            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
19174        }
19175        // We always allow the memory level to go up (better).  We only allow it to go
19176        // down if we are in a state where that is allowed, *and* the total number of processes
19177        // has gone down since last time.
19178        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
19179                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
19180                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
19181        if (memFactor > mLastMemoryLevel) {
19182            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
19183                memFactor = mLastMemoryLevel;
19184                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
19185            }
19186        }
19187        mLastMemoryLevel = memFactor;
19188        mLastNumProcesses = mLruProcesses.size();
19189        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
19190        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
19191        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
19192            if (mLowRamStartTime == 0) {
19193                mLowRamStartTime = now;
19194            }
19195            int step = 0;
19196            int fgTrimLevel;
19197            switch (memFactor) {
19198                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
19199                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
19200                    break;
19201                case ProcessStats.ADJ_MEM_FACTOR_LOW:
19202                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
19203                    break;
19204                default:
19205                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
19206                    break;
19207            }
19208            int factor = numTrimming/3;
19209            int minFactor = 2;
19210            if (mHomeProcess != null) minFactor++;
19211            if (mPreviousProcess != null) minFactor++;
19212            if (factor < minFactor) factor = minFactor;
19213            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
19214            for (int i=N-1; i>=0; i--) {
19215                ProcessRecord app = mLruProcesses.get(i);
19216                if (allChanged || app.procStateChanged) {
19217                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
19218                    app.procStateChanged = false;
19219                }
19220                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19221                        && !app.killedByAm) {
19222                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
19223                        try {
19224                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19225                                    "Trimming memory of " + app.processName + " to " + curLevel);
19226                            app.thread.scheduleTrimMemory(curLevel);
19227                        } catch (RemoteException e) {
19228                        }
19229                        if (false) {
19230                            // For now we won't do this; our memory trimming seems
19231                            // to be good enough at this point that destroying
19232                            // activities causes more harm than good.
19233                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
19234                                    && app != mHomeProcess && app != mPreviousProcess) {
19235                                // Need to do this on its own message because the stack may not
19236                                // be in a consistent state at this point.
19237                                // For these apps we will also finish their activities
19238                                // to help them free memory.
19239                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
19240                            }
19241                        }
19242                    }
19243                    app.trimMemoryLevel = curLevel;
19244                    step++;
19245                    if (step >= factor) {
19246                        step = 0;
19247                        switch (curLevel) {
19248                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
19249                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
19250                                break;
19251                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
19252                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19253                                break;
19254                        }
19255                    }
19256                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19257                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
19258                            && app.thread != null) {
19259                        try {
19260                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19261                                    "Trimming memory of heavy-weight " + app.processName
19262                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19263                            app.thread.scheduleTrimMemory(
19264                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19265                        } catch (RemoteException e) {
19266                        }
19267                    }
19268                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19269                } else {
19270                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19271                            || app.systemNoUi) && app.pendingUiClean) {
19272                        // If this application is now in the background and it
19273                        // had done UI, then give it the special trim level to
19274                        // have it free UI resources.
19275                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
19276                        if (app.trimMemoryLevel < level && app.thread != null) {
19277                            try {
19278                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19279                                        "Trimming memory of bg-ui " + app.processName
19280                                        + " to " + level);
19281                                app.thread.scheduleTrimMemory(level);
19282                            } catch (RemoteException e) {
19283                            }
19284                        }
19285                        app.pendingUiClean = false;
19286                    }
19287                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
19288                        try {
19289                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19290                                    "Trimming memory of fg " + app.processName
19291                                    + " to " + fgTrimLevel);
19292                            app.thread.scheduleTrimMemory(fgTrimLevel);
19293                        } catch (RemoteException e) {
19294                        }
19295                    }
19296                    app.trimMemoryLevel = fgTrimLevel;
19297                }
19298            }
19299        } else {
19300            if (mLowRamStartTime != 0) {
19301                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
19302                mLowRamStartTime = 0;
19303            }
19304            for (int i=N-1; i>=0; i--) {
19305                ProcessRecord app = mLruProcesses.get(i);
19306                if (allChanged || app.procStateChanged) {
19307                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
19308                    app.procStateChanged = false;
19309                }
19310                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19311                        || app.systemNoUi) && app.pendingUiClean) {
19312                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
19313                            && app.thread != null) {
19314                        try {
19315                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19316                                    "Trimming memory of ui hidden " + app.processName
19317                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19318                            app.thread.scheduleTrimMemory(
19319                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19320                        } catch (RemoteException e) {
19321                        }
19322                    }
19323                    app.pendingUiClean = false;
19324                }
19325                app.trimMemoryLevel = 0;
19326            }
19327        }
19328
19329        if (mAlwaysFinishActivities) {
19330            // Need to do this on its own message because the stack may not
19331            // be in a consistent state at this point.
19332            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
19333        }
19334
19335        if (allChanged) {
19336            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
19337        }
19338
19339        // Update from any uid changes.
19340        for (int i=mActiveUids.size()-1; i>=0; i--) {
19341            final UidRecord uidRec = mActiveUids.valueAt(i);
19342            if (uidRec.setProcState != uidRec.curProcState) {
19343                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19344                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
19345                        + " to " + uidRec.curProcState);
19346                uidRec.setProcState = uidRec.curProcState;
19347                enqueueUidChangeLocked(uidRec, false);
19348            }
19349        }
19350
19351        if (mProcessStats.shouldWriteNowLocked(now)) {
19352            mHandler.post(new Runnable() {
19353                @Override public void run() {
19354                    synchronized (ActivityManagerService.this) {
19355                        mProcessStats.writeStateAsyncLocked();
19356                    }
19357                }
19358            });
19359        }
19360
19361        if (DEBUG_OOM_ADJ) {
19362            final long duration = SystemClock.uptimeMillis() - now;
19363            if (false) {
19364                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
19365                        new RuntimeException("here").fillInStackTrace());
19366            } else {
19367                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
19368            }
19369        }
19370    }
19371
19372    final void trimApplications() {
19373        synchronized (this) {
19374            int i;
19375
19376            // First remove any unused application processes whose package
19377            // has been removed.
19378            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
19379                final ProcessRecord app = mRemovedProcesses.get(i);
19380                if (app.activities.size() == 0
19381                        && app.curReceiver == null && app.services.size() == 0) {
19382                    Slog.i(
19383                        TAG, "Exiting empty application process "
19384                        + app.processName + " ("
19385                        + (app.thread != null ? app.thread.asBinder() : null)
19386                        + ")\n");
19387                    if (app.pid > 0 && app.pid != MY_PID) {
19388                        app.kill("empty", false);
19389                    } else {
19390                        try {
19391                            app.thread.scheduleExit();
19392                        } catch (Exception e) {
19393                            // Ignore exceptions.
19394                        }
19395                    }
19396                    cleanUpApplicationRecordLocked(app, false, true, -1);
19397                    mRemovedProcesses.remove(i);
19398
19399                    if (app.persistent) {
19400                        addAppLocked(app.info, false, null /* ABI override */);
19401                    }
19402                }
19403            }
19404
19405            // Now update the oom adj for all processes.
19406            updateOomAdjLocked();
19407        }
19408    }
19409
19410    /** This method sends the specified signal to each of the persistent apps */
19411    public void signalPersistentProcesses(int sig) throws RemoteException {
19412        if (sig != Process.SIGNAL_USR1) {
19413            throw new SecurityException("Only SIGNAL_USR1 is allowed");
19414        }
19415
19416        synchronized (this) {
19417            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
19418                    != PackageManager.PERMISSION_GRANTED) {
19419                throw new SecurityException("Requires permission "
19420                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
19421            }
19422
19423            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
19424                ProcessRecord r = mLruProcesses.get(i);
19425                if (r.thread != null && r.persistent) {
19426                    Process.sendSignal(r.pid, sig);
19427                }
19428            }
19429        }
19430    }
19431
19432    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
19433        if (proc == null || proc == mProfileProc) {
19434            proc = mProfileProc;
19435            profileType = mProfileType;
19436            clearProfilerLocked();
19437        }
19438        if (proc == null) {
19439            return;
19440        }
19441        try {
19442            proc.thread.profilerControl(false, null, profileType);
19443        } catch (RemoteException e) {
19444            throw new IllegalStateException("Process disappeared");
19445        }
19446    }
19447
19448    private void clearProfilerLocked() {
19449        if (mProfileFd != null) {
19450            try {
19451                mProfileFd.close();
19452            } catch (IOException e) {
19453            }
19454        }
19455        mProfileApp = null;
19456        mProfileProc = null;
19457        mProfileFile = null;
19458        mProfileType = 0;
19459        mAutoStopProfiler = false;
19460        mSamplingInterval = 0;
19461    }
19462
19463    public boolean profileControl(String process, int userId, boolean start,
19464            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
19465
19466        try {
19467            synchronized (this) {
19468                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19469                // its own permission.
19470                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19471                        != PackageManager.PERMISSION_GRANTED) {
19472                    throw new SecurityException("Requires permission "
19473                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19474                }
19475
19476                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
19477                    throw new IllegalArgumentException("null profile info or fd");
19478                }
19479
19480                ProcessRecord proc = null;
19481                if (process != null) {
19482                    proc = findProcessLocked(process, userId, "profileControl");
19483                }
19484
19485                if (start && (proc == null || proc.thread == null)) {
19486                    throw new IllegalArgumentException("Unknown process: " + process);
19487                }
19488
19489                if (start) {
19490                    stopProfilerLocked(null, 0);
19491                    setProfileApp(proc.info, proc.processName, profilerInfo);
19492                    mProfileProc = proc;
19493                    mProfileType = profileType;
19494                    ParcelFileDescriptor fd = profilerInfo.profileFd;
19495                    try {
19496                        fd = fd.dup();
19497                    } catch (IOException e) {
19498                        fd = null;
19499                    }
19500                    profilerInfo.profileFd = fd;
19501                    proc.thread.profilerControl(start, profilerInfo, profileType);
19502                    fd = null;
19503                    mProfileFd = null;
19504                } else {
19505                    stopProfilerLocked(proc, profileType);
19506                    if (profilerInfo != null && profilerInfo.profileFd != null) {
19507                        try {
19508                            profilerInfo.profileFd.close();
19509                        } catch (IOException e) {
19510                        }
19511                    }
19512                }
19513
19514                return true;
19515            }
19516        } catch (RemoteException e) {
19517            throw new IllegalStateException("Process disappeared");
19518        } finally {
19519            if (profilerInfo != null && profilerInfo.profileFd != null) {
19520                try {
19521                    profilerInfo.profileFd.close();
19522                } catch (IOException e) {
19523                }
19524            }
19525        }
19526    }
19527
19528    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
19529        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19530                userId, true, ALLOW_FULL_ONLY, callName, null);
19531        ProcessRecord proc = null;
19532        try {
19533            int pid = Integer.parseInt(process);
19534            synchronized (mPidsSelfLocked) {
19535                proc = mPidsSelfLocked.get(pid);
19536            }
19537        } catch (NumberFormatException e) {
19538        }
19539
19540        if (proc == null) {
19541            ArrayMap<String, SparseArray<ProcessRecord>> all
19542                    = mProcessNames.getMap();
19543            SparseArray<ProcessRecord> procs = all.get(process);
19544            if (procs != null && procs.size() > 0) {
19545                proc = procs.valueAt(0);
19546                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
19547                    for (int i=1; i<procs.size(); i++) {
19548                        ProcessRecord thisProc = procs.valueAt(i);
19549                        if (thisProc.userId == userId) {
19550                            proc = thisProc;
19551                            break;
19552                        }
19553                    }
19554                }
19555            }
19556        }
19557
19558        return proc;
19559    }
19560
19561    public boolean dumpHeap(String process, int userId, boolean managed,
19562            String path, ParcelFileDescriptor fd) throws RemoteException {
19563
19564        try {
19565            synchronized (this) {
19566                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19567                // its own permission (same as profileControl).
19568                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19569                        != PackageManager.PERMISSION_GRANTED) {
19570                    throw new SecurityException("Requires permission "
19571                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19572                }
19573
19574                if (fd == null) {
19575                    throw new IllegalArgumentException("null fd");
19576                }
19577
19578                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
19579                if (proc == null || proc.thread == null) {
19580                    throw new IllegalArgumentException("Unknown process: " + process);
19581                }
19582
19583                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19584                if (!isDebuggable) {
19585                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19586                        throw new SecurityException("Process not debuggable: " + proc);
19587                    }
19588                }
19589
19590                proc.thread.dumpHeap(managed, path, fd);
19591                fd = null;
19592                return true;
19593            }
19594        } catch (RemoteException e) {
19595            throw new IllegalStateException("Process disappeared");
19596        } finally {
19597            if (fd != null) {
19598                try {
19599                    fd.close();
19600                } catch (IOException e) {
19601                }
19602            }
19603        }
19604    }
19605
19606    @Override
19607    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
19608            String reportPackage) {
19609        if (processName != null) {
19610            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
19611                    "setDumpHeapDebugLimit()");
19612        } else {
19613            synchronized (mPidsSelfLocked) {
19614                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
19615                if (proc == null) {
19616                    throw new SecurityException("No process found for calling pid "
19617                            + Binder.getCallingPid());
19618                }
19619                if (!Build.IS_DEBUGGABLE
19620                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19621                    throw new SecurityException("Not running a debuggable build");
19622                }
19623                processName = proc.processName;
19624                uid = proc.uid;
19625                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
19626                    throw new SecurityException("Package " + reportPackage + " is not running in "
19627                            + proc);
19628                }
19629            }
19630        }
19631        synchronized (this) {
19632            if (maxMemSize > 0) {
19633                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
19634            } else {
19635                if (uid != 0) {
19636                    mMemWatchProcesses.remove(processName, uid);
19637                } else {
19638                    mMemWatchProcesses.getMap().remove(processName);
19639                }
19640            }
19641        }
19642    }
19643
19644    @Override
19645    public void dumpHeapFinished(String path) {
19646        synchronized (this) {
19647            if (Binder.getCallingPid() != mMemWatchDumpPid) {
19648                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
19649                        + " does not match last pid " + mMemWatchDumpPid);
19650                return;
19651            }
19652            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
19653                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
19654                        + " does not match last path " + mMemWatchDumpFile);
19655                return;
19656            }
19657            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
19658            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
19659        }
19660    }
19661
19662    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
19663    public void monitor() {
19664        synchronized (this) { }
19665    }
19666
19667    void onCoreSettingsChange(Bundle settings) {
19668        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19669            ProcessRecord processRecord = mLruProcesses.get(i);
19670            try {
19671                if (processRecord.thread != null) {
19672                    processRecord.thread.setCoreSettings(settings);
19673                }
19674            } catch (RemoteException re) {
19675                /* ignore */
19676            }
19677        }
19678    }
19679
19680    // Multi-user methods
19681
19682    /**
19683     * Start user, if its not already running, but don't bring it to foreground.
19684     */
19685    @Override
19686    public boolean startUserInBackground(final int userId) {
19687        return startUser(userId, /* foreground */ false);
19688    }
19689
19690    /**
19691     * Start user, if its not already running, and bring it to foreground.
19692     */
19693    boolean startUserInForeground(final int userId, Dialog dlg) {
19694        boolean result = startUser(userId, /* foreground */ true);
19695        dlg.dismiss();
19696        return result;
19697    }
19698
19699    /**
19700     * Refreshes the list of users related to the current user when either a
19701     * user switch happens or when a new related user is started in the
19702     * background.
19703     */
19704    private void updateCurrentProfileIdsLocked() {
19705        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19706                mCurrentUserId, false /* enabledOnly */);
19707        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
19708        for (int i = 0; i < currentProfileIds.length; i++) {
19709            currentProfileIds[i] = profiles.get(i).id;
19710        }
19711        mCurrentProfileIds = currentProfileIds;
19712
19713        synchronized (mUserProfileGroupIdsSelfLocked) {
19714            mUserProfileGroupIdsSelfLocked.clear();
19715            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
19716            for (int i = 0; i < users.size(); i++) {
19717                UserInfo user = users.get(i);
19718                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
19719                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
19720                }
19721            }
19722        }
19723    }
19724
19725    private Set<Integer> getProfileIdsLocked(int userId) {
19726        Set<Integer> userIds = new HashSet<Integer>();
19727        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19728                userId, false /* enabledOnly */);
19729        for (UserInfo user : profiles) {
19730            userIds.add(Integer.valueOf(user.id));
19731        }
19732        return userIds;
19733    }
19734
19735    @Override
19736    public boolean switchUser(final int userId) {
19737        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19738        String userName;
19739        synchronized (this) {
19740            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19741            if (userInfo == null) {
19742                Slog.w(TAG, "No user info for user #" + userId);
19743                return false;
19744            }
19745            if (userInfo.isManagedProfile()) {
19746                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19747                return false;
19748            }
19749            userName = userInfo.name;
19750            mTargetUserId = userId;
19751        }
19752        mUiHandler.removeMessages(START_USER_SWITCH_MSG);
19753        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
19754        return true;
19755    }
19756
19757    private void showUserSwitchDialog(int userId, String userName) {
19758        // The dialog will show and then initiate the user switch by calling startUserInForeground
19759        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
19760                true /* above system */);
19761        d.show();
19762    }
19763
19764    private boolean startUser(final int userId, final boolean foreground) {
19765        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19766                != PackageManager.PERMISSION_GRANTED) {
19767            String msg = "Permission Denial: switchUser() from pid="
19768                    + Binder.getCallingPid()
19769                    + ", uid=" + Binder.getCallingUid()
19770                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19771            Slog.w(TAG, msg);
19772            throw new SecurityException(msg);
19773        }
19774
19775        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
19776
19777        final long ident = Binder.clearCallingIdentity();
19778        try {
19779            synchronized (this) {
19780                final int oldUserId = mCurrentUserId;
19781                if (oldUserId == userId) {
19782                    return true;
19783                }
19784
19785                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
19786                        "startUser", false);
19787
19788                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19789                if (userInfo == null) {
19790                    Slog.w(TAG, "No user info for user #" + userId);
19791                    return false;
19792                }
19793                if (foreground && userInfo.isManagedProfile()) {
19794                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19795                    return false;
19796                }
19797
19798                if (foreground) {
19799                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
19800                            R.anim.screen_user_enter);
19801                }
19802
19803                boolean needStart = false;
19804
19805                // If the user we are switching to is not currently started, then
19806                // we need to start it now.
19807                if (mStartedUsers.get(userId) == null) {
19808                    mStartedUsers.put(userId, new UserState(new UserHandle(userId), false));
19809                    updateStartedUserArrayLocked();
19810                    needStart = true;
19811                }
19812
19813                final Integer userIdInt = Integer.valueOf(userId);
19814                mUserLru.remove(userIdInt);
19815                mUserLru.add(userIdInt);
19816
19817                if (foreground) {
19818                    mCurrentUserId = userId;
19819                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
19820                    updateCurrentProfileIdsLocked();
19821                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
19822                    // Once the internal notion of the active user has switched, we lock the device
19823                    // with the option to show the user switcher on the keyguard.
19824                    mWindowManager.lockNow(null);
19825                } else {
19826                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
19827                    updateCurrentProfileIdsLocked();
19828                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
19829                    mUserLru.remove(currentUserIdInt);
19830                    mUserLru.add(currentUserIdInt);
19831                }
19832
19833                final UserState uss = mStartedUsers.get(userId);
19834
19835                // Make sure user is in the started state.  If it is currently
19836                // stopping, we need to knock that off.
19837                if (uss.mState == UserState.STATE_STOPPING) {
19838                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
19839                    // so we can just fairly silently bring the user back from
19840                    // the almost-dead.
19841                    uss.mState = UserState.STATE_RUNNING;
19842                    updateStartedUserArrayLocked();
19843                    needStart = true;
19844                } else if (uss.mState == UserState.STATE_SHUTDOWN) {
19845                    // This means ACTION_SHUTDOWN has been sent, so we will
19846                    // need to treat this as a new boot of the user.
19847                    uss.mState = UserState.STATE_BOOTING;
19848                    updateStartedUserArrayLocked();
19849                    needStart = true;
19850                }
19851
19852                if (uss.mState == UserState.STATE_BOOTING) {
19853                    // Booting up a new user, need to tell system services about it.
19854                    // Note that this is on the same handler as scheduling of broadcasts,
19855                    // which is important because it needs to go first.
19856                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
19857                }
19858
19859                if (foreground) {
19860                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
19861                            oldUserId));
19862                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
19863                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19864                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
19865                            oldUserId, userId, uss));
19866                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
19867                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
19868                }
19869
19870                if (needStart) {
19871                    // Send USER_STARTED broadcast
19872                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
19873                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19874                            | Intent.FLAG_RECEIVER_FOREGROUND);
19875                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19876                    broadcastIntentLocked(null, null, intent,
19877                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19878                            null, false, false, MY_PID, Process.SYSTEM_UID, userId);
19879                }
19880
19881                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
19882                    if (userId != UserHandle.USER_OWNER) {
19883                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
19884                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19885                        broadcastIntentLocked(null, null, intent, null,
19886                                new IIntentReceiver.Stub() {
19887                                    public void performReceive(Intent intent, int resultCode,
19888                                            String data, Bundle extras, boolean ordered,
19889                                            boolean sticky, int sendingUser) {
19890                                        onUserInitialized(uss, foreground, oldUserId, userId);
19891                                    }
19892                                }, 0, null, null, null, AppOpsManager.OP_NONE,
19893                                null, true, false, MY_PID, Process.SYSTEM_UID, userId);
19894                        uss.initializing = true;
19895                    } else {
19896                        getUserManagerLocked().makeInitialized(userInfo.id);
19897                    }
19898                }
19899
19900                if (foreground) {
19901                    if (!uss.initializing) {
19902                        moveUserToForeground(uss, oldUserId, userId);
19903                    }
19904                } else {
19905                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
19906                }
19907
19908                if (needStart) {
19909                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
19910                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19911                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19912                    broadcastIntentLocked(null, null, intent,
19913                            null, new IIntentReceiver.Stub() {
19914                                @Override
19915                                public void performReceive(Intent intent, int resultCode,
19916                                        String data, Bundle extras, boolean ordered, boolean sticky,
19917                                        int sendingUser) throws RemoteException {
19918                                }
19919                            }, 0, null, null,
19920                            new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
19921                            null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19922                }
19923            }
19924        } finally {
19925            Binder.restoreCallingIdentity(ident);
19926        }
19927
19928        return true;
19929    }
19930
19931    void dispatchForegroundProfileChanged(int userId) {
19932        final int N = mUserSwitchObservers.beginBroadcast();
19933        for (int i = 0; i < N; i++) {
19934            try {
19935                mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
19936            } catch (RemoteException e) {
19937                // Ignore
19938            }
19939        }
19940        mUserSwitchObservers.finishBroadcast();
19941    }
19942
19943    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
19944        long ident = Binder.clearCallingIdentity();
19945        try {
19946            Intent intent;
19947            if (oldUserId >= 0) {
19948                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
19949                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
19950                int count = profiles.size();
19951                for (int i = 0; i < count; i++) {
19952                    int profileUserId = profiles.get(i).id;
19953                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
19954                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19955                            | Intent.FLAG_RECEIVER_FOREGROUND);
19956                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19957                    broadcastIntentLocked(null, null, intent,
19958                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19959                            null, false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19960                }
19961            }
19962            if (newUserId >= 0) {
19963                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
19964                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
19965                int count = profiles.size();
19966                for (int i = 0; i < count; i++) {
19967                    int profileUserId = profiles.get(i).id;
19968                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
19969                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19970                            | Intent.FLAG_RECEIVER_FOREGROUND);
19971                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19972                    broadcastIntentLocked(null, null, intent,
19973                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19974                            null, false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19975                }
19976                intent = new Intent(Intent.ACTION_USER_SWITCHED);
19977                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19978                        | Intent.FLAG_RECEIVER_FOREGROUND);
19979                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
19980                broadcastIntentLocked(null, null, intent,
19981                        null, null, 0, null, null,
19982                        new String[] {android.Manifest.permission.MANAGE_USERS},
19983                        AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
19984                        UserHandle.USER_ALL);
19985            }
19986        } finally {
19987            Binder.restoreCallingIdentity(ident);
19988        }
19989    }
19990
19991    void dispatchUserSwitch(final UserState uss, final int oldUserId,
19992            final int newUserId) {
19993        final int N = mUserSwitchObservers.beginBroadcast();
19994        if (N > 0) {
19995            final IRemoteCallback callback = new IRemoteCallback.Stub() {
19996                int mCount = 0;
19997                @Override
19998                public void sendResult(Bundle data) throws RemoteException {
19999                    synchronized (ActivityManagerService.this) {
20000                        if (mCurUserSwitchCallback == this) {
20001                            mCount++;
20002                            if (mCount == N) {
20003                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
20004                            }
20005                        }
20006                    }
20007                }
20008            };
20009            synchronized (this) {
20010                uss.switching = true;
20011                mCurUserSwitchCallback = callback;
20012            }
20013            for (int i=0; i<N; i++) {
20014                try {
20015                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
20016                            newUserId, callback);
20017                } catch (RemoteException e) {
20018                }
20019            }
20020        } else {
20021            synchronized (this) {
20022                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
20023            }
20024        }
20025        mUserSwitchObservers.finishBroadcast();
20026    }
20027
20028    void timeoutUserSwitch(UserState uss, int oldUserId, int newUserId) {
20029        synchronized (this) {
20030            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
20031            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
20032        }
20033    }
20034
20035    void sendContinueUserSwitchLocked(UserState uss, int oldUserId, int newUserId) {
20036        mCurUserSwitchCallback = null;
20037        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
20038        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
20039                oldUserId, newUserId, uss));
20040    }
20041
20042    void onUserInitialized(UserState uss, boolean foreground, int oldUserId, int newUserId) {
20043        synchronized (this) {
20044            if (foreground) {
20045                moveUserToForeground(uss, oldUserId, newUserId);
20046            }
20047        }
20048
20049        completeSwitchAndInitialize(uss, newUserId, true, false);
20050    }
20051
20052    void moveUserToForeground(UserState uss, int oldUserId, int newUserId) {
20053        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
20054        if (homeInFront) {
20055            startHomeActivityLocked(newUserId, "moveUserToFroreground");
20056        } else {
20057            mStackSupervisor.resumeTopActivitiesLocked();
20058        }
20059        EventLogTags.writeAmSwitchUser(newUserId);
20060        getUserManagerLocked().onUserForeground(newUserId);
20061        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
20062    }
20063
20064    void continueUserSwitch(UserState uss, int oldUserId, int newUserId) {
20065        completeSwitchAndInitialize(uss, newUserId, false, true);
20066    }
20067
20068    void completeSwitchAndInitialize(UserState uss, int newUserId,
20069            boolean clearInitializing, boolean clearSwitching) {
20070        boolean unfrozen = false;
20071        synchronized (this) {
20072            if (clearInitializing) {
20073                uss.initializing = false;
20074                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
20075            }
20076            if (clearSwitching) {
20077                uss.switching = false;
20078            }
20079            if (!uss.switching && !uss.initializing) {
20080                mWindowManager.stopFreezingScreen();
20081                unfrozen = true;
20082            }
20083        }
20084        if (unfrozen) {
20085            mHandler.removeMessages(REPORT_USER_SWITCH_COMPLETE_MSG);
20086            mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_COMPLETE_MSG,
20087                    newUserId, 0));
20088        }
20089        stopGuestUserIfBackground();
20090    }
20091
20092    /** Called on handler thread */
20093    void dispatchUserSwitchComplete(int userId) {
20094        final int observerCount = mUserSwitchObservers.beginBroadcast();
20095        for (int i = 0; i < observerCount; i++) {
20096            try {
20097                mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(userId);
20098            } catch (RemoteException e) {
20099            }
20100        }
20101        mUserSwitchObservers.finishBroadcast();
20102    }
20103
20104    /**
20105     * Stops the guest user if it has gone to the background.
20106     */
20107    private void stopGuestUserIfBackground() {
20108        synchronized (this) {
20109            final int num = mUserLru.size();
20110            for (int i = 0; i < num; i++) {
20111                Integer oldUserId = mUserLru.get(i);
20112                UserState oldUss = mStartedUsers.get(oldUserId);
20113                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
20114                        || oldUss.mState == UserState.STATE_STOPPING
20115                        || oldUss.mState == UserState.STATE_SHUTDOWN) {
20116                    continue;
20117                }
20118                UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
20119                if (userInfo.isGuest()) {
20120                    // This is a user to be stopped.
20121                    stopUserLocked(oldUserId, null);
20122                    break;
20123                }
20124            }
20125        }
20126    }
20127
20128    void scheduleStartProfilesLocked() {
20129        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20130            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20131                    DateUtils.SECOND_IN_MILLIS);
20132        }
20133    }
20134
20135    void startProfilesLocked() {
20136        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
20137        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
20138                mCurrentUserId, false /* enabledOnly */);
20139        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
20140        for (UserInfo user : profiles) {
20141            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
20142                    && user.id != mCurrentUserId) {
20143                toStart.add(user);
20144            }
20145        }
20146        final int n = toStart.size();
20147        int i = 0;
20148        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
20149            startUserInBackground(toStart.get(i).id);
20150        }
20151        if (i < n) {
20152            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
20153        }
20154    }
20155
20156    void finishUserBoot(UserState uss) {
20157        synchronized (this) {
20158            if (uss.mState == UserState.STATE_BOOTING
20159                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
20160                uss.mState = UserState.STATE_RUNNING;
20161                final int userId = uss.mHandle.getIdentifier();
20162                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
20163                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20164                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
20165                broadcastIntentLocked(null, null, intent,
20166                        null, null, 0, null, null,
20167                        new String[] {android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
20168                        AppOpsManager.OP_NONE, null, true, false, MY_PID, Process.SYSTEM_UID,
20169                        userId);
20170            }
20171        }
20172    }
20173
20174    void finishUserSwitch(UserState uss) {
20175        synchronized (this) {
20176            finishUserBoot(uss);
20177
20178            startProfilesLocked();
20179
20180            int num = mUserLru.size();
20181            int i = 0;
20182            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
20183                Integer oldUserId = mUserLru.get(i);
20184                UserState oldUss = mStartedUsers.get(oldUserId);
20185                if (oldUss == null) {
20186                    // Shouldn't happen, but be sane if it does.
20187                    mUserLru.remove(i);
20188                    num--;
20189                    continue;
20190                }
20191                if (oldUss.mState == UserState.STATE_STOPPING
20192                        || oldUss.mState == UserState.STATE_SHUTDOWN) {
20193                    // This user is already stopping, doesn't count.
20194                    num--;
20195                    i++;
20196                    continue;
20197                }
20198                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
20199                    // Owner and current can't be stopped, but count as running.
20200                    i++;
20201                    continue;
20202                }
20203                // This is a user to be stopped.
20204                stopUserLocked(oldUserId, null);
20205                num--;
20206                i++;
20207            }
20208        }
20209    }
20210
20211    @Override
20212    public int stopUser(final int userId, final IStopUserCallback callback) {
20213        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20214                != PackageManager.PERMISSION_GRANTED) {
20215            String msg = "Permission Denial: switchUser() from pid="
20216                    + Binder.getCallingPid()
20217                    + ", uid=" + Binder.getCallingUid()
20218                    + " requires " + INTERACT_ACROSS_USERS_FULL;
20219            Slog.w(TAG, msg);
20220            throw new SecurityException(msg);
20221        }
20222        if (userId < 0 || userId == UserHandle.USER_OWNER) {
20223            throw new IllegalArgumentException("Can't stop primary user " + userId);
20224        }
20225        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
20226        synchronized (this) {
20227            return stopUserLocked(userId, callback);
20228        }
20229    }
20230
20231    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
20232        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
20233        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
20234            return ActivityManager.USER_OP_IS_CURRENT;
20235        }
20236
20237        final UserState uss = mStartedUsers.get(userId);
20238        if (uss == null) {
20239            // User is not started, nothing to do...  but we do need to
20240            // callback if requested.
20241            if (callback != null) {
20242                mHandler.post(new Runnable() {
20243                    @Override
20244                    public void run() {
20245                        try {
20246                            callback.userStopped(userId);
20247                        } catch (RemoteException e) {
20248                        }
20249                    }
20250                });
20251            }
20252            return ActivityManager.USER_OP_SUCCESS;
20253        }
20254
20255        if (callback != null) {
20256            uss.mStopCallbacks.add(callback);
20257        }
20258
20259        if (uss.mState != UserState.STATE_STOPPING
20260                && uss.mState != UserState.STATE_SHUTDOWN) {
20261            uss.mState = UserState.STATE_STOPPING;
20262            updateStartedUserArrayLocked();
20263
20264            long ident = Binder.clearCallingIdentity();
20265            try {
20266                // We are going to broadcast ACTION_USER_STOPPING and then
20267                // once that is done send a final ACTION_SHUTDOWN and then
20268                // stop the user.
20269                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
20270                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20271                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20272                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
20273                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
20274                // This is the result receiver for the final shutdown broadcast.
20275                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
20276                    @Override
20277                    public void performReceive(Intent intent, int resultCode, String data,
20278                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
20279                        finishUserStop(uss);
20280                    }
20281                };
20282                // This is the result receiver for the initial stopping broadcast.
20283                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
20284                    @Override
20285                    public void performReceive(Intent intent, int resultCode, String data,
20286                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
20287                        // On to the next.
20288                        synchronized (ActivityManagerService.this) {
20289                            if (uss.mState != UserState.STATE_STOPPING) {
20290                                // Whoops, we are being started back up.  Abort, abort!
20291                                return;
20292                            }
20293                            uss.mState = UserState.STATE_SHUTDOWN;
20294                        }
20295                        mBatteryStatsService.noteEvent(
20296                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
20297                                Integer.toString(userId), userId);
20298                        mSystemServiceManager.stopUser(userId);
20299                        broadcastIntentLocked(null, null, shutdownIntent,
20300                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
20301                                null, true, false, MY_PID, Process.SYSTEM_UID, userId);
20302                    }
20303                };
20304                // Kick things off.
20305                broadcastIntentLocked(null, null, stoppingIntent,
20306                        null, stoppingReceiver, 0, null, null,
20307                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
20308                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
20309            } finally {
20310                Binder.restoreCallingIdentity(ident);
20311            }
20312        }
20313
20314        return ActivityManager.USER_OP_SUCCESS;
20315    }
20316
20317    void finishUserStop(UserState uss) {
20318        final int userId = uss.mHandle.getIdentifier();
20319        boolean stopped;
20320        ArrayList<IStopUserCallback> callbacks;
20321        synchronized (this) {
20322            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
20323            if (mStartedUsers.get(userId) != uss) {
20324                stopped = false;
20325            } else if (uss.mState != UserState.STATE_SHUTDOWN) {
20326                stopped = false;
20327            } else {
20328                stopped = true;
20329                // User can no longer run.
20330                mStartedUsers.remove(userId);
20331                mUserLru.remove(Integer.valueOf(userId));
20332                updateStartedUserArrayLocked();
20333
20334                // Clean up all state and processes associated with the user.
20335                // Kill all the processes for the user.
20336                forceStopUserLocked(userId, "finish user");
20337            }
20338
20339            // Explicitly remove the old information in mRecentTasks.
20340            mRecentTasks.removeTasksForUserLocked(userId);
20341        }
20342
20343        for (int i=0; i<callbacks.size(); i++) {
20344            try {
20345                if (stopped) callbacks.get(i).userStopped(userId);
20346                else callbacks.get(i).userStopAborted(userId);
20347            } catch (RemoteException e) {
20348            }
20349        }
20350
20351        if (stopped) {
20352            mSystemServiceManager.cleanupUser(userId);
20353            synchronized (this) {
20354                mStackSupervisor.removeUserLocked(userId);
20355            }
20356        }
20357    }
20358
20359    @Override
20360    public UserInfo getCurrentUser() {
20361        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
20362                != PackageManager.PERMISSION_GRANTED) && (
20363                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20364                != PackageManager.PERMISSION_GRANTED)) {
20365            String msg = "Permission Denial: getCurrentUser() from pid="
20366                    + Binder.getCallingPid()
20367                    + ", uid=" + Binder.getCallingUid()
20368                    + " requires " + INTERACT_ACROSS_USERS;
20369            Slog.w(TAG, msg);
20370            throw new SecurityException(msg);
20371        }
20372        synchronized (this) {
20373            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20374            return getUserManagerLocked().getUserInfo(userId);
20375        }
20376    }
20377
20378    int getCurrentUserIdLocked() {
20379        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20380    }
20381
20382    @Override
20383    public boolean isUserRunning(int userId, boolean orStopped) {
20384        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20385                != PackageManager.PERMISSION_GRANTED) {
20386            String msg = "Permission Denial: isUserRunning() from pid="
20387                    + Binder.getCallingPid()
20388                    + ", uid=" + Binder.getCallingUid()
20389                    + " requires " + INTERACT_ACROSS_USERS;
20390            Slog.w(TAG, msg);
20391            throw new SecurityException(msg);
20392        }
20393        synchronized (this) {
20394            return isUserRunningLocked(userId, orStopped);
20395        }
20396    }
20397
20398    boolean isUserRunningLocked(int userId, boolean orStopped) {
20399        UserState state = mStartedUsers.get(userId);
20400        if (state == null) {
20401            return false;
20402        }
20403        if (orStopped) {
20404            return true;
20405        }
20406        return state.mState != UserState.STATE_STOPPING
20407                && state.mState != UserState.STATE_SHUTDOWN;
20408    }
20409
20410    @Override
20411    public int[] getRunningUserIds() {
20412        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20413                != PackageManager.PERMISSION_GRANTED) {
20414            String msg = "Permission Denial: isUserRunning() from pid="
20415                    + Binder.getCallingPid()
20416                    + ", uid=" + Binder.getCallingUid()
20417                    + " requires " + INTERACT_ACROSS_USERS;
20418            Slog.w(TAG, msg);
20419            throw new SecurityException(msg);
20420        }
20421        synchronized (this) {
20422            return mStartedUserArray;
20423        }
20424    }
20425
20426    private void updateStartedUserArrayLocked() {
20427        int num = 0;
20428        for (int i=0; i<mStartedUsers.size();  i++) {
20429            UserState uss = mStartedUsers.valueAt(i);
20430            // This list does not include stopping users.
20431            if (uss.mState != UserState.STATE_STOPPING
20432                    && uss.mState != UserState.STATE_SHUTDOWN) {
20433                num++;
20434            }
20435        }
20436        mStartedUserArray = new int[num];
20437        num = 0;
20438        for (int i=0; i<mStartedUsers.size();  i++) {
20439            UserState uss = mStartedUsers.valueAt(i);
20440            if (uss.mState != UserState.STATE_STOPPING
20441                    && uss.mState != UserState.STATE_SHUTDOWN) {
20442                mStartedUserArray[num] = mStartedUsers.keyAt(i);
20443                num++;
20444            }
20445        }
20446    }
20447
20448    @Override
20449    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20450        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20451                != PackageManager.PERMISSION_GRANTED) {
20452            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
20453                    + Binder.getCallingPid()
20454                    + ", uid=" + Binder.getCallingUid()
20455                    + " requires " + INTERACT_ACROSS_USERS_FULL;
20456            Slog.w(TAG, msg);
20457            throw new SecurityException(msg);
20458        }
20459
20460        mUserSwitchObservers.register(observer);
20461    }
20462
20463    @Override
20464    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20465        mUserSwitchObservers.unregister(observer);
20466    }
20467
20468    int[] getUsersLocked() {
20469        UserManagerService ums = getUserManagerLocked();
20470        return ums != null ? ums.getUserIds() : new int[] { 0 };
20471    }
20472
20473    UserManagerService getUserManagerLocked() {
20474        if (mUserManager == null) {
20475            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
20476            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
20477        }
20478        return mUserManager;
20479    }
20480
20481    private int applyUserId(int uid, int userId) {
20482        return UserHandle.getUid(userId, uid);
20483    }
20484
20485    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20486        if (info == null) return null;
20487        ApplicationInfo newInfo = new ApplicationInfo(info);
20488        newInfo.uid = applyUserId(info.uid, userId);
20489        newInfo.dataDir = Environment
20490                .getDataUserPackageDirectory(info.volumeUuid, userId, info.packageName)
20491                .getAbsolutePath();
20492        return newInfo;
20493    }
20494
20495    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20496        if (aInfo == null
20497                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20498            return aInfo;
20499        }
20500
20501        ActivityInfo info = new ActivityInfo(aInfo);
20502        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20503        return info;
20504    }
20505
20506    private final class LocalService extends ActivityManagerInternal {
20507        @Override
20508        public void onWakefulnessChanged(int wakefulness) {
20509            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20510        }
20511
20512        @Override
20513        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20514                String processName, String abiOverride, int uid, Runnable crashHandler) {
20515            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20516                    processName, abiOverride, uid, crashHandler);
20517        }
20518
20519        @Override
20520        public SleepToken acquireSleepToken(String tag) {
20521            Preconditions.checkNotNull(tag);
20522
20523            synchronized (ActivityManagerService.this) {
20524                SleepTokenImpl token = new SleepTokenImpl(tag);
20525                mSleepTokens.add(token);
20526                updateSleepIfNeededLocked();
20527                return token;
20528            }
20529        }
20530
20531        @Override
20532        public ComponentName getHomeActivityForUser(int userId) {
20533            synchronized (ActivityManagerService.this) {
20534                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20535                return homeActivity == null ? null : homeActivity.realActivity;
20536            }
20537        }
20538    }
20539
20540    private final class SleepTokenImpl extends SleepToken {
20541        private final String mTag;
20542        private final long mAcquireTime;
20543
20544        public SleepTokenImpl(String tag) {
20545            mTag = tag;
20546            mAcquireTime = SystemClock.uptimeMillis();
20547        }
20548
20549        @Override
20550        public void release() {
20551            synchronized (ActivityManagerService.this) {
20552                if (mSleepTokens.remove(this)) {
20553                    updateSleepIfNeededLocked();
20554                }
20555            }
20556        }
20557
20558        @Override
20559        public String toString() {
20560            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20561        }
20562    }
20563
20564    /**
20565     * An implementation of IAppTask, that allows an app to manage its own tasks via
20566     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
20567     * only the process that calls getAppTasks() can call the AppTask methods.
20568     */
20569    class AppTaskImpl extends IAppTask.Stub {
20570        private int mTaskId;
20571        private int mCallingUid;
20572
20573        public AppTaskImpl(int taskId, int callingUid) {
20574            mTaskId = taskId;
20575            mCallingUid = callingUid;
20576        }
20577
20578        private void checkCaller() {
20579            if (mCallingUid != Binder.getCallingUid()) {
20580                throw new SecurityException("Caller " + mCallingUid
20581                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
20582            }
20583        }
20584
20585        @Override
20586        public void finishAndRemoveTask() {
20587            checkCaller();
20588
20589            synchronized (ActivityManagerService.this) {
20590                long origId = Binder.clearCallingIdentity();
20591                try {
20592                    if (!removeTaskByIdLocked(mTaskId, false)) {
20593                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20594                    }
20595                } finally {
20596                    Binder.restoreCallingIdentity(origId);
20597                }
20598            }
20599        }
20600
20601        @Override
20602        public ActivityManager.RecentTaskInfo getTaskInfo() {
20603            checkCaller();
20604
20605            synchronized (ActivityManagerService.this) {
20606                long origId = Binder.clearCallingIdentity();
20607                try {
20608                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20609                    if (tr == null) {
20610                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20611                    }
20612                    return createRecentTaskInfoFromTaskRecord(tr);
20613                } finally {
20614                    Binder.restoreCallingIdentity(origId);
20615                }
20616            }
20617        }
20618
20619        @Override
20620        public void moveToFront() {
20621            checkCaller();
20622            // Will bring task to front if it already has a root activity.
20623            startActivityFromRecentsInner(mTaskId, null);
20624        }
20625
20626        @Override
20627        public int startActivity(IBinder whoThread, String callingPackage,
20628                Intent intent, String resolvedType, Bundle options) {
20629            checkCaller();
20630
20631            int callingUser = UserHandle.getCallingUserId();
20632            TaskRecord tr;
20633            IApplicationThread appThread;
20634            synchronized (ActivityManagerService.this) {
20635                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20636                if (tr == null) {
20637                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20638                }
20639                appThread = ApplicationThreadNative.asInterface(whoThread);
20640                if (appThread == null) {
20641                    throw new IllegalArgumentException("Bad app thread " + appThread);
20642                }
20643            }
20644            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
20645                    resolvedType, null, null, null, null, 0, 0, null, null,
20646                    null, options, false, callingUser, null, tr);
20647        }
20648
20649        @Override
20650        public void setExcludeFromRecents(boolean exclude) {
20651            checkCaller();
20652
20653            synchronized (ActivityManagerService.this) {
20654                long origId = Binder.clearCallingIdentity();
20655                try {
20656                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20657                    if (tr == null) {
20658                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20659                    }
20660                    Intent intent = tr.getBaseIntent();
20661                    if (exclude) {
20662                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20663                    } else {
20664                        intent.setFlags(intent.getFlags()
20665                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20666                    }
20667                } finally {
20668                    Binder.restoreCallingIdentity(origId);
20669                }
20670            }
20671        }
20672    }
20673}
20674