ActivityManagerService.java revision 65052ba4fa266dcf3a31c51317418301fe6d1a0a
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.Trace;
213import android.os.UpdateLock;
214import android.os.UserHandle;
215import android.os.UserManager;
216import android.provider.Settings;
217import android.text.format.DateUtils;
218import android.text.format.Time;
219import android.util.AtomicFile;
220import android.util.EventLog;
221import android.util.Log;
222import android.util.Pair;
223import android.util.PrintWriterPrinter;
224import android.util.Slog;
225import android.util.SparseArray;
226import android.util.TimeUtils;
227import android.util.Xml;
228import android.view.Gravity;
229import android.view.LayoutInflater;
230import android.view.View;
231import android.view.WindowManager;
232
233import dalvik.system.VMRuntime;
234
235import java.io.BufferedInputStream;
236import java.io.BufferedOutputStream;
237import java.io.DataInputStream;
238import java.io.DataOutputStream;
239import java.io.File;
240import java.io.FileDescriptor;
241import java.io.FileInputStream;
242import java.io.FileNotFoundException;
243import java.io.FileOutputStream;
244import java.io.IOException;
245import java.io.InputStreamReader;
246import java.io.PrintWriter;
247import java.io.StringWriter;
248import java.lang.ref.WeakReference;
249import java.nio.charset.StandardCharsets;
250import java.util.ArrayList;
251import java.util.Arrays;
252import java.util.Collections;
253import java.util.Comparator;
254import java.util.HashMap;
255import java.util.HashSet;
256import java.util.Iterator;
257import java.util.List;
258import java.util.Locale;
259import java.util.Map;
260import java.util.Set;
261import java.util.concurrent.atomic.AtomicBoolean;
262import java.util.concurrent.atomic.AtomicLong;
263
264public final class ActivityManagerService extends ActivityManagerNative
265        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
266
267    // File that stores last updated system version and called preboot receivers
268    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
269
270    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
271    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
272    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
273    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
274    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
275    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
276    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
277    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
278    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
279    private static final String TAG_LRU = TAG + POSTFIX_LRU;
280    private static final String TAG_MU = TAG + POSTFIX_MU;
281    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
282    private static final String TAG_POWER = TAG + POSTFIX_POWER;
283    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
284    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
285    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
286    private static final String TAG_PSS = TAG + POSTFIX_PSS;
287    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
288    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
289    private static final String TAG_STACK = TAG + POSTFIX_STACK;
290    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
291    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
292    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
293    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
294    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
295
296    /** Control over CPU and battery monitoring */
297    // write battery stats every 30 minutes.
298    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
299    static final boolean MONITOR_CPU_USAGE = true;
300    // don't sample cpu less than every 5 seconds.
301    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
302    // wait possibly forever for next cpu sample.
303    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
304    static final boolean MONITOR_THREAD_CPU_USAGE = false;
305
306    // The flags that are set for all calls we make to the package manager.
307    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
308
309    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
310
311    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
312
313    // Amount of time after a call to stopAppSwitches() during which we will
314    // prevent further untrusted switches from happening.
315    static final long APP_SWITCH_DELAY_TIME = 5*1000;
316
317    // How long we wait for a launched process to attach to the activity manager
318    // before we decide it's never going to come up for real.
319    static final int PROC_START_TIMEOUT = 10*1000;
320
321    // How long we wait for a launched process to attach to the activity manager
322    // before we decide it's never going to come up for real, when the process was
323    // started with a wrapper for instrumentation (such as Valgrind) because it
324    // could take much longer than usual.
325    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
326
327    // How long to wait after going idle before forcing apps to GC.
328    static final int GC_TIMEOUT = 5*1000;
329
330    // The minimum amount of time between successive GC requests for a process.
331    static final int GC_MIN_INTERVAL = 60*1000;
332
333    // The minimum amount of time between successive PSS requests for a process.
334    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
335
336    // The minimum amount of time between successive PSS requests for a process
337    // when the request is due to the memory state being lowered.
338    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
339
340    // The rate at which we check for apps using excessive power -- 15 mins.
341    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
342
343    // The minimum sample duration we will allow before deciding we have
344    // enough data on wake locks to start killing things.
345    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
346
347    // The minimum sample duration we will allow before deciding we have
348    // enough data on CPU usage to start killing things.
349    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
350
351    // How long we allow a receiver to run before giving up on it.
352    static final int BROADCAST_FG_TIMEOUT = 10*1000;
353    static final int BROADCAST_BG_TIMEOUT = 60*1000;
354
355    // How long we wait until we timeout on key dispatching.
356    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
357
358    // How long we wait until we timeout on key dispatching during instrumentation.
359    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
360
361    // Amount of time we wait for observers to handle a user switch before
362    // giving up on them and unfreezing the screen.
363    static final int USER_SWITCH_TIMEOUT = 2*1000;
364
365    // This is the amount of time an app needs to be running a foreground service before
366    // we will consider it to be doing interaction for usage stats.
367    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
368
369    // Maximum number of users we allow to be running at a time.
370    static final int MAX_RUNNING_USERS = 3;
371
372    // How long to wait in getAssistContextExtras for the activity and foreground services
373    // to respond with the result.
374    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
375
376    // How long top wait when going through the modern assist (which doesn't need to block
377    // on getting this result before starting to launch its UI).
378    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
379
380    // Maximum number of persisted Uri grants a package is allowed
381    static final int MAX_PERSISTED_URI_GRANTS = 128;
382
383    static final int MY_PID = Process.myPid();
384
385    static final String[] EMPTY_STRING_ARRAY = new String[0];
386
387    // How many bytes to write into the dropbox log before truncating
388    static final int DROPBOX_MAX_SIZE = 256 * 1024;
389
390    // Access modes for handleIncomingUser.
391    static final int ALLOW_NON_FULL = 0;
392    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
393    static final int ALLOW_FULL_ONLY = 2;
394
395    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
396
397    // Delay in notifying task stack change listeners (in millis)
398    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
399
400    // Necessary ApplicationInfo flags to mark an app as persistent
401    private static final int PERSISTENT_MASK =
402            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
403
404
405    // Delay to disable app launch boost
406    static final int APP_BOOST_MESSAGE_DELAY = 3000;
407    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
408    static final int APP_BOOST_TIMEOUT = 2500;
409
410    private static native int nativeMigrateToBoost();
411    private static native int nativeMigrateFromBoost();
412    private boolean mIsBoosted = false;
413    private long mBoostStartTime = 0;
414
415    /** All system services */
416    SystemServiceManager mSystemServiceManager;
417
418    private Installer mInstaller;
419
420    /** Run all ActivityStacks through this */
421    ActivityStackSupervisor mStackSupervisor;
422
423    /** Task stack change listeners. */
424    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
425            new RemoteCallbackList<ITaskStackListener>();
426
427    public IntentFirewall mIntentFirewall;
428
429    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
430    // default actuion automatically.  Important for devices without direct input
431    // devices.
432    private boolean mShowDialogs = true;
433
434    BroadcastQueue mFgBroadcastQueue;
435    BroadcastQueue mBgBroadcastQueue;
436    // Convenient for easy iteration over the queues. Foreground is first
437    // so that dispatch of foreground broadcasts gets precedence.
438    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
439
440    BroadcastQueue broadcastQueueForIntent(Intent intent) {
441        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
442        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
443                "Broadcast intent " + intent + " on "
444                + (isFg ? "foreground" : "background") + " queue");
445        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
446    }
447
448    /**
449     * Activity we have told the window manager to have key focus.
450     */
451    ActivityRecord mFocusedActivity = null;
452
453    /**
454     * User id of the last activity mFocusedActivity was set to.
455     */
456    private int mLastFocusedUserId;
457
458    /**
459     * If non-null, we are tracking the time the user spends in the currently focused app.
460     */
461    private AppTimeTracker mCurAppTimeTracker;
462
463    /**
464     * List of intents that were used to start the most recent tasks.
465     */
466    private final RecentTasks mRecentTasks;
467
468    /**
469     * For addAppTask: cached of the last activity component that was added.
470     */
471    ComponentName mLastAddedTaskComponent;
472
473    /**
474     * For addAppTask: cached of the last activity uid that was added.
475     */
476    int mLastAddedTaskUid;
477
478    /**
479     * For addAppTask: cached of the last ActivityInfo that was added.
480     */
481    ActivityInfo mLastAddedTaskActivity;
482
483    /**
484     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
485     */
486    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
487
488    /**
489     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
490     */
491    String mDeviceOwnerName;
492
493    public class PendingAssistExtras extends Binder implements Runnable {
494        public final ActivityRecord activity;
495        public final Bundle extras;
496        public final Intent intent;
497        public final String hint;
498        public final IResultReceiver receiver;
499        public final int userHandle;
500        public boolean haveResult = false;
501        public Bundle result = null;
502        public AssistStructure structure = null;
503        public AssistContent content = null;
504        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
505                String _hint, IResultReceiver _receiver, int _userHandle) {
506            activity = _activity;
507            extras = _extras;
508            intent = _intent;
509            hint = _hint;
510            receiver = _receiver;
511            userHandle = _userHandle;
512        }
513        @Override
514        public void run() {
515            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
516            synchronized (this) {
517                haveResult = true;
518                notifyAll();
519            }
520            pendingAssistExtrasTimedOut(this);
521        }
522    }
523
524    final ArrayList<PendingAssistExtras> mPendingAssistExtras
525            = new ArrayList<PendingAssistExtras>();
526
527    /**
528     * Process management.
529     */
530    final ProcessList mProcessList = new ProcessList();
531
532    /**
533     * All of the applications we currently have running organized by name.
534     * The keys are strings of the application package name (as
535     * returned by the package manager), and the keys are ApplicationRecord
536     * objects.
537     */
538    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
539
540    /**
541     * Tracking long-term execution of processes to look for abuse and other
542     * bad app behavior.
543     */
544    final ProcessStatsService mProcessStats;
545
546    /**
547     * The currently running isolated processes.
548     */
549    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
550
551    /**
552     * Counter for assigning isolated process uids, to avoid frequently reusing the
553     * same ones.
554     */
555    int mNextIsolatedProcessUid = 0;
556
557    /**
558     * The currently running heavy-weight process, if any.
559     */
560    ProcessRecord mHeavyWeightProcess = null;
561
562    /**
563     * The last time that various processes have crashed.
564     */
565    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
566
567    /**
568     * Information about a process that is currently marked as bad.
569     */
570    static final class BadProcessInfo {
571        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
572            this.time = time;
573            this.shortMsg = shortMsg;
574            this.longMsg = longMsg;
575            this.stack = stack;
576        }
577
578        final long time;
579        final String shortMsg;
580        final String longMsg;
581        final String stack;
582    }
583
584    /**
585     * Set of applications that we consider to be bad, and will reject
586     * incoming broadcasts from (which the user has no control over).
587     * Processes are added to this set when they have crashed twice within
588     * a minimum amount of time; they are removed from it when they are
589     * later restarted (hopefully due to some user action).  The value is the
590     * time it was added to the list.
591     */
592    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
593
594    /**
595     * All of the processes we currently have running organized by pid.
596     * The keys are the pid running the application.
597     *
598     * <p>NOTE: This object is protected by its own lock, NOT the global
599     * activity manager lock!
600     */
601    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
602
603    /**
604     * All of the processes that have been forced to be foreground.  The key
605     * is the pid of the caller who requested it (we hold a death
606     * link on it).
607     */
608    abstract class ForegroundToken implements IBinder.DeathRecipient {
609        int pid;
610        IBinder token;
611    }
612    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
613
614    /**
615     * List of records for processes that someone had tried to start before the
616     * system was ready.  We don't start them at that point, but ensure they
617     * are started by the time booting is complete.
618     */
619    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
620
621    /**
622     * List of persistent applications that are in the process
623     * of being started.
624     */
625    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
626
627    /**
628     * Processes that are being forcibly torn down.
629     */
630    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
631
632    /**
633     * List of running applications, sorted by recent usage.
634     * The first entry in the list is the least recently used.
635     */
636    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
637
638    /**
639     * Where in mLruProcesses that the processes hosting activities start.
640     */
641    int mLruProcessActivityStart = 0;
642
643    /**
644     * Where in mLruProcesses that the processes hosting services start.
645     * This is after (lower index) than mLruProcessesActivityStart.
646     */
647    int mLruProcessServiceStart = 0;
648
649    /**
650     * List of processes that should gc as soon as things are idle.
651     */
652    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
653
654    /**
655     * Processes we want to collect PSS data from.
656     */
657    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
658
659    /**
660     * Last time we requested PSS data of all processes.
661     */
662    long mLastFullPssTime = SystemClock.uptimeMillis();
663
664    /**
665     * If set, the next time we collect PSS data we should do a full collection
666     * with data from native processes and the kernel.
667     */
668    boolean mFullPssPending = false;
669
670    /**
671     * This is the process holding what we currently consider to be
672     * the "home" activity.
673     */
674    ProcessRecord mHomeProcess;
675
676    /**
677     * This is the process holding the activity the user last visited that
678     * is in a different process from the one they are currently in.
679     */
680    ProcessRecord mPreviousProcess;
681
682    /**
683     * The time at which the previous process was last visible.
684     */
685    long mPreviousProcessVisibleTime;
686
687    /**
688     * Track all uids that have actively running processes.
689     */
690    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
691
692    /**
693     * Which users have been started, so are allowed to run code.
694     */
695    final SparseArray<UserState> mStartedUsers = new SparseArray<>();
696
697    /**
698     * LRU list of history of current users.  Most recently current is at the end.
699     */
700    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
701
702    /**
703     * Constant array of the users that are currently started.
704     */
705    int[] mStartedUserArray = new int[] { 0 };
706
707    /**
708     * Registered observers of the user switching mechanics.
709     */
710    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
711            = new RemoteCallbackList<IUserSwitchObserver>();
712
713    /**
714     * Currently active user switch.
715     */
716    Object mCurUserSwitchCallback;
717
718    /**
719     * Packages that the user has asked to have run in screen size
720     * compatibility mode instead of filling the screen.
721     */
722    final CompatModePackages mCompatModePackages;
723
724    /**
725     * Set of IntentSenderRecord objects that are currently active.
726     */
727    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
728            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
729
730    /**
731     * Fingerprints (hashCode()) of stack traces that we've
732     * already logged DropBox entries for.  Guarded by itself.  If
733     * something (rogue user app) forces this over
734     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
735     */
736    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
737    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
738
739    /**
740     * Strict Mode background batched logging state.
741     *
742     * The string buffer is guarded by itself, and its lock is also
743     * used to determine if another batched write is already
744     * in-flight.
745     */
746    private final StringBuilder mStrictModeBuffer = new StringBuilder();
747
748    /**
749     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
750     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
751     */
752    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
753
754    /**
755     * Resolver for broadcast intents to registered receivers.
756     * Holds BroadcastFilter (subclass of IntentFilter).
757     */
758    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
759            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
760        @Override
761        protected boolean allowFilterResult(
762                BroadcastFilter filter, List<BroadcastFilter> dest) {
763            IBinder target = filter.receiverList.receiver.asBinder();
764            for (int i = dest.size() - 1; i >= 0; i--) {
765                if (dest.get(i).receiverList.receiver.asBinder() == target) {
766                    return false;
767                }
768            }
769            return true;
770        }
771
772        @Override
773        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
774            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
775                    || userId == filter.owningUserId) {
776                return super.newResult(filter, match, userId);
777            }
778            return null;
779        }
780
781        @Override
782        protected BroadcastFilter[] newArray(int size) {
783            return new BroadcastFilter[size];
784        }
785
786        @Override
787        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
788            return packageName.equals(filter.packageName);
789        }
790    };
791
792    /**
793     * State of all active sticky broadcasts per user.  Keys are the action of the
794     * sticky Intent, values are an ArrayList of all broadcasted intents with
795     * that action (which should usually be one).  The SparseArray is keyed
796     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
797     * for stickies that are sent to all users.
798     */
799    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
800            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
801
802    final ActiveServices mServices;
803
804    final static class Association {
805        final int mSourceUid;
806        final String mSourceProcess;
807        final int mTargetUid;
808        final ComponentName mTargetComponent;
809        final String mTargetProcess;
810
811        int mCount;
812        long mTime;
813
814        int mNesting;
815        long mStartTime;
816
817        Association(int sourceUid, String sourceProcess, int targetUid,
818                ComponentName targetComponent, String targetProcess) {
819            mSourceUid = sourceUid;
820            mSourceProcess = sourceProcess;
821            mTargetUid = targetUid;
822            mTargetComponent = targetComponent;
823            mTargetProcess = targetProcess;
824        }
825    }
826
827    /**
828     * When service association tracking is enabled, this is all of the associations we
829     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
830     * -> association data.
831     */
832    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
833            mAssociations = new SparseArray<>();
834    boolean mTrackingAssociations;
835
836    /**
837     * Backup/restore process management
838     */
839    String mBackupAppName = null;
840    BackupRecord mBackupTarget = null;
841
842    final ProviderMap mProviderMap;
843
844    /**
845     * List of content providers who have clients waiting for them.  The
846     * application is currently being launched and the provider will be
847     * removed from this list once it is published.
848     */
849    final ArrayList<ContentProviderRecord> mLaunchingProviders
850            = new ArrayList<ContentProviderRecord>();
851
852    /**
853     * File storing persisted {@link #mGrantedUriPermissions}.
854     */
855    private final AtomicFile mGrantFile;
856
857    /** XML constants used in {@link #mGrantFile} */
858    private static final String TAG_URI_GRANTS = "uri-grants";
859    private static final String TAG_URI_GRANT = "uri-grant";
860    private static final String ATTR_USER_HANDLE = "userHandle";
861    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
862    private static final String ATTR_TARGET_USER_ID = "targetUserId";
863    private static final String ATTR_SOURCE_PKG = "sourcePkg";
864    private static final String ATTR_TARGET_PKG = "targetPkg";
865    private static final String ATTR_URI = "uri";
866    private static final String ATTR_MODE_FLAGS = "modeFlags";
867    private static final String ATTR_CREATED_TIME = "createdTime";
868    private static final String ATTR_PREFIX = "prefix";
869
870    /**
871     * Global set of specific {@link Uri} permissions that have been granted.
872     * This optimized lookup structure maps from {@link UriPermission#targetUid}
873     * to {@link UriPermission#uri} to {@link UriPermission}.
874     */
875    @GuardedBy("this")
876    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
877            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
878
879    public static class GrantUri {
880        public final int sourceUserId;
881        public final Uri uri;
882        public boolean prefix;
883
884        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
885            this.sourceUserId = sourceUserId;
886            this.uri = uri;
887            this.prefix = prefix;
888        }
889
890        @Override
891        public int hashCode() {
892            int hashCode = 1;
893            hashCode = 31 * hashCode + sourceUserId;
894            hashCode = 31 * hashCode + uri.hashCode();
895            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
896            return hashCode;
897        }
898
899        @Override
900        public boolean equals(Object o) {
901            if (o instanceof GrantUri) {
902                GrantUri other = (GrantUri) o;
903                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
904                        && prefix == other.prefix;
905            }
906            return false;
907        }
908
909        @Override
910        public String toString() {
911            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
912            if (prefix) result += " [prefix]";
913            return result;
914        }
915
916        public String toSafeString() {
917            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
918            if (prefix) result += " [prefix]";
919            return result;
920        }
921
922        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
923            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
924                    ContentProvider.getUriWithoutUserId(uri), false);
925        }
926    }
927
928    CoreSettingsObserver mCoreSettingsObserver;
929
930    /**
931     * Thread-local storage used to carry caller permissions over through
932     * indirect content-provider access.
933     */
934    private class Identity {
935        public final IBinder token;
936        public final int pid;
937        public final int uid;
938
939        Identity(IBinder _token, int _pid, int _uid) {
940            token = _token;
941            pid = _pid;
942            uid = _uid;
943        }
944    }
945
946    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
947
948    /**
949     * All information we have collected about the runtime performance of
950     * any user id that can impact battery performance.
951     */
952    final BatteryStatsService mBatteryStatsService;
953
954    /**
955     * Information about component usage
956     */
957    UsageStatsManagerInternal mUsageStatsService;
958
959    /**
960     * Access to DeviceIdleController service.
961     */
962    DeviceIdleController.LocalService mLocalDeviceIdleController;
963
964    /**
965     * Information about and control over application operations
966     */
967    final AppOpsService mAppOpsService;
968
969    /**
970     * Save recent tasks information across reboots.
971     */
972    final TaskPersister mTaskPersister;
973
974    /**
975     * Current configuration information.  HistoryRecord objects are given
976     * a reference to this object to indicate which configuration they are
977     * currently running in, so this object must be kept immutable.
978     */
979    Configuration mConfiguration = new Configuration();
980
981    /**
982     * Current sequencing integer of the configuration, for skipping old
983     * configurations.
984     */
985    int mConfigurationSeq = 0;
986
987    /**
988     * Hardware-reported OpenGLES version.
989     */
990    final int GL_ES_VERSION;
991
992    /**
993     * List of initialization arguments to pass to all processes when binding applications to them.
994     * For example, references to the commonly used services.
995     */
996    HashMap<String, IBinder> mAppBindArgs;
997
998    /**
999     * Temporary to avoid allocations.  Protected by main lock.
1000     */
1001    final StringBuilder mStringBuilder = new StringBuilder(256);
1002
1003    /**
1004     * Used to control how we initialize the service.
1005     */
1006    ComponentName mTopComponent;
1007    String mTopAction = Intent.ACTION_MAIN;
1008    String mTopData;
1009    boolean mProcessesReady = false;
1010    boolean mSystemReady = false;
1011    boolean mBooting = false;
1012    boolean mCallFinishBooting = false;
1013    boolean mBootAnimationComplete = false;
1014    boolean mWaitingUpdate = false;
1015    boolean mDidUpdate = false;
1016    boolean mOnBattery = false;
1017    boolean mLaunchWarningShown = false;
1018
1019    Context mContext;
1020
1021    int mFactoryTest;
1022
1023    boolean mCheckedForSetup;
1024
1025    /**
1026     * The time at which we will allow normal application switches again,
1027     * after a call to {@link #stopAppSwitches()}.
1028     */
1029    long mAppSwitchesAllowedTime;
1030
1031    /**
1032     * This is set to true after the first switch after mAppSwitchesAllowedTime
1033     * is set; any switches after that will clear the time.
1034     */
1035    boolean mDidAppSwitch;
1036
1037    /**
1038     * Last time (in realtime) at which we checked for power usage.
1039     */
1040    long mLastPowerCheckRealtime;
1041
1042    /**
1043     * Last time (in uptime) at which we checked for power usage.
1044     */
1045    long mLastPowerCheckUptime;
1046
1047    /**
1048     * Set while we are wanting to sleep, to prevent any
1049     * activities from being started/resumed.
1050     */
1051    private boolean mSleeping = false;
1052
1053    /**
1054     * The process state used for processes that are running the top activities.
1055     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1056     */
1057    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1058
1059    /**
1060     * Set while we are running a voice interaction.  This overrides
1061     * sleeping while it is active.
1062     */
1063    private IVoiceInteractionSession mRunningVoice;
1064
1065    /**
1066     * For some direct access we need to power manager.
1067     */
1068    PowerManagerInternal mLocalPowerManager;
1069
1070    /**
1071     * We want to hold a wake lock while running a voice interaction session, since
1072     * this may happen with the screen off and we need to keep the CPU running to
1073     * be able to continue to interact with the user.
1074     */
1075    PowerManager.WakeLock mVoiceWakeLock;
1076
1077    /**
1078     * State of external calls telling us if the device is awake or asleep.
1079     */
1080    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1081
1082    /**
1083     * A list of tokens that cause the top activity to be put to sleep.
1084     * They are used by components that may hide and block interaction with underlying
1085     * activities.
1086     */
1087    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1088
1089    static final int LOCK_SCREEN_HIDDEN = 0;
1090    static final int LOCK_SCREEN_LEAVING = 1;
1091    static final int LOCK_SCREEN_SHOWN = 2;
1092    /**
1093     * State of external call telling us if the lock screen is shown.
1094     */
1095    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1096
1097    /**
1098     * Set if we are shutting down the system, similar to sleeping.
1099     */
1100    boolean mShuttingDown = false;
1101
1102    /**
1103     * Current sequence id for oom_adj computation traversal.
1104     */
1105    int mAdjSeq = 0;
1106
1107    /**
1108     * Current sequence id for process LRU updating.
1109     */
1110    int mLruSeq = 0;
1111
1112    /**
1113     * Keep track of the non-cached/empty process we last found, to help
1114     * determine how to distribute cached/empty processes next time.
1115     */
1116    int mNumNonCachedProcs = 0;
1117
1118    /**
1119     * Keep track of the number of cached hidden procs, to balance oom adj
1120     * distribution between those and empty procs.
1121     */
1122    int mNumCachedHiddenProcs = 0;
1123
1124    /**
1125     * Keep track of the number of service processes we last found, to
1126     * determine on the next iteration which should be B services.
1127     */
1128    int mNumServiceProcs = 0;
1129    int mNewNumAServiceProcs = 0;
1130    int mNewNumServiceProcs = 0;
1131
1132    /**
1133     * Allow the current computed overall memory level of the system to go down?
1134     * This is set to false when we are killing processes for reasons other than
1135     * memory management, so that the now smaller process list will not be taken as
1136     * an indication that memory is tighter.
1137     */
1138    boolean mAllowLowerMemLevel = false;
1139
1140    /**
1141     * The last computed memory level, for holding when we are in a state that
1142     * processes are going away for other reasons.
1143     */
1144    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1145
1146    /**
1147     * The last total number of process we have, to determine if changes actually look
1148     * like a shrinking number of process due to lower RAM.
1149     */
1150    int mLastNumProcesses;
1151
1152    /**
1153     * The uptime of the last time we performed idle maintenance.
1154     */
1155    long mLastIdleTime = SystemClock.uptimeMillis();
1156
1157    /**
1158     * Total time spent with RAM that has been added in the past since the last idle time.
1159     */
1160    long mLowRamTimeSinceLastIdle = 0;
1161
1162    /**
1163     * If RAM is currently low, when that horrible situation started.
1164     */
1165    long mLowRamStartTime = 0;
1166
1167    /**
1168     * For reporting to battery stats the current top application.
1169     */
1170    private String mCurResumedPackage = null;
1171    private int mCurResumedUid = -1;
1172
1173    /**
1174     * For reporting to battery stats the apps currently running foreground
1175     * service.  The ProcessMap is package/uid tuples; each of these contain
1176     * an array of the currently foreground processes.
1177     */
1178    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1179            = new ProcessMap<ArrayList<ProcessRecord>>();
1180
1181    /**
1182     * This is set if we had to do a delayed dexopt of an app before launching
1183     * it, to increase the ANR timeouts in that case.
1184     */
1185    boolean mDidDexOpt;
1186
1187    /**
1188     * Set if the systemServer made a call to enterSafeMode.
1189     */
1190    boolean mSafeMode;
1191
1192    /**
1193     * If true, we are running under a test environment so will sample PSS from processes
1194     * much more rapidly to try to collect better data when the tests are rapidly
1195     * running through apps.
1196     */
1197    boolean mTestPssMode = false;
1198
1199    String mDebugApp = null;
1200    boolean mWaitForDebugger = false;
1201    boolean mDebugTransient = false;
1202    String mOrigDebugApp = null;
1203    boolean mOrigWaitForDebugger = false;
1204    boolean mAlwaysFinishActivities = false;
1205    IActivityController mController = null;
1206    String mProfileApp = null;
1207    ProcessRecord mProfileProc = null;
1208    String mProfileFile;
1209    ParcelFileDescriptor mProfileFd;
1210    int mSamplingInterval = 0;
1211    boolean mAutoStopProfiler = false;
1212    int mProfileType = 0;
1213    String mOpenGlTraceApp = null;
1214    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1215    String mMemWatchDumpProcName;
1216    String mMemWatchDumpFile;
1217    int mMemWatchDumpPid;
1218    int mMemWatchDumpUid;
1219    String mTrackAllocationApp = null;
1220
1221    final long[] mTmpLong = new long[1];
1222
1223    static final class ProcessChangeItem {
1224        static final int CHANGE_ACTIVITIES = 1<<0;
1225        static final int CHANGE_PROCESS_STATE = 1<<1;
1226        int changes;
1227        int uid;
1228        int pid;
1229        int processState;
1230        boolean foregroundActivities;
1231    }
1232
1233    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1234    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1235
1236    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1237    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1238
1239    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1240    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1241
1242    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1243    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1244
1245    /**
1246     * Runtime CPU use collection thread.  This object's lock is used to
1247     * perform synchronization with the thread (notifying it to run).
1248     */
1249    final Thread mProcessCpuThread;
1250
1251    /**
1252     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1253     * Must acquire this object's lock when accessing it.
1254     * NOTE: this lock will be held while doing long operations (trawling
1255     * through all processes in /proc), so it should never be acquired by
1256     * any critical paths such as when holding the main activity manager lock.
1257     */
1258    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1259            MONITOR_THREAD_CPU_USAGE);
1260    final AtomicLong mLastCpuTime = new AtomicLong(0);
1261    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1262
1263    long mLastWriteTime = 0;
1264
1265    /**
1266     * Used to retain an update lock when the foreground activity is in
1267     * immersive mode.
1268     */
1269    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1270
1271    /**
1272     * Set to true after the system has finished booting.
1273     */
1274    boolean mBooted = false;
1275
1276    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1277    int mProcessLimitOverride = -1;
1278
1279    WindowManagerService mWindowManager;
1280
1281    final ActivityThread mSystemThread;
1282
1283    // Holds the current foreground user's id
1284    int mCurrentUserId = 0;
1285    // Holds the target user's id during a user switch
1286    int mTargetUserId = UserHandle.USER_NULL;
1287    // If there are multiple profiles for the current user, their ids are here
1288    // Currently only the primary user can have managed profiles
1289    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1290
1291    /**
1292     * Mapping from each known user ID to the profile group ID it is associated with.
1293     */
1294    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1295
1296    private UserManagerService mUserManager;
1297
1298    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1299        final ProcessRecord mApp;
1300        final int mPid;
1301        final IApplicationThread mAppThread;
1302
1303        AppDeathRecipient(ProcessRecord app, int pid,
1304                IApplicationThread thread) {
1305            if (DEBUG_ALL) Slog.v(
1306                TAG, "New death recipient " + this
1307                + " for thread " + thread.asBinder());
1308            mApp = app;
1309            mPid = pid;
1310            mAppThread = thread;
1311        }
1312
1313        @Override
1314        public void binderDied() {
1315            if (DEBUG_ALL) Slog.v(
1316                TAG, "Death received in " + this
1317                + " for thread " + mAppThread.asBinder());
1318            synchronized(ActivityManagerService.this) {
1319                appDiedLocked(mApp, mPid, mAppThread, true);
1320            }
1321        }
1322    }
1323
1324    static final int SHOW_ERROR_MSG = 1;
1325    static final int SHOW_NOT_RESPONDING_MSG = 2;
1326    static final int SHOW_FACTORY_ERROR_MSG = 3;
1327    static final int UPDATE_CONFIGURATION_MSG = 4;
1328    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1329    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1330    static final int SERVICE_TIMEOUT_MSG = 12;
1331    static final int UPDATE_TIME_ZONE = 13;
1332    static final int SHOW_UID_ERROR_MSG = 14;
1333    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1334    static final int PROC_START_TIMEOUT_MSG = 20;
1335    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1336    static final int KILL_APPLICATION_MSG = 22;
1337    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1338    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1339    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1340    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1341    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1342    static final int CLEAR_DNS_CACHE_MSG = 28;
1343    static final int UPDATE_HTTP_PROXY_MSG = 29;
1344    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1345    static final int DISPATCH_PROCESSES_CHANGED = 31;
1346    static final int DISPATCH_PROCESS_DIED = 32;
1347    static final int REPORT_MEM_USAGE_MSG = 33;
1348    static final int REPORT_USER_SWITCH_MSG = 34;
1349    static final int CONTINUE_USER_SWITCH_MSG = 35;
1350    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1351    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1352    static final int PERSIST_URI_GRANTS_MSG = 38;
1353    static final int REQUEST_ALL_PSS_MSG = 39;
1354    static final int START_PROFILES_MSG = 40;
1355    static final int UPDATE_TIME = 41;
1356    static final int SYSTEM_USER_START_MSG = 42;
1357    static final int SYSTEM_USER_CURRENT_MSG = 43;
1358    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1359    static final int FINISH_BOOTING_MSG = 45;
1360    static final int START_USER_SWITCH_MSG = 46;
1361    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1362    static final int DISMISS_DIALOG_MSG = 48;
1363    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1364    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1365    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1366    static final int DELETE_DUMPHEAP_MSG = 52;
1367    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1368    static final int DISPATCH_UIDS_CHANGED_MSG = 54;
1369    static final int REPORT_TIME_TRACKER_MSG = 55;
1370    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1371    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1372    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1373
1374    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1375    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1376    static final int FIRST_COMPAT_MODE_MSG = 300;
1377    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1378
1379    CompatModeDialog mCompatModeDialog;
1380    long mLastMemUsageReportTime = 0;
1381
1382    /**
1383     * Flag whether the current user is a "monkey", i.e. whether
1384     * the UI is driven by a UI automation tool.
1385     */
1386    private boolean mUserIsMonkey;
1387
1388    /** Flag whether the device has a Recents UI */
1389    boolean mHasRecents;
1390
1391    /** The dimensions of the thumbnails in the Recents UI. */
1392    int mThumbnailWidth;
1393    int mThumbnailHeight;
1394
1395    final ServiceThread mHandlerThread;
1396    final MainHandler mHandler;
1397    final UiHandler mUiHandler;
1398
1399    final class UiHandler extends Handler {
1400        public UiHandler() {
1401            super(com.android.server.UiThread.get().getLooper(), null, true);
1402        }
1403
1404        @Override
1405        public void handleMessage(Message msg) {
1406            switch (msg.what) {
1407            case SHOW_ERROR_MSG: {
1408                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1409                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1410                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1411                synchronized (ActivityManagerService.this) {
1412                    ProcessRecord proc = (ProcessRecord)data.get("app");
1413                    AppErrorResult res = (AppErrorResult) data.get("result");
1414                    if (proc != null && proc.crashDialog != null) {
1415                        Slog.e(TAG, "App already has crash dialog: " + proc);
1416                        if (res != null) {
1417                            res.set(0);
1418                        }
1419                        return;
1420                    }
1421                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1422                            >= Process.FIRST_APPLICATION_UID
1423                            && proc.pid != MY_PID);
1424                    for (int userId : mCurrentProfileIds) {
1425                        isBackground &= (proc.userId != userId);
1426                    }
1427                    if (isBackground && !showBackground) {
1428                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1429                        if (res != null) {
1430                            res.set(0);
1431                        }
1432                        return;
1433                    }
1434                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1435                        Dialog d = new AppErrorDialog(mContext,
1436                                ActivityManagerService.this, res, proc);
1437                        d.show();
1438                        proc.crashDialog = d;
1439                    } else {
1440                        // The device is asleep, so just pretend that the user
1441                        // saw a crash dialog and hit "force quit".
1442                        if (res != null) {
1443                            res.set(0);
1444                        }
1445                    }
1446                }
1447
1448                ensureBootCompleted();
1449            } break;
1450            case SHOW_NOT_RESPONDING_MSG: {
1451                synchronized (ActivityManagerService.this) {
1452                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1453                    ProcessRecord proc = (ProcessRecord)data.get("app");
1454                    if (proc != null && proc.anrDialog != null) {
1455                        Slog.e(TAG, "App already has anr dialog: " + proc);
1456                        return;
1457                    }
1458
1459                    Intent intent = new Intent("android.intent.action.ANR");
1460                    if (!mProcessesReady) {
1461                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1462                                | Intent.FLAG_RECEIVER_FOREGROUND);
1463                    }
1464                    broadcastIntentLocked(null, null, intent,
1465                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1466                            null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1467
1468                    if (mShowDialogs) {
1469                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1470                                mContext, proc, (ActivityRecord)data.get("activity"),
1471                                msg.arg1 != 0);
1472                        d.show();
1473                        proc.anrDialog = d;
1474                    } else {
1475                        // Just kill the app if there is no dialog to be shown.
1476                        killAppAtUsersRequest(proc, null);
1477                    }
1478                }
1479
1480                ensureBootCompleted();
1481            } break;
1482            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1483                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1484                synchronized (ActivityManagerService.this) {
1485                    ProcessRecord proc = (ProcessRecord) data.get("app");
1486                    if (proc == null) {
1487                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1488                        break;
1489                    }
1490                    if (proc.crashDialog != null) {
1491                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1492                        return;
1493                    }
1494                    AppErrorResult res = (AppErrorResult) data.get("result");
1495                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1496                        Dialog d = new StrictModeViolationDialog(mContext,
1497                                ActivityManagerService.this, res, proc);
1498                        d.show();
1499                        proc.crashDialog = d;
1500                    } else {
1501                        // The device is asleep, so just pretend that the user
1502                        // saw a crash dialog and hit "force quit".
1503                        res.set(0);
1504                    }
1505                }
1506                ensureBootCompleted();
1507            } break;
1508            case SHOW_FACTORY_ERROR_MSG: {
1509                Dialog d = new FactoryErrorDialog(
1510                    mContext, msg.getData().getCharSequence("msg"));
1511                d.show();
1512                ensureBootCompleted();
1513            } break;
1514            case WAIT_FOR_DEBUGGER_MSG: {
1515                synchronized (ActivityManagerService.this) {
1516                    ProcessRecord app = (ProcessRecord)msg.obj;
1517                    if (msg.arg1 != 0) {
1518                        if (!app.waitedForDebugger) {
1519                            Dialog d = new AppWaitingForDebuggerDialog(
1520                                    ActivityManagerService.this,
1521                                    mContext, app);
1522                            app.waitDialog = d;
1523                            app.waitedForDebugger = true;
1524                            d.show();
1525                        }
1526                    } else {
1527                        if (app.waitDialog != null) {
1528                            app.waitDialog.dismiss();
1529                            app.waitDialog = null;
1530                        }
1531                    }
1532                }
1533            } break;
1534            case SHOW_UID_ERROR_MSG: {
1535                if (mShowDialogs) {
1536                    AlertDialog d = new BaseErrorDialog(mContext);
1537                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1538                    d.setCancelable(false);
1539                    d.setTitle(mContext.getText(R.string.android_system_label));
1540                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1541                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1542                            obtainMessage(DISMISS_DIALOG_MSG, d));
1543                    d.show();
1544                }
1545            } break;
1546            case SHOW_FINGERPRINT_ERROR_MSG: {
1547                if (mShowDialogs) {
1548                    AlertDialog d = new BaseErrorDialog(mContext);
1549                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1550                    d.setCancelable(false);
1551                    d.setTitle(mContext.getText(R.string.android_system_label));
1552                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1553                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1554                            obtainMessage(DISMISS_DIALOG_MSG, d));
1555                    d.show();
1556                }
1557            } break;
1558            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1559                synchronized (ActivityManagerService.this) {
1560                    ActivityRecord ar = (ActivityRecord) msg.obj;
1561                    if (mCompatModeDialog != null) {
1562                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1563                                ar.info.applicationInfo.packageName)) {
1564                            return;
1565                        }
1566                        mCompatModeDialog.dismiss();
1567                        mCompatModeDialog = null;
1568                    }
1569                    if (ar != null && false) {
1570                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1571                                ar.packageName)) {
1572                            int mode = mCompatModePackages.computeCompatModeLocked(
1573                                    ar.info.applicationInfo);
1574                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1575                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1576                                mCompatModeDialog = new CompatModeDialog(
1577                                        ActivityManagerService.this, mContext,
1578                                        ar.info.applicationInfo);
1579                                mCompatModeDialog.show();
1580                            }
1581                        }
1582                    }
1583                }
1584                break;
1585            }
1586            case START_USER_SWITCH_MSG: {
1587                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1588                break;
1589            }
1590            case DISMISS_DIALOG_MSG: {
1591                final Dialog d = (Dialog) msg.obj;
1592                d.dismiss();
1593                break;
1594            }
1595            case DISPATCH_PROCESSES_CHANGED: {
1596                dispatchProcessesChanged();
1597                break;
1598            }
1599            case DISPATCH_PROCESS_DIED: {
1600                final int pid = msg.arg1;
1601                final int uid = msg.arg2;
1602                dispatchProcessDied(pid, uid);
1603                break;
1604            }
1605            case DISPATCH_UIDS_CHANGED_MSG: {
1606                dispatchUidsChanged();
1607            } break;
1608            }
1609        }
1610    }
1611
1612    final class MainHandler extends Handler {
1613        public MainHandler(Looper looper) {
1614            super(looper, null, true);
1615        }
1616
1617        @Override
1618        public void handleMessage(Message msg) {
1619            switch (msg.what) {
1620            case UPDATE_CONFIGURATION_MSG: {
1621                final ContentResolver resolver = mContext.getContentResolver();
1622                Settings.System.putConfiguration(resolver, (Configuration) msg.obj);
1623            } break;
1624            case GC_BACKGROUND_PROCESSES_MSG: {
1625                synchronized (ActivityManagerService.this) {
1626                    performAppGcsIfAppropriateLocked();
1627                }
1628            } break;
1629            case SERVICE_TIMEOUT_MSG: {
1630                if (mDidDexOpt) {
1631                    mDidDexOpt = false;
1632                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1633                    nmsg.obj = msg.obj;
1634                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1635                    return;
1636                }
1637                mServices.serviceTimeout((ProcessRecord)msg.obj);
1638            } break;
1639            case UPDATE_TIME_ZONE: {
1640                synchronized (ActivityManagerService.this) {
1641                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1642                        ProcessRecord r = mLruProcesses.get(i);
1643                        if (r.thread != null) {
1644                            try {
1645                                r.thread.updateTimeZone();
1646                            } catch (RemoteException ex) {
1647                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1648                            }
1649                        }
1650                    }
1651                }
1652            } break;
1653            case CLEAR_DNS_CACHE_MSG: {
1654                synchronized (ActivityManagerService.this) {
1655                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1656                        ProcessRecord r = mLruProcesses.get(i);
1657                        if (r.thread != null) {
1658                            try {
1659                                r.thread.clearDnsCache();
1660                            } catch (RemoteException ex) {
1661                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1662                            }
1663                        }
1664                    }
1665                }
1666            } break;
1667            case UPDATE_HTTP_PROXY_MSG: {
1668                ProxyInfo proxy = (ProxyInfo)msg.obj;
1669                String host = "";
1670                String port = "";
1671                String exclList = "";
1672                Uri pacFileUrl = Uri.EMPTY;
1673                if (proxy != null) {
1674                    host = proxy.getHost();
1675                    port = Integer.toString(proxy.getPort());
1676                    exclList = proxy.getExclusionListAsString();
1677                    pacFileUrl = proxy.getPacFileUrl();
1678                }
1679                synchronized (ActivityManagerService.this) {
1680                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1681                        ProcessRecord r = mLruProcesses.get(i);
1682                        if (r.thread != null) {
1683                            try {
1684                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1685                            } catch (RemoteException ex) {
1686                                Slog.w(TAG, "Failed to update http proxy for: " +
1687                                        r.info.processName);
1688                            }
1689                        }
1690                    }
1691                }
1692            } break;
1693            case PROC_START_TIMEOUT_MSG: {
1694                if (mDidDexOpt) {
1695                    mDidDexOpt = false;
1696                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1697                    nmsg.obj = msg.obj;
1698                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1699                    return;
1700                }
1701                ProcessRecord app = (ProcessRecord)msg.obj;
1702                synchronized (ActivityManagerService.this) {
1703                    processStartTimedOutLocked(app);
1704                }
1705            } break;
1706            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1707                synchronized (ActivityManagerService.this) {
1708                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1709                }
1710            } break;
1711            case KILL_APPLICATION_MSG: {
1712                synchronized (ActivityManagerService.this) {
1713                    int appid = msg.arg1;
1714                    boolean restart = (msg.arg2 == 1);
1715                    Bundle bundle = (Bundle)msg.obj;
1716                    String pkg = bundle.getString("pkg");
1717                    String reason = bundle.getString("reason");
1718                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1719                            false, UserHandle.USER_ALL, reason);
1720                }
1721            } break;
1722            case FINALIZE_PENDING_INTENT_MSG: {
1723                ((PendingIntentRecord)msg.obj).completeFinalize();
1724            } break;
1725            case POST_HEAVY_NOTIFICATION_MSG: {
1726                INotificationManager inm = NotificationManager.getService();
1727                if (inm == null) {
1728                    return;
1729                }
1730
1731                ActivityRecord root = (ActivityRecord)msg.obj;
1732                ProcessRecord process = root.app;
1733                if (process == null) {
1734                    return;
1735                }
1736
1737                try {
1738                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1739                    String text = mContext.getString(R.string.heavy_weight_notification,
1740                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1741                    Notification notification = new Notification.Builder(context)
1742                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1743                            .setWhen(0)
1744                            .setOngoing(true)
1745                            .setTicker(text)
1746                            .setColor(mContext.getColor(
1747                                    com.android.internal.R.color.system_notification_accent_color))
1748                            .setContentTitle(text)
1749                            .setContentText(
1750                                    mContext.getText(R.string.heavy_weight_notification_detail))
1751                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1752                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1753                                    new UserHandle(root.userId)))
1754                            .build();
1755                    try {
1756                        int[] outId = new int[1];
1757                        inm.enqueueNotificationWithTag("android", "android", null,
1758                                R.string.heavy_weight_notification,
1759                                notification, outId, root.userId);
1760                    } catch (RuntimeException e) {
1761                        Slog.w(ActivityManagerService.TAG,
1762                                "Error showing notification for heavy-weight app", e);
1763                    } catch (RemoteException e) {
1764                    }
1765                } catch (NameNotFoundException e) {
1766                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1767                }
1768            } break;
1769            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1770                INotificationManager inm = NotificationManager.getService();
1771                if (inm == null) {
1772                    return;
1773                }
1774                try {
1775                    inm.cancelNotificationWithTag("android", null,
1776                            R.string.heavy_weight_notification,  msg.arg1);
1777                } catch (RuntimeException e) {
1778                    Slog.w(ActivityManagerService.TAG,
1779                            "Error canceling notification for service", e);
1780                } catch (RemoteException e) {
1781                }
1782            } break;
1783            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1784                synchronized (ActivityManagerService.this) {
1785                    checkExcessivePowerUsageLocked(true);
1786                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1787                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1788                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1789                }
1790            } break;
1791            case REPORT_MEM_USAGE_MSG: {
1792                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1793                Thread thread = new Thread() {
1794                    @Override public void run() {
1795                        reportMemUsage(memInfos);
1796                    }
1797                };
1798                thread.start();
1799                break;
1800            }
1801            case REPORT_USER_SWITCH_MSG: {
1802                dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1803                break;
1804            }
1805            case CONTINUE_USER_SWITCH_MSG: {
1806                continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1807                break;
1808            }
1809            case USER_SWITCH_TIMEOUT_MSG: {
1810                timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1811                break;
1812            }
1813            case IMMERSIVE_MODE_LOCK_MSG: {
1814                final boolean nextState = (msg.arg1 != 0);
1815                if (mUpdateLock.isHeld() != nextState) {
1816                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1817                            "Applying new update lock state '" + nextState
1818                            + "' for " + (ActivityRecord)msg.obj);
1819                    if (nextState) {
1820                        mUpdateLock.acquire();
1821                    } else {
1822                        mUpdateLock.release();
1823                    }
1824                }
1825                break;
1826            }
1827            case PERSIST_URI_GRANTS_MSG: {
1828                writeGrantedUriPermissions();
1829                break;
1830            }
1831            case REQUEST_ALL_PSS_MSG: {
1832                synchronized (ActivityManagerService.this) {
1833                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1834                }
1835                break;
1836            }
1837            case START_PROFILES_MSG: {
1838                synchronized (ActivityManagerService.this) {
1839                    startProfilesLocked();
1840                }
1841                break;
1842            }
1843            case UPDATE_TIME: {
1844                synchronized (ActivityManagerService.this) {
1845                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1846                        ProcessRecord r = mLruProcesses.get(i);
1847                        if (r.thread != null) {
1848                            try {
1849                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1850                            } catch (RemoteException ex) {
1851                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1852                            }
1853                        }
1854                    }
1855                }
1856                break;
1857            }
1858            case SYSTEM_USER_START_MSG: {
1859                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1860                        Integer.toString(msg.arg1), msg.arg1);
1861                mSystemServiceManager.startUser(msg.arg1);
1862                break;
1863            }
1864            case SYSTEM_USER_CURRENT_MSG: {
1865                mBatteryStatsService.noteEvent(
1866                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1867                        Integer.toString(msg.arg2), msg.arg2);
1868                mBatteryStatsService.noteEvent(
1869                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1870                        Integer.toString(msg.arg1), msg.arg1);
1871                mSystemServiceManager.switchUser(msg.arg1);
1872                break;
1873            }
1874            case ENTER_ANIMATION_COMPLETE_MSG: {
1875                synchronized (ActivityManagerService.this) {
1876                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1877                    if (r != null && r.app != null && r.app.thread != null) {
1878                        try {
1879                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1880                        } catch (RemoteException e) {
1881                        }
1882                    }
1883                }
1884                break;
1885            }
1886            case FINISH_BOOTING_MSG: {
1887                if (msg.arg1 != 0) {
1888                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
1889                    finishBooting();
1890                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1891                }
1892                if (msg.arg2 != 0) {
1893                    enableScreenAfterBoot();
1894                }
1895                break;
1896            }
1897            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1898                try {
1899                    Locale l = (Locale) msg.obj;
1900                    IBinder service = ServiceManager.getService("mount");
1901                    IMountService mountService = IMountService.Stub.asInterface(service);
1902                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1903                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1904                } catch (RemoteException e) {
1905                    Log.e(TAG, "Error storing locale for decryption UI", e);
1906                }
1907                break;
1908            }
1909            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1910                synchronized (ActivityManagerService.this) {
1911                    int i = mTaskStackListeners.beginBroadcast();
1912                    while (i > 0) {
1913                        i--;
1914                        try {
1915                            // Make a one-way callback to the listener
1916                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1917                        } catch (RemoteException e){
1918                            // Handled by the RemoteCallbackList
1919                        }
1920                    }
1921                    mTaskStackListeners.finishBroadcast();
1922                }
1923                break;
1924            }
1925            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1926                final int uid = msg.arg1;
1927                final byte[] firstPacket = (byte[]) msg.obj;
1928
1929                synchronized (mPidsSelfLocked) {
1930                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
1931                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
1932                        if (p.uid == uid) {
1933                            try {
1934                                p.thread.notifyCleartextNetwork(firstPacket);
1935                            } catch (RemoteException ignored) {
1936                            }
1937                        }
1938                    }
1939                }
1940                break;
1941            }
1942            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
1943                final String procName;
1944                final int uid;
1945                final long memLimit;
1946                final String reportPackage;
1947                synchronized (ActivityManagerService.this) {
1948                    procName = mMemWatchDumpProcName;
1949                    uid = mMemWatchDumpUid;
1950                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
1951                    if (val == null) {
1952                        val = mMemWatchProcesses.get(procName, 0);
1953                    }
1954                    if (val != null) {
1955                        memLimit = val.first;
1956                        reportPackage = val.second;
1957                    } else {
1958                        memLimit = 0;
1959                        reportPackage = null;
1960                    }
1961                }
1962                if (procName == null) {
1963                    return;
1964                }
1965
1966                if (DEBUG_PSS) Slog.d(TAG_PSS,
1967                        "Showing dump heap notification from " + procName + "/" + uid);
1968
1969                INotificationManager inm = NotificationManager.getService();
1970                if (inm == null) {
1971                    return;
1972                }
1973
1974                String text = mContext.getString(R.string.dump_heap_notification, procName);
1975
1976
1977                Intent deleteIntent = new Intent();
1978                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
1979                Intent intent = new Intent();
1980                intent.setClassName("android", DumpHeapActivity.class.getName());
1981                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
1982                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
1983                if (reportPackage != null) {
1984                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
1985                }
1986                int userId = UserHandle.getUserId(uid);
1987                Notification notification = new Notification.Builder(mContext)
1988                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1989                        .setWhen(0)
1990                        .setOngoing(true)
1991                        .setAutoCancel(true)
1992                        .setTicker(text)
1993                        .setColor(mContext.getColor(
1994                                com.android.internal.R.color.system_notification_accent_color))
1995                        .setContentTitle(text)
1996                        .setContentText(
1997                                mContext.getText(R.string.dump_heap_notification_detail))
1998                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1999                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2000                                new UserHandle(userId)))
2001                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2002                                deleteIntent, 0, UserHandle.OWNER))
2003                        .build();
2004
2005                try {
2006                    int[] outId = new int[1];
2007                    inm.enqueueNotificationWithTag("android", "android", null,
2008                            R.string.dump_heap_notification,
2009                            notification, outId, userId);
2010                } catch (RuntimeException e) {
2011                    Slog.w(ActivityManagerService.TAG,
2012                            "Error showing notification for dump heap", e);
2013                } catch (RemoteException e) {
2014                }
2015            } break;
2016            case DELETE_DUMPHEAP_MSG: {
2017                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2018                        DumpHeapActivity.JAVA_URI,
2019                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2020                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2021                        UserHandle.myUserId());
2022                synchronized (ActivityManagerService.this) {
2023                    mMemWatchDumpFile = null;
2024                    mMemWatchDumpProcName = null;
2025                    mMemWatchDumpPid = -1;
2026                    mMemWatchDumpUid = -1;
2027                }
2028            } break;
2029            case FOREGROUND_PROFILE_CHANGED_MSG: {
2030                dispatchForegroundProfileChanged(msg.arg1);
2031            } break;
2032            case REPORT_TIME_TRACKER_MSG: {
2033                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2034                tracker.deliverResult(mContext);
2035            } break;
2036            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2037                dispatchUserSwitchComplete(msg.arg1);
2038            } break;
2039            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2040                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2041                try {
2042                    connection.shutdown();
2043                } catch (RemoteException e) {
2044                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2045                }
2046                // Only a UiAutomation can set this flag and now that
2047                // it is finished we make sure it is reset to its default.
2048                mUserIsMonkey = false;
2049            } break;
2050            case APP_BOOST_DEACTIVATE_MSG : {
2051                synchronized(ActivityManagerService.this) {
2052                    if (mIsBoosted) {
2053                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2054                            nativeMigrateFromBoost();
2055                            mIsBoosted = false;
2056                            mBoostStartTime = 0;
2057                        } else {
2058                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2059                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2060                        }
2061                    }
2062                }
2063            } break;
2064            }
2065        }
2066    };
2067
2068    static final int COLLECT_PSS_BG_MSG = 1;
2069
2070    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2071        @Override
2072        public void handleMessage(Message msg) {
2073            switch (msg.what) {
2074            case COLLECT_PSS_BG_MSG: {
2075                long start = SystemClock.uptimeMillis();
2076                MemInfoReader memInfo = null;
2077                synchronized (ActivityManagerService.this) {
2078                    if (mFullPssPending) {
2079                        mFullPssPending = false;
2080                        memInfo = new MemInfoReader();
2081                    }
2082                }
2083                if (memInfo != null) {
2084                    updateCpuStatsNow();
2085                    long nativeTotalPss = 0;
2086                    synchronized (mProcessCpuTracker) {
2087                        final int N = mProcessCpuTracker.countStats();
2088                        for (int j=0; j<N; j++) {
2089                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2090                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2091                                // This is definitely an application process; skip it.
2092                                continue;
2093                            }
2094                            synchronized (mPidsSelfLocked) {
2095                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2096                                    // This is one of our own processes; skip it.
2097                                    continue;
2098                                }
2099                            }
2100                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2101                        }
2102                    }
2103                    memInfo.readMemInfo();
2104                    synchronized (ActivityManagerService.this) {
2105                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2106                                + (SystemClock.uptimeMillis()-start) + "ms");
2107                        final long cachedKb = memInfo.getCachedSizeKb();
2108                        final long freeKb = memInfo.getFreeSizeKb();
2109                        final long zramKb = memInfo.getZramTotalSizeKb();
2110                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2111                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2112                                kernelKb*1024, nativeTotalPss*1024);
2113                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2114                                nativeTotalPss);
2115                    }
2116                }
2117
2118                int num = 0;
2119                long[] tmp = new long[1];
2120                do {
2121                    ProcessRecord proc;
2122                    int procState;
2123                    int pid;
2124                    long lastPssTime;
2125                    synchronized (ActivityManagerService.this) {
2126                        if (mPendingPssProcesses.size() <= 0) {
2127                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2128                                    "Collected PSS of " + num + " processes in "
2129                                    + (SystemClock.uptimeMillis() - start) + "ms");
2130                            mPendingPssProcesses.clear();
2131                            return;
2132                        }
2133                        proc = mPendingPssProcesses.remove(0);
2134                        procState = proc.pssProcState;
2135                        lastPssTime = proc.lastPssTime;
2136                        if (proc.thread != null && procState == proc.setProcState
2137                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2138                                        < SystemClock.uptimeMillis()) {
2139                            pid = proc.pid;
2140                        } else {
2141                            proc = null;
2142                            pid = 0;
2143                        }
2144                    }
2145                    if (proc != null) {
2146                        long pss = Debug.getPss(pid, tmp, null);
2147                        synchronized (ActivityManagerService.this) {
2148                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2149                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2150                                num++;
2151                                recordPssSampleLocked(proc, procState, pss, tmp[0],
2152                                        SystemClock.uptimeMillis());
2153                            }
2154                        }
2155                    }
2156                } while (true);
2157            }
2158            }
2159        }
2160    };
2161
2162    public void setSystemProcess() {
2163        try {
2164            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2165            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2166            ServiceManager.addService("meminfo", new MemBinder(this));
2167            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2168            ServiceManager.addService("dbinfo", new DbBinder(this));
2169            if (MONITOR_CPU_USAGE) {
2170                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2171            }
2172            ServiceManager.addService("permission", new PermissionController(this));
2173            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2174
2175            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2176                    "android", STOCK_PM_FLAGS);
2177            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2178
2179            synchronized (this) {
2180                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2181                app.persistent = true;
2182                app.pid = MY_PID;
2183                app.maxAdj = ProcessList.SYSTEM_ADJ;
2184                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2185                synchronized (mPidsSelfLocked) {
2186                    mPidsSelfLocked.put(app.pid, app);
2187                }
2188                updateLruProcessLocked(app, false, null);
2189                updateOomAdjLocked();
2190            }
2191        } catch (PackageManager.NameNotFoundException e) {
2192            throw new RuntimeException(
2193                    "Unable to find android system package", e);
2194        }
2195    }
2196
2197    public void setWindowManager(WindowManagerService wm) {
2198        mWindowManager = wm;
2199        mStackSupervisor.setWindowManager(wm);
2200    }
2201
2202    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2203        mUsageStatsService = usageStatsManager;
2204    }
2205
2206    public void startObservingNativeCrashes() {
2207        final NativeCrashListener ncl = new NativeCrashListener(this);
2208        ncl.start();
2209    }
2210
2211    public IAppOpsService getAppOpsService() {
2212        return mAppOpsService;
2213    }
2214
2215    static class MemBinder extends Binder {
2216        ActivityManagerService mActivityManagerService;
2217        MemBinder(ActivityManagerService activityManagerService) {
2218            mActivityManagerService = activityManagerService;
2219        }
2220
2221        @Override
2222        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2223            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2224                    != PackageManager.PERMISSION_GRANTED) {
2225                pw.println("Permission Denial: can't dump meminfo from from pid="
2226                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2227                        + " without permission " + android.Manifest.permission.DUMP);
2228                return;
2229            }
2230
2231            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2232        }
2233    }
2234
2235    static class GraphicsBinder extends Binder {
2236        ActivityManagerService mActivityManagerService;
2237        GraphicsBinder(ActivityManagerService activityManagerService) {
2238            mActivityManagerService = activityManagerService;
2239        }
2240
2241        @Override
2242        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2243            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2244                    != PackageManager.PERMISSION_GRANTED) {
2245                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2246                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2247                        + " without permission " + android.Manifest.permission.DUMP);
2248                return;
2249            }
2250
2251            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2252        }
2253    }
2254
2255    static class DbBinder extends Binder {
2256        ActivityManagerService mActivityManagerService;
2257        DbBinder(ActivityManagerService activityManagerService) {
2258            mActivityManagerService = activityManagerService;
2259        }
2260
2261        @Override
2262        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2263            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2264                    != PackageManager.PERMISSION_GRANTED) {
2265                pw.println("Permission Denial: can't dump dbinfo from from pid="
2266                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2267                        + " without permission " + android.Manifest.permission.DUMP);
2268                return;
2269            }
2270
2271            mActivityManagerService.dumpDbInfo(fd, pw, args);
2272        }
2273    }
2274
2275    static class CpuBinder extends Binder {
2276        ActivityManagerService mActivityManagerService;
2277        CpuBinder(ActivityManagerService activityManagerService) {
2278            mActivityManagerService = activityManagerService;
2279        }
2280
2281        @Override
2282        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2283            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2284                    != PackageManager.PERMISSION_GRANTED) {
2285                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2286                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2287                        + " without permission " + android.Manifest.permission.DUMP);
2288                return;
2289            }
2290
2291            synchronized (mActivityManagerService.mProcessCpuTracker) {
2292                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2293                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2294                        SystemClock.uptimeMillis()));
2295            }
2296        }
2297    }
2298
2299    public static final class Lifecycle extends SystemService {
2300        private final ActivityManagerService mService;
2301
2302        public Lifecycle(Context context) {
2303            super(context);
2304            mService = new ActivityManagerService(context);
2305        }
2306
2307        @Override
2308        public void onStart() {
2309            mService.start();
2310        }
2311
2312        public ActivityManagerService getService() {
2313            return mService;
2314        }
2315    }
2316
2317    // Note: This method is invoked on the main thread but may need to attach various
2318    // handlers to other threads.  So take care to be explicit about the looper.
2319    public ActivityManagerService(Context systemContext) {
2320        mContext = systemContext;
2321        mFactoryTest = FactoryTest.getMode();
2322        mSystemThread = ActivityThread.currentActivityThread();
2323
2324        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2325
2326        mHandlerThread = new ServiceThread(TAG,
2327                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2328        mHandlerThread.start();
2329        mHandler = new MainHandler(mHandlerThread.getLooper());
2330        mUiHandler = new UiHandler();
2331
2332        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2333                "foreground", BROADCAST_FG_TIMEOUT, false);
2334        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2335                "background", BROADCAST_BG_TIMEOUT, true);
2336        mBroadcastQueues[0] = mFgBroadcastQueue;
2337        mBroadcastQueues[1] = mBgBroadcastQueue;
2338
2339        mServices = new ActiveServices(this);
2340        mProviderMap = new ProviderMap(this);
2341
2342        // TODO: Move creation of battery stats service outside of activity manager service.
2343        File dataDir = Environment.getDataDirectory();
2344        File systemDir = new File(dataDir, "system");
2345        systemDir.mkdirs();
2346        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2347        mBatteryStatsService.getActiveStatistics().readLocked();
2348        mBatteryStatsService.scheduleWriteToDisk();
2349        mOnBattery = DEBUG_POWER ? true
2350                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2351        mBatteryStatsService.getActiveStatistics().setCallback(this);
2352
2353        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2354
2355        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2356
2357        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2358
2359        // User 0 is the first and only user that runs at boot.
2360        mStartedUsers.put(UserHandle.USER_OWNER, new UserState(UserHandle.OWNER, true));
2361        mUserLru.add(UserHandle.USER_OWNER);
2362        updateStartedUserArrayLocked();
2363
2364        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2365            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2366
2367        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2368
2369        mConfiguration.setToDefaults();
2370        mConfiguration.setLocale(Locale.getDefault());
2371
2372        mConfigurationSeq = mConfiguration.seq = 1;
2373        mProcessCpuTracker.init();
2374
2375        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2376        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2377        mRecentTasks = new RecentTasks(this);
2378        mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
2379        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
2380
2381        mProcessCpuThread = new Thread("CpuTracker") {
2382            @Override
2383            public void run() {
2384                while (true) {
2385                    try {
2386                        try {
2387                            synchronized(this) {
2388                                final long now = SystemClock.uptimeMillis();
2389                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2390                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2391                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2392                                //        + ", write delay=" + nextWriteDelay);
2393                                if (nextWriteDelay < nextCpuDelay) {
2394                                    nextCpuDelay = nextWriteDelay;
2395                                }
2396                                if (nextCpuDelay > 0) {
2397                                    mProcessCpuMutexFree.set(true);
2398                                    this.wait(nextCpuDelay);
2399                                }
2400                            }
2401                        } catch (InterruptedException e) {
2402                        }
2403                        updateCpuStatsNow();
2404                    } catch (Exception e) {
2405                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2406                    }
2407                }
2408            }
2409        };
2410
2411        Watchdog.getInstance().addMonitor(this);
2412        Watchdog.getInstance().addThread(mHandler);
2413    }
2414
2415    public void setSystemServiceManager(SystemServiceManager mgr) {
2416        mSystemServiceManager = mgr;
2417    }
2418
2419    public void setInstaller(Installer installer) {
2420        mInstaller = installer;
2421    }
2422
2423    private void start() {
2424        Process.removeAllProcessGroups();
2425        mProcessCpuThread.start();
2426
2427        mBatteryStatsService.publish(mContext);
2428        mAppOpsService.publish(mContext);
2429        Slog.d("AppOps", "AppOpsService published");
2430        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2431    }
2432
2433    public void initPowerManagement() {
2434        mStackSupervisor.initPowerManagement();
2435        mBatteryStatsService.initPowerManagement();
2436        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2437        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2438        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2439        mVoiceWakeLock.setReferenceCounted(false);
2440    }
2441
2442    @Override
2443    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2444            throws RemoteException {
2445        if (code == SYSPROPS_TRANSACTION) {
2446            // We need to tell all apps about the system property change.
2447            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2448            synchronized(this) {
2449                final int NP = mProcessNames.getMap().size();
2450                for (int ip=0; ip<NP; ip++) {
2451                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2452                    final int NA = apps.size();
2453                    for (int ia=0; ia<NA; ia++) {
2454                        ProcessRecord app = apps.valueAt(ia);
2455                        if (app.thread != null) {
2456                            procs.add(app.thread.asBinder());
2457                        }
2458                    }
2459                }
2460            }
2461
2462            int N = procs.size();
2463            for (int i=0; i<N; i++) {
2464                Parcel data2 = Parcel.obtain();
2465                try {
2466                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2467                } catch (RemoteException e) {
2468                }
2469                data2.recycle();
2470            }
2471        }
2472        try {
2473            return super.onTransact(code, data, reply, flags);
2474        } catch (RuntimeException e) {
2475            // The activity manager only throws security exceptions, so let's
2476            // log all others.
2477            if (!(e instanceof SecurityException)) {
2478                Slog.wtf(TAG, "Activity Manager Crash", e);
2479            }
2480            throw e;
2481        }
2482    }
2483
2484    void updateCpuStats() {
2485        final long now = SystemClock.uptimeMillis();
2486        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2487            return;
2488        }
2489        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2490            synchronized (mProcessCpuThread) {
2491                mProcessCpuThread.notify();
2492            }
2493        }
2494    }
2495
2496    void updateCpuStatsNow() {
2497        synchronized (mProcessCpuTracker) {
2498            mProcessCpuMutexFree.set(false);
2499            final long now = SystemClock.uptimeMillis();
2500            boolean haveNewCpuStats = false;
2501
2502            if (MONITOR_CPU_USAGE &&
2503                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2504                mLastCpuTime.set(now);
2505                mProcessCpuTracker.update();
2506                if (mProcessCpuTracker.hasGoodLastStats()) {
2507                    haveNewCpuStats = true;
2508                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2509                    //Slog.i(TAG, "Total CPU usage: "
2510                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2511
2512                    // Slog the cpu usage if the property is set.
2513                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2514                        int user = mProcessCpuTracker.getLastUserTime();
2515                        int system = mProcessCpuTracker.getLastSystemTime();
2516                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2517                        int irq = mProcessCpuTracker.getLastIrqTime();
2518                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2519                        int idle = mProcessCpuTracker.getLastIdleTime();
2520
2521                        int total = user + system + iowait + irq + softIrq + idle;
2522                        if (total == 0) total = 1;
2523
2524                        EventLog.writeEvent(EventLogTags.CPU,
2525                                ((user+system+iowait+irq+softIrq) * 100) / total,
2526                                (user * 100) / total,
2527                                (system * 100) / total,
2528                                (iowait * 100) / total,
2529                                (irq * 100) / total,
2530                                (softIrq * 100) / total);
2531                    }
2532                }
2533            }
2534
2535            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2536            synchronized(bstats) {
2537                synchronized(mPidsSelfLocked) {
2538                    if (haveNewCpuStats) {
2539                        if (bstats.startAddingCpuLocked()) {
2540                            int totalUTime = 0;
2541                            int totalSTime = 0;
2542                            final int N = mProcessCpuTracker.countStats();
2543                            for (int i=0; i<N; i++) {
2544                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2545                                if (!st.working) {
2546                                    continue;
2547                                }
2548                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2549                                totalUTime += st.rel_utime;
2550                                totalSTime += st.rel_stime;
2551                                if (pr != null) {
2552                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2553                                    if (ps == null || !ps.isActive()) {
2554                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2555                                                pr.info.uid, pr.processName);
2556                                    }
2557                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2558                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2559                                } else {
2560                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2561                                    if (ps == null || !ps.isActive()) {
2562                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2563                                                bstats.mapUid(st.uid), st.name);
2564                                    }
2565                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2566                                }
2567                            }
2568                            final int userTime = mProcessCpuTracker.getLastUserTime();
2569                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2570                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2571                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2572                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2573                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2574                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2575                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2576                        }
2577                    }
2578                }
2579
2580                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2581                    mLastWriteTime = now;
2582                    mBatteryStatsService.scheduleWriteToDisk();
2583                }
2584            }
2585        }
2586    }
2587
2588    @Override
2589    public void batteryNeedsCpuUpdate() {
2590        updateCpuStatsNow();
2591    }
2592
2593    @Override
2594    public void batteryPowerChanged(boolean onBattery) {
2595        // When plugging in, update the CPU stats first before changing
2596        // the plug state.
2597        updateCpuStatsNow();
2598        synchronized (this) {
2599            synchronized(mPidsSelfLocked) {
2600                mOnBattery = DEBUG_POWER ? true : onBattery;
2601            }
2602        }
2603    }
2604
2605    @Override
2606    public void batterySendBroadcast(Intent intent) {
2607        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2608                AppOpsManager.OP_NONE, null, false, false,
2609                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2610    }
2611
2612    /**
2613     * Initialize the application bind args. These are passed to each
2614     * process when the bindApplication() IPC is sent to the process. They're
2615     * lazily setup to make sure the services are running when they're asked for.
2616     */
2617    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2618        if (mAppBindArgs == null) {
2619            mAppBindArgs = new HashMap<>();
2620
2621            // Isolated processes won't get this optimization, so that we don't
2622            // violate the rules about which services they have access to.
2623            if (!isolated) {
2624                // Setup the application init args
2625                mAppBindArgs.put("package", ServiceManager.getService("package"));
2626                mAppBindArgs.put("window", ServiceManager.getService("window"));
2627                mAppBindArgs.put(Context.ALARM_SERVICE,
2628                        ServiceManager.getService(Context.ALARM_SERVICE));
2629            }
2630        }
2631        return mAppBindArgs;
2632    }
2633
2634    final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2635        if (r != null && mFocusedActivity != r) {
2636            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2637            ActivityRecord last = mFocusedActivity;
2638            mFocusedActivity = r;
2639            if (r.task.taskType != ActivityRecord.HOME_ACTIVITY_TYPE
2640                    && r.task.taskType != ActivityRecord.RECENTS_ACTIVITY_TYPE) {
2641                if (mCurAppTimeTracker != r.appTimeTracker) {
2642                    // We are switching app tracking.  Complete the current one.
2643                    if (mCurAppTimeTracker != null) {
2644                        mCurAppTimeTracker.stop();
2645                        mHandler.obtainMessage(REPORT_TIME_TRACKER_MSG,
2646                                mCurAppTimeTracker).sendToTarget();
2647                        mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2648                        mCurAppTimeTracker = null;
2649                    }
2650                    if (r.appTimeTracker != null) {
2651                        mCurAppTimeTracker = r.appTimeTracker;
2652                        startTimeTrackingFocusedActivityLocked();
2653                    }
2654                } else {
2655                    startTimeTrackingFocusedActivityLocked();
2656                }
2657            } else {
2658                r.appTimeTracker = null;
2659            }
2660            if (r.task != null && r.task.voiceInteractor != null) {
2661                startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2662            } else {
2663                finishRunningVoiceLocked();
2664                if (last != null && last.task.voiceSession != null) {
2665                    // We had been in a voice interaction session, but now focused has
2666                    // move to something different.  Just finish the session, we can't
2667                    // return to it and retain the proper state and synchronization with
2668                    // the voice interaction service.
2669                    finishVoiceTask(last.task.voiceSession);
2670                }
2671            }
2672            if (mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
2673                mWindowManager.setFocusedApp(r.appToken, true);
2674            }
2675            applyUpdateLockStateLocked(r);
2676            if (mFocusedActivity.userId != mLastFocusedUserId) {
2677                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2678                mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2679                        mFocusedActivity.userId, 0));
2680                mLastFocusedUserId = mFocusedActivity.userId;
2681            }
2682        }
2683        EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY,
2684                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2685                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2686    }
2687
2688    final void clearFocusedActivity(ActivityRecord r) {
2689        if (mFocusedActivity == r) {
2690            ActivityStack stack = mStackSupervisor.getFocusedStack();
2691            if (stack != null) {
2692                ActivityRecord top = stack.topActivity();
2693                if (top != null && top.userId != mLastFocusedUserId) {
2694                    mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2695                    mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2696                                    top.userId, 0));
2697                    mLastFocusedUserId = top.userId;
2698                }
2699            }
2700            mFocusedActivity = null;
2701            EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, -1, "NULL");
2702        }
2703    }
2704
2705    @Override
2706    public void setFocusedStack(int stackId) {
2707        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2708        synchronized (ActivityManagerService.this) {
2709            ActivityStack stack = mStackSupervisor.getStack(stackId);
2710            if (stack != null) {
2711                ActivityRecord r = stack.topRunningActivityLocked(null);
2712                if (r != null) {
2713                    setFocusedActivityLocked(r, "setFocusedStack");
2714                    mStackSupervisor.resumeTopActivitiesLocked(stack, null, null);
2715                }
2716            }
2717        }
2718    }
2719
2720    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2721    @Override
2722    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2723        synchronized (ActivityManagerService.this) {
2724            if (listener != null) {
2725                mTaskStackListeners.register(listener);
2726            }
2727        }
2728    }
2729
2730    @Override
2731    public void notifyActivityDrawn(IBinder token) {
2732        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2733        synchronized (this) {
2734            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2735            if (r != null) {
2736                r.task.stack.notifyActivityDrawnLocked(r);
2737            }
2738        }
2739    }
2740
2741    final void applyUpdateLockStateLocked(ActivityRecord r) {
2742        // Modifications to the UpdateLock state are done on our handler, outside
2743        // the activity manager's locks.  The new state is determined based on the
2744        // state *now* of the relevant activity record.  The object is passed to
2745        // the handler solely for logging detail, not to be consulted/modified.
2746        final boolean nextState = r != null && r.immersive;
2747        mHandler.sendMessage(
2748                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2749    }
2750
2751    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2752        Message msg = Message.obtain();
2753        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2754        msg.obj = r.task.askedCompatMode ? null : r;
2755        mUiHandler.sendMessage(msg);
2756    }
2757
2758    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2759            String what, Object obj, ProcessRecord srcApp) {
2760        app.lastActivityTime = now;
2761
2762        if (app.activities.size() > 0) {
2763            // Don't want to touch dependent processes that are hosting activities.
2764            return index;
2765        }
2766
2767        int lrui = mLruProcesses.lastIndexOf(app);
2768        if (lrui < 0) {
2769            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2770                    + what + " " + obj + " from " + srcApp);
2771            return index;
2772        }
2773
2774        if (lrui >= index) {
2775            // Don't want to cause this to move dependent processes *back* in the
2776            // list as if they were less frequently used.
2777            return index;
2778        }
2779
2780        if (lrui >= mLruProcessActivityStart) {
2781            // Don't want to touch dependent processes that are hosting activities.
2782            return index;
2783        }
2784
2785        mLruProcesses.remove(lrui);
2786        if (index > 0) {
2787            index--;
2788        }
2789        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2790                + " in LRU list: " + app);
2791        mLruProcesses.add(index, app);
2792        return index;
2793    }
2794
2795    private static void killProcessGroup(int uid, int pid) {
2796        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
2797        Process.killProcessGroup(uid, pid);
2798        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2799    }
2800
2801    final void removeLruProcessLocked(ProcessRecord app) {
2802        int lrui = mLruProcesses.lastIndexOf(app);
2803        if (lrui >= 0) {
2804            if (!app.killed) {
2805                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2806                Process.killProcessQuiet(app.pid);
2807                killProcessGroup(app.info.uid, app.pid);
2808            }
2809            if (lrui <= mLruProcessActivityStart) {
2810                mLruProcessActivityStart--;
2811            }
2812            if (lrui <= mLruProcessServiceStart) {
2813                mLruProcessServiceStart--;
2814            }
2815            mLruProcesses.remove(lrui);
2816        }
2817    }
2818
2819    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2820            ProcessRecord client) {
2821        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2822                || app.treatLikeActivity;
2823        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2824        if (!activityChange && hasActivity) {
2825            // The process has activities, so we are only allowing activity-based adjustments
2826            // to move it.  It should be kept in the front of the list with other
2827            // processes that have activities, and we don't want those to change their
2828            // order except due to activity operations.
2829            return;
2830        }
2831
2832        mLruSeq++;
2833        final long now = SystemClock.uptimeMillis();
2834        app.lastActivityTime = now;
2835
2836        // First a quick reject: if the app is already at the position we will
2837        // put it, then there is nothing to do.
2838        if (hasActivity) {
2839            final int N = mLruProcesses.size();
2840            if (N > 0 && mLruProcesses.get(N-1) == app) {
2841                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
2842                return;
2843            }
2844        } else {
2845            if (mLruProcessServiceStart > 0
2846                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2847                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
2848                return;
2849            }
2850        }
2851
2852        int lrui = mLruProcesses.lastIndexOf(app);
2853
2854        if (app.persistent && lrui >= 0) {
2855            // We don't care about the position of persistent processes, as long as
2856            // they are in the list.
2857            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
2858            return;
2859        }
2860
2861        /* In progress: compute new position first, so we can avoid doing work
2862           if the process is not actually going to move.  Not yet working.
2863        int addIndex;
2864        int nextIndex;
2865        boolean inActivity = false, inService = false;
2866        if (hasActivity) {
2867            // Process has activities, put it at the very tipsy-top.
2868            addIndex = mLruProcesses.size();
2869            nextIndex = mLruProcessServiceStart;
2870            inActivity = true;
2871        } else if (hasService) {
2872            // Process has services, put it at the top of the service list.
2873            addIndex = mLruProcessActivityStart;
2874            nextIndex = mLruProcessServiceStart;
2875            inActivity = true;
2876            inService = true;
2877        } else  {
2878            // Process not otherwise of interest, it goes to the top of the non-service area.
2879            addIndex = mLruProcessServiceStart;
2880            if (client != null) {
2881                int clientIndex = mLruProcesses.lastIndexOf(client);
2882                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2883                        + app);
2884                if (clientIndex >= 0 && addIndex > clientIndex) {
2885                    addIndex = clientIndex;
2886                }
2887            }
2888            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2889        }
2890
2891        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2892                + mLruProcessActivityStart + "): " + app);
2893        */
2894
2895        if (lrui >= 0) {
2896            if (lrui < mLruProcessActivityStart) {
2897                mLruProcessActivityStart--;
2898            }
2899            if (lrui < mLruProcessServiceStart) {
2900                mLruProcessServiceStart--;
2901            }
2902            /*
2903            if (addIndex > lrui) {
2904                addIndex--;
2905            }
2906            if (nextIndex > lrui) {
2907                nextIndex--;
2908            }
2909            */
2910            mLruProcesses.remove(lrui);
2911        }
2912
2913        /*
2914        mLruProcesses.add(addIndex, app);
2915        if (inActivity) {
2916            mLruProcessActivityStart++;
2917        }
2918        if (inService) {
2919            mLruProcessActivityStart++;
2920        }
2921        */
2922
2923        int nextIndex;
2924        if (hasActivity) {
2925            final int N = mLruProcesses.size();
2926            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
2927                // Process doesn't have activities, but has clients with
2928                // activities...  move it up, but one below the top (the top
2929                // should always have a real activity).
2930                if (DEBUG_LRU) Slog.d(TAG_LRU,
2931                        "Adding to second-top of LRU activity list: " + app);
2932                mLruProcesses.add(N - 1, app);
2933                // To keep it from spamming the LRU list (by making a bunch of clients),
2934                // we will push down any other entries owned by the app.
2935                final int uid = app.info.uid;
2936                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
2937                    ProcessRecord subProc = mLruProcesses.get(i);
2938                    if (subProc.info.uid == uid) {
2939                        // We want to push this one down the list.  If the process after
2940                        // it is for the same uid, however, don't do so, because we don't
2941                        // want them internally to be re-ordered.
2942                        if (mLruProcesses.get(i - 1).info.uid != uid) {
2943                            if (DEBUG_LRU) Slog.d(TAG_LRU,
2944                                    "Pushing uid " + uid + " swapping at " + i + ": "
2945                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
2946                            ProcessRecord tmp = mLruProcesses.get(i);
2947                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
2948                            mLruProcesses.set(i - 1, tmp);
2949                            i--;
2950                        }
2951                    } else {
2952                        // A gap, we can stop here.
2953                        break;
2954                    }
2955                }
2956            } else {
2957                // Process has activities, put it at the very tipsy-top.
2958                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
2959                mLruProcesses.add(app);
2960            }
2961            nextIndex = mLruProcessServiceStart;
2962        } else if (hasService) {
2963            // Process has services, put it at the top of the service list.
2964            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
2965            mLruProcesses.add(mLruProcessActivityStart, app);
2966            nextIndex = mLruProcessServiceStart;
2967            mLruProcessActivityStart++;
2968        } else  {
2969            // Process not otherwise of interest, it goes to the top of the non-service area.
2970            int index = mLruProcessServiceStart;
2971            if (client != null) {
2972                // If there is a client, don't allow the process to be moved up higher
2973                // in the list than that client.
2974                int clientIndex = mLruProcesses.lastIndexOf(client);
2975                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
2976                        + " when updating " + app);
2977                if (clientIndex <= lrui) {
2978                    // Don't allow the client index restriction to push it down farther in the
2979                    // list than it already is.
2980                    clientIndex = lrui;
2981                }
2982                if (clientIndex >= 0 && index > clientIndex) {
2983                    index = clientIndex;
2984                }
2985            }
2986            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
2987            mLruProcesses.add(index, app);
2988            nextIndex = index-1;
2989            mLruProcessActivityStart++;
2990            mLruProcessServiceStart++;
2991        }
2992
2993        // If the app is currently using a content provider or service,
2994        // bump those processes as well.
2995        for (int j=app.connections.size()-1; j>=0; j--) {
2996            ConnectionRecord cr = app.connections.valueAt(j);
2997            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2998                    && cr.binding.service.app != null
2999                    && cr.binding.service.app.lruSeq != mLruSeq
3000                    && !cr.binding.service.app.persistent) {
3001                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3002                        "service connection", cr, app);
3003            }
3004        }
3005        for (int j=app.conProviders.size()-1; j>=0; j--) {
3006            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3007            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3008                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3009                        "provider reference", cpr, app);
3010            }
3011        }
3012    }
3013
3014    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3015        if (uid == Process.SYSTEM_UID) {
3016            // The system gets to run in any process.  If there are multiple
3017            // processes with the same uid, just pick the first (this
3018            // should never happen).
3019            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3020            if (procs == null) return null;
3021            final int procCount = procs.size();
3022            for (int i = 0; i < procCount; i++) {
3023                final int procUid = procs.keyAt(i);
3024                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3025                    // Don't use an app process or different user process for system component.
3026                    continue;
3027                }
3028                return procs.valueAt(i);
3029            }
3030        }
3031        ProcessRecord proc = mProcessNames.get(processName, uid);
3032        if (false && proc != null && !keepIfLarge
3033                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3034                && proc.lastCachedPss >= 4000) {
3035            // Turn this condition on to cause killing to happen regularly, for testing.
3036            if (proc.baseProcessTracker != null) {
3037                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3038            }
3039            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3040        } else if (proc != null && !keepIfLarge
3041                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3042                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3043            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3044            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3045                if (proc.baseProcessTracker != null) {
3046                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3047                }
3048                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3049            }
3050        }
3051        return proc;
3052    }
3053
3054    void ensurePackageDexOpt(String packageName) {
3055        IPackageManager pm = AppGlobals.getPackageManager();
3056        try {
3057            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
3058                mDidDexOpt = true;
3059            }
3060        } catch (RemoteException e) {
3061        }
3062    }
3063
3064    boolean isNextTransitionForward() {
3065        int transit = mWindowManager.getPendingAppTransition();
3066        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
3067                || transit == AppTransition.TRANSIT_TASK_OPEN
3068                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
3069    }
3070
3071    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3072            String processName, String abiOverride, int uid, Runnable crashHandler) {
3073        synchronized(this) {
3074            ApplicationInfo info = new ApplicationInfo();
3075            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3076            // For isolated processes, the former contains the parent's uid and the latter the
3077            // actual uid of the isolated process.
3078            // In the special case introduced by this method (which is, starting an isolated
3079            // process directly from the SystemServer without an actual parent app process) the
3080            // closest thing to a parent's uid is SYSTEM_UID.
3081            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3082            // the |isolated| logic in the ProcessRecord constructor.
3083            info.uid = Process.SYSTEM_UID;
3084            info.processName = processName;
3085            info.className = entryPoint;
3086            info.packageName = "android";
3087            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3088                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3089                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3090                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3091                    crashHandler);
3092            return proc != null ? proc.pid : 0;
3093        }
3094    }
3095
3096    final ProcessRecord startProcessLocked(String processName,
3097            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3098            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3099            boolean isolated, boolean keepIfLarge) {
3100        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3101                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3102                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3103                null /* crashHandler */);
3104    }
3105
3106    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3107            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3108            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3109            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3110        long startTime = SystemClock.elapsedRealtime();
3111        ProcessRecord app;
3112        if (!isolated) {
3113            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3114            checkTime(startTime, "startProcess: after getProcessRecord");
3115
3116            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3117                // If we are in the background, then check to see if this process
3118                // is bad.  If so, we will just silently fail.
3119                if (mBadProcesses.get(info.processName, info.uid) != null) {
3120                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3121                            + "/" + info.processName);
3122                    return null;
3123                }
3124            } else {
3125                // When the user is explicitly starting a process, then clear its
3126                // crash count so that we won't make it bad until they see at
3127                // least one crash dialog again, and make the process good again
3128                // if it had been bad.
3129                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3130                        + "/" + info.processName);
3131                mProcessCrashTimes.remove(info.processName, info.uid);
3132                if (mBadProcesses.get(info.processName, info.uid) != null) {
3133                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3134                            UserHandle.getUserId(info.uid), info.uid,
3135                            info.processName);
3136                    mBadProcesses.remove(info.processName, info.uid);
3137                    if (app != null) {
3138                        app.bad = false;
3139                    }
3140                }
3141            }
3142        } else {
3143            // If this is an isolated process, it can't re-use an existing process.
3144            app = null;
3145        }
3146
3147        // app launch boost for big.little configurations
3148        // use cpusets to migrate freshly launched tasks to big cores
3149        synchronized(ActivityManagerService.this) {
3150            nativeMigrateToBoost();
3151            mIsBoosted = true;
3152            mBoostStartTime = SystemClock.uptimeMillis();
3153            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3154            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3155        }
3156
3157        // We don't have to do anything more if:
3158        // (1) There is an existing application record; and
3159        // (2) The caller doesn't think it is dead, OR there is no thread
3160        //     object attached to it so we know it couldn't have crashed; and
3161        // (3) There is a pid assigned to it, so it is either starting or
3162        //     already running.
3163        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3164                + " app=" + app + " knownToBeDead=" + knownToBeDead
3165                + " thread=" + (app != null ? app.thread : null)
3166                + " pid=" + (app != null ? app.pid : -1));
3167        if (app != null && app.pid > 0) {
3168            if (!knownToBeDead || app.thread == null) {
3169                // We already have the app running, or are waiting for it to
3170                // come up (we have a pid but not yet its thread), so keep it.
3171                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3172                // If this is a new package in the process, add the package to the list
3173                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3174                checkTime(startTime, "startProcess: done, added package to proc");
3175                return app;
3176            }
3177
3178            // An application record is attached to a previous process,
3179            // clean it up now.
3180            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3181            checkTime(startTime, "startProcess: bad proc running, killing");
3182            killProcessGroup(app.info.uid, app.pid);
3183            handleAppDiedLocked(app, true, true);
3184            checkTime(startTime, "startProcess: done killing old proc");
3185        }
3186
3187        String hostingNameStr = hostingName != null
3188                ? hostingName.flattenToShortString() : null;
3189
3190        if (app == null) {
3191            checkTime(startTime, "startProcess: creating new process record");
3192            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3193            if (app == null) {
3194                Slog.w(TAG, "Failed making new process record for "
3195                        + processName + "/" + info.uid + " isolated=" + isolated);
3196                return null;
3197            }
3198            app.crashHandler = crashHandler;
3199            checkTime(startTime, "startProcess: done creating new process record");
3200        } else {
3201            // If this is a new package in the process, add the package to the list
3202            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3203            checkTime(startTime, "startProcess: added package to existing proc");
3204        }
3205
3206        // If the system is not ready yet, then hold off on starting this
3207        // process until it is.
3208        if (!mProcessesReady
3209                && !isAllowedWhileBooting(info)
3210                && !allowWhileBooting) {
3211            if (!mProcessesOnHold.contains(app)) {
3212                mProcessesOnHold.add(app);
3213            }
3214            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3215                    "System not ready, putting on hold: " + app);
3216            checkTime(startTime, "startProcess: returning with proc on hold");
3217            return app;
3218        }
3219
3220        checkTime(startTime, "startProcess: stepping in to startProcess");
3221        startProcessLocked(
3222                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3223        checkTime(startTime, "startProcess: done starting proc!");
3224        return (app.pid != 0) ? app : null;
3225    }
3226
3227    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3228        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3229    }
3230
3231    private final void startProcessLocked(ProcessRecord app,
3232            String hostingType, String hostingNameStr) {
3233        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3234                null /* entryPoint */, null /* entryPointArgs */);
3235    }
3236
3237    private final void startProcessLocked(ProcessRecord app, String hostingType,
3238            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3239        long startTime = SystemClock.elapsedRealtime();
3240        if (app.pid > 0 && app.pid != MY_PID) {
3241            checkTime(startTime, "startProcess: removing from pids map");
3242            synchronized (mPidsSelfLocked) {
3243                mPidsSelfLocked.remove(app.pid);
3244                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3245            }
3246            checkTime(startTime, "startProcess: done removing from pids map");
3247            app.setPid(0);
3248        }
3249
3250        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3251                "startProcessLocked removing on hold: " + app);
3252        mProcessesOnHold.remove(app);
3253
3254        checkTime(startTime, "startProcess: starting to update cpu stats");
3255        updateCpuStats();
3256        checkTime(startTime, "startProcess: done updating cpu stats");
3257
3258        try {
3259            try {
3260                if (AppGlobals.getPackageManager().isPackageFrozen(app.info.packageName)) {
3261                    // This is caught below as if we had failed to fork zygote
3262                    throw new RuntimeException("Package " + app.info.packageName + " is frozen!");
3263                }
3264            } catch (RemoteException e) {
3265                throw e.rethrowAsRuntimeException();
3266            }
3267
3268            int uid = app.uid;
3269            int[] gids = null;
3270            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3271            if (!app.isolated) {
3272                int[] permGids = null;
3273                try {
3274                    checkTime(startTime, "startProcess: getting gids from package manager");
3275                    final IPackageManager pm = AppGlobals.getPackageManager();
3276                    permGids = pm.getPackageGids(app.info.packageName, app.userId);
3277                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3278                            MountServiceInternal.class);
3279                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3280                            app.info.packageName);
3281                } catch (RemoteException e) {
3282                    throw e.rethrowAsRuntimeException();
3283                }
3284
3285                /*
3286                 * Add shared application and profile GIDs so applications can share some
3287                 * resources like shared libraries and access user-wide resources
3288                 */
3289                if (ArrayUtils.isEmpty(permGids)) {
3290                    gids = new int[2];
3291                } else {
3292                    gids = new int[permGids.length + 2];
3293                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3294                }
3295                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3296                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3297            }
3298            checkTime(startTime, "startProcess: building args");
3299            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3300                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3301                        && mTopComponent != null
3302                        && app.processName.equals(mTopComponent.getPackageName())) {
3303                    uid = 0;
3304                }
3305                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3306                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3307                    uid = 0;
3308                }
3309            }
3310            int debugFlags = 0;
3311            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3312                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3313                // Also turn on CheckJNI for debuggable apps. It's quite
3314                // awkward to turn on otherwise.
3315                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3316            }
3317            // Run the app in safe mode if its manifest requests so or the
3318            // system is booted in safe mode.
3319            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3320                mSafeMode == true) {
3321                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3322            }
3323            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3324                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3325            }
3326            String jitDebugProperty = SystemProperties.get("debug.usejit");
3327            if ("true".equals(jitDebugProperty)) {
3328                debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3329            } else if (!"false".equals(jitDebugProperty)) {
3330                // If we didn't force disable by setting false, defer to the dalvik vm options.
3331                if ("true".equals(SystemProperties.get("dalvik.vm.usejit"))) {
3332                    debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3333                }
3334            }
3335            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3336            if ("true".equals(genDebugInfoProperty)) {
3337                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3338            }
3339            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3340                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3341            }
3342            if ("1".equals(SystemProperties.get("debug.assert"))) {
3343                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3344            }
3345
3346            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3347            if (requiredAbi == null) {
3348                requiredAbi = Build.SUPPORTED_ABIS[0];
3349            }
3350
3351            String instructionSet = null;
3352            if (app.info.primaryCpuAbi != null) {
3353                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3354            }
3355
3356            app.gids = gids;
3357            app.requiredAbi = requiredAbi;
3358            app.instructionSet = instructionSet;
3359
3360            // Start the process.  It will either succeed and return a result containing
3361            // the PID of the new process, or else throw a RuntimeException.
3362            boolean isActivityProcess = (entryPoint == null);
3363            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3364            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3365                    app.processName);
3366            checkTime(startTime, "startProcess: asking zygote to start proc");
3367            Process.ProcessStartResult startResult = Process.start(entryPoint,
3368                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3369                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3370                    app.info.dataDir, entryPointArgs);
3371            checkTime(startTime, "startProcess: returned from zygote!");
3372            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3373
3374            if (app.isolated) {
3375                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3376            }
3377            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3378            checkTime(startTime, "startProcess: done updating battery stats");
3379
3380            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3381                    UserHandle.getUserId(uid), startResult.pid, uid,
3382                    app.processName, hostingType,
3383                    hostingNameStr != null ? hostingNameStr : "");
3384
3385            if (app.persistent) {
3386                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3387            }
3388
3389            checkTime(startTime, "startProcess: building log message");
3390            StringBuilder buf = mStringBuilder;
3391            buf.setLength(0);
3392            buf.append("Start proc ");
3393            buf.append(startResult.pid);
3394            buf.append(':');
3395            buf.append(app.processName);
3396            buf.append('/');
3397            UserHandle.formatUid(buf, uid);
3398            if (!isActivityProcess) {
3399                buf.append(" [");
3400                buf.append(entryPoint);
3401                buf.append("]");
3402            }
3403            buf.append(" for ");
3404            buf.append(hostingType);
3405            if (hostingNameStr != null) {
3406                buf.append(" ");
3407                buf.append(hostingNameStr);
3408            }
3409            Slog.i(TAG, buf.toString());
3410            app.setPid(startResult.pid);
3411            app.usingWrapper = startResult.usingWrapper;
3412            app.removed = false;
3413            app.killed = false;
3414            app.killedByAm = false;
3415            checkTime(startTime, "startProcess: starting to update pids map");
3416            synchronized (mPidsSelfLocked) {
3417                this.mPidsSelfLocked.put(startResult.pid, app);
3418                if (isActivityProcess) {
3419                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3420                    msg.obj = app;
3421                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3422                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3423                }
3424            }
3425            checkTime(startTime, "startProcess: done updating pids map");
3426        } catch (RuntimeException e) {
3427            // XXX do better error recovery.
3428            app.setPid(0);
3429            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3430            if (app.isolated) {
3431                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3432            }
3433            Slog.e(TAG, "Failure starting process " + app.processName, e);
3434        }
3435    }
3436
3437    void updateUsageStats(ActivityRecord component, boolean resumed) {
3438        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3439                "updateUsageStats: comp=" + component + "res=" + resumed);
3440        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3441        if (resumed) {
3442            if (mUsageStatsService != null) {
3443                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3444                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3445            }
3446            synchronized (stats) {
3447                stats.noteActivityResumedLocked(component.app.uid);
3448            }
3449        } else {
3450            if (mUsageStatsService != null) {
3451                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3452                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3453            }
3454            synchronized (stats) {
3455                stats.noteActivityPausedLocked(component.app.uid);
3456            }
3457        }
3458    }
3459
3460    Intent getHomeIntent() {
3461        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3462        intent.setComponent(mTopComponent);
3463        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3464            intent.addCategory(Intent.CATEGORY_HOME);
3465        }
3466        return intent;
3467    }
3468
3469    boolean startHomeActivityLocked(int userId, String reason) {
3470        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3471                && mTopAction == null) {
3472            // We are running in factory test mode, but unable to find
3473            // the factory test app, so just sit around displaying the
3474            // error message and don't try to start anything.
3475            return false;
3476        }
3477        Intent intent = getHomeIntent();
3478        ActivityInfo aInfo =
3479            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3480        if (aInfo != null) {
3481            intent.setComponent(new ComponentName(
3482                    aInfo.applicationInfo.packageName, aInfo.name));
3483            // Don't do this if the home app is currently being
3484            // instrumented.
3485            aInfo = new ActivityInfo(aInfo);
3486            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3487            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3488                    aInfo.applicationInfo.uid, true);
3489            if (app == null || app.instrumentationClass == null) {
3490                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3491                mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3492            }
3493        }
3494
3495        return true;
3496    }
3497
3498    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3499        ActivityInfo ai = null;
3500        ComponentName comp = intent.getComponent();
3501        try {
3502            if (comp != null) {
3503                // Factory test.
3504                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3505            } else {
3506                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3507                        intent,
3508                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3509                        flags, userId);
3510
3511                if (info != null) {
3512                    ai = info.activityInfo;
3513                }
3514            }
3515        } catch (RemoteException e) {
3516            // ignore
3517        }
3518
3519        return ai;
3520    }
3521
3522    /**
3523     * Starts the "new version setup screen" if appropriate.
3524     */
3525    void startSetupActivityLocked() {
3526        // Only do this once per boot.
3527        if (mCheckedForSetup) {
3528            return;
3529        }
3530
3531        // We will show this screen if the current one is a different
3532        // version than the last one shown, and we are not running in
3533        // low-level factory test mode.
3534        final ContentResolver resolver = mContext.getContentResolver();
3535        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3536                Settings.Global.getInt(resolver,
3537                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3538            mCheckedForSetup = true;
3539
3540            // See if we should be showing the platform update setup UI.
3541            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3542            List<ResolveInfo> ris = mContext.getPackageManager()
3543                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3544
3545            // We don't allow third party apps to replace this.
3546            ResolveInfo ri = null;
3547            for (int i=0; ris != null && i<ris.size(); i++) {
3548                if ((ris.get(i).activityInfo.applicationInfo.flags
3549                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3550                    ri = ris.get(i);
3551                    break;
3552                }
3553            }
3554
3555            if (ri != null) {
3556                String vers = ri.activityInfo.metaData != null
3557                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3558                        : null;
3559                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3560                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3561                            Intent.METADATA_SETUP_VERSION);
3562                }
3563                String lastVers = Settings.Secure.getString(
3564                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3565                if (vers != null && !vers.equals(lastVers)) {
3566                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3567                    intent.setComponent(new ComponentName(
3568                            ri.activityInfo.packageName, ri.activityInfo.name));
3569                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3570                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, false,
3571                            null, null, null);
3572                }
3573            }
3574        }
3575    }
3576
3577    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3578        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3579    }
3580
3581    void enforceNotIsolatedCaller(String caller) {
3582        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3583            throw new SecurityException("Isolated process not allowed to call " + caller);
3584        }
3585    }
3586
3587    void enforceShellRestriction(String restriction, int userHandle) {
3588        if (Binder.getCallingUid() == Process.SHELL_UID) {
3589            if (userHandle < 0
3590                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3591                throw new SecurityException("Shell does not have permission to access user "
3592                        + userHandle);
3593            }
3594        }
3595    }
3596
3597    @Override
3598    public int getFrontActivityScreenCompatMode() {
3599        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3600        synchronized (this) {
3601            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3602        }
3603    }
3604
3605    @Override
3606    public void setFrontActivityScreenCompatMode(int mode) {
3607        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3608                "setFrontActivityScreenCompatMode");
3609        synchronized (this) {
3610            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3611        }
3612    }
3613
3614    @Override
3615    public int getPackageScreenCompatMode(String packageName) {
3616        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3617        synchronized (this) {
3618            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3619        }
3620    }
3621
3622    @Override
3623    public void setPackageScreenCompatMode(String packageName, int mode) {
3624        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3625                "setPackageScreenCompatMode");
3626        synchronized (this) {
3627            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3628        }
3629    }
3630
3631    @Override
3632    public boolean getPackageAskScreenCompat(String packageName) {
3633        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3634        synchronized (this) {
3635            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3636        }
3637    }
3638
3639    @Override
3640    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3641        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3642                "setPackageAskScreenCompat");
3643        synchronized (this) {
3644            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3645        }
3646    }
3647
3648    private boolean hasUsageStatsPermission(String callingPackage) {
3649        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3650                Binder.getCallingUid(), callingPackage);
3651        if (mode == AppOpsManager.MODE_DEFAULT) {
3652            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3653                    == PackageManager.PERMISSION_GRANTED;
3654        }
3655        return mode == AppOpsManager.MODE_ALLOWED;
3656    }
3657
3658    @Override
3659    public int getPackageProcessState(String packageName, String callingPackage) {
3660        if (!hasUsageStatsPermission(callingPackage)) {
3661            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3662                    "getPackageProcessState");
3663        }
3664
3665        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3666        synchronized (this) {
3667            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3668                final ProcessRecord proc = mLruProcesses.get(i);
3669                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3670                        || procState > proc.setProcState) {
3671                    boolean found = false;
3672                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3673                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3674                            procState = proc.setProcState;
3675                            found = true;
3676                        }
3677                    }
3678                    if (proc.pkgDeps != null && !found) {
3679                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3680                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3681                                procState = proc.setProcState;
3682                                break;
3683                            }
3684                        }
3685                    }
3686                }
3687            }
3688        }
3689        return procState;
3690    }
3691
3692    @Override
3693    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3694        synchronized (this) {
3695            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3696            if (app == null) {
3697                return false;
3698            }
3699            if (app.trimMemoryLevel < level && app.thread != null &&
3700                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3701                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3702                try {
3703                    app.thread.scheduleTrimMemory(level);
3704                    app.trimMemoryLevel = level;
3705                    return true;
3706                } catch (RemoteException e) {
3707                    // Fallthrough to failure case.
3708                }
3709            }
3710        }
3711        return false;
3712    }
3713
3714    private void dispatchProcessesChanged() {
3715        int N;
3716        synchronized (this) {
3717            N = mPendingProcessChanges.size();
3718            if (mActiveProcessChanges.length < N) {
3719                mActiveProcessChanges = new ProcessChangeItem[N];
3720            }
3721            mPendingProcessChanges.toArray(mActiveProcessChanges);
3722            mPendingProcessChanges.clear();
3723            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3724                    "*** Delivering " + N + " process changes");
3725        }
3726
3727        int i = mProcessObservers.beginBroadcast();
3728        while (i > 0) {
3729            i--;
3730            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3731            if (observer != null) {
3732                try {
3733                    for (int j=0; j<N; j++) {
3734                        ProcessChangeItem item = mActiveProcessChanges[j];
3735                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3736                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3737                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3738                                    + item.uid + ": " + item.foregroundActivities);
3739                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3740                                    item.foregroundActivities);
3741                        }
3742                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3743                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3744                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3745                                    + ": " + item.processState);
3746                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3747                        }
3748                    }
3749                } catch (RemoteException e) {
3750                }
3751            }
3752        }
3753        mProcessObservers.finishBroadcast();
3754
3755        synchronized (this) {
3756            for (int j=0; j<N; j++) {
3757                mAvailProcessChanges.add(mActiveProcessChanges[j]);
3758            }
3759        }
3760    }
3761
3762    private void dispatchProcessDied(int pid, int uid) {
3763        int i = mProcessObservers.beginBroadcast();
3764        while (i > 0) {
3765            i--;
3766            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3767            if (observer != null) {
3768                try {
3769                    observer.onProcessDied(pid, uid);
3770                } catch (RemoteException e) {
3771                }
3772            }
3773        }
3774        mProcessObservers.finishBroadcast();
3775    }
3776
3777    private void dispatchUidsChanged() {
3778        int N;
3779        synchronized (this) {
3780            N = mPendingUidChanges.size();
3781            if (mActiveUidChanges.length < N) {
3782                mActiveUidChanges = new UidRecord.ChangeItem[N];
3783            }
3784            for (int i=0; i<N; i++) {
3785                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3786                mActiveUidChanges[i] = change;
3787                change.uidRecord.pendingChange = null;
3788                change.uidRecord = null;
3789            }
3790            mPendingUidChanges.clear();
3791            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3792                    "*** Delivering " + N + " uid changes");
3793        }
3794
3795        if (mLocalPowerManager != null) {
3796            for (int j=0; j<N; j++) {
3797                UidRecord.ChangeItem item = mActiveUidChanges[j];
3798                if (item.gone) {
3799                    mLocalPowerManager.uidGone(item.uid);
3800                } else {
3801                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
3802                }
3803            }
3804        }
3805
3806        int i = mUidObservers.beginBroadcast();
3807        while (i > 0) {
3808            i--;
3809            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
3810            if (observer != null) {
3811                try {
3812                    for (int j=0; j<N; j++) {
3813                        UidRecord.ChangeItem item = mActiveUidChanges[j];
3814                        if (item.gone) {
3815                            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3816                                    "UID gone uid=" + item.uid);
3817                            observer.onUidGone(item.uid);
3818                        } else {
3819                            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3820                                    "UID CHANGED uid=" + item.uid
3821                                    + ": " + item.processState);
3822                            observer.onUidStateChanged(item.uid, item.processState);
3823                        }
3824                    }
3825                } catch (RemoteException e) {
3826                }
3827            }
3828        }
3829        mUidObservers.finishBroadcast();
3830
3831        synchronized (this) {
3832            for (int j=0; j<N; j++) {
3833                mAvailUidChanges.add(mActiveUidChanges[j]);
3834            }
3835        }
3836    }
3837
3838    @Override
3839    public final int startActivity(IApplicationThread caller, String callingPackage,
3840            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3841            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3842        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3843            resultWho, requestCode, startFlags, profilerInfo, options,
3844            UserHandle.getCallingUserId());
3845    }
3846
3847    @Override
3848    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3849            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3850            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3851        enforceNotIsolatedCaller("startActivity");
3852        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3853                false, ALLOW_FULL_ONLY, "startActivity", null);
3854        // TODO: Switch to user app stacks here.
3855        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3856                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3857                profilerInfo, null, null, options, false, userId, null, null);
3858    }
3859
3860    @Override
3861    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3862            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3863            int startFlags, ProfilerInfo profilerInfo, Bundle options, boolean ignoreTargetSecurity,
3864            int userId) {
3865
3866        // This is very dangerous -- it allows you to perform a start activity (including
3867        // permission grants) as any app that may launch one of your own activities.  So
3868        // we will only allow this to be done from activities that are part of the core framework,
3869        // and then only when they are running as the system.
3870        final ActivityRecord sourceRecord;
3871        final int targetUid;
3872        final String targetPackage;
3873        synchronized (this) {
3874            if (resultTo == null) {
3875                throw new SecurityException("Must be called from an activity");
3876            }
3877            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3878            if (sourceRecord == null) {
3879                throw new SecurityException("Called with bad activity token: " + resultTo);
3880            }
3881            if (!sourceRecord.info.packageName.equals("android")) {
3882                throw new SecurityException(
3883                        "Must be called from an activity that is declared in the android package");
3884            }
3885            if (sourceRecord.app == null) {
3886                throw new SecurityException("Called without a process attached to activity");
3887            }
3888            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3889                // This is still okay, as long as this activity is running under the
3890                // uid of the original calling activity.
3891                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3892                    throw new SecurityException(
3893                            "Calling activity in uid " + sourceRecord.app.uid
3894                                    + " must be system uid or original calling uid "
3895                                    + sourceRecord.launchedFromUid);
3896                }
3897            }
3898            if (ignoreTargetSecurity) {
3899                if (intent.getComponent() == null) {
3900                    throw new SecurityException(
3901                            "Component must be specified with ignoreTargetSecurity");
3902                }
3903                if (intent.getSelector() != null) {
3904                    throw new SecurityException(
3905                            "Selector not allowed with ignoreTargetSecurity");
3906                }
3907            }
3908            targetUid = sourceRecord.launchedFromUid;
3909            targetPackage = sourceRecord.launchedFromPackage;
3910        }
3911
3912        if (userId == UserHandle.USER_NULL) {
3913            userId = UserHandle.getUserId(sourceRecord.app.uid);
3914        }
3915
3916        // TODO: Switch to user app stacks here.
3917        try {
3918            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3919                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3920                    null, null, options, ignoreTargetSecurity, userId, null, null);
3921            return ret;
3922        } catch (SecurityException e) {
3923            // XXX need to figure out how to propagate to original app.
3924            // A SecurityException here is generally actually a fault of the original
3925            // calling activity (such as a fairly granting permissions), so propagate it
3926            // back to them.
3927            /*
3928            StringBuilder msg = new StringBuilder();
3929            msg.append("While launching");
3930            msg.append(intent.toString());
3931            msg.append(": ");
3932            msg.append(e.getMessage());
3933            */
3934            throw e;
3935        }
3936    }
3937
3938    @Override
3939    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3940            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3941            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3942        enforceNotIsolatedCaller("startActivityAndWait");
3943        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3944                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3945        WaitResult res = new WaitResult();
3946        // TODO: Switch to user app stacks here.
3947        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3948                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3949                options, false, userId, null, null);
3950        return res;
3951    }
3952
3953    @Override
3954    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3955            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3956            int startFlags, Configuration config, Bundle options, int userId) {
3957        enforceNotIsolatedCaller("startActivityWithConfig");
3958        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3959                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3960        // TODO: Switch to user app stacks here.
3961        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3962                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3963                null, null, config, options, false, userId, null, null);
3964        return ret;
3965    }
3966
3967    @Override
3968    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
3969            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
3970            int requestCode, int flagsMask, int flagsValues, Bundle options)
3971            throws TransactionTooLargeException {
3972        enforceNotIsolatedCaller("startActivityIntentSender");
3973        // Refuse possible leaked file descriptors
3974        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3975            throw new IllegalArgumentException("File descriptors passed in Intent");
3976        }
3977
3978        IIntentSender sender = intent.getTarget();
3979        if (!(sender instanceof PendingIntentRecord)) {
3980            throw new IllegalArgumentException("Bad PendingIntent object");
3981        }
3982
3983        PendingIntentRecord pir = (PendingIntentRecord)sender;
3984
3985        synchronized (this) {
3986            // If this is coming from the currently resumed activity, it is
3987            // effectively saying that app switches are allowed at this point.
3988            final ActivityStack stack = getFocusedStack();
3989            if (stack.mResumedActivity != null &&
3990                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3991                mAppSwitchesAllowedTime = 0;
3992            }
3993        }
3994        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3995                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3996        return ret;
3997    }
3998
3999    @Override
4000    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4001            Intent intent, String resolvedType, IVoiceInteractionSession session,
4002            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4003            Bundle options, int userId) {
4004        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4005                != PackageManager.PERMISSION_GRANTED) {
4006            String msg = "Permission Denial: startVoiceActivity() from pid="
4007                    + Binder.getCallingPid()
4008                    + ", uid=" + Binder.getCallingUid()
4009                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4010            Slog.w(TAG, msg);
4011            throw new SecurityException(msg);
4012        }
4013        if (session == null || interactor == null) {
4014            throw new NullPointerException("null session or interactor");
4015        }
4016        userId = handleIncomingUser(callingPid, callingUid, userId,
4017                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
4018        // TODO: Switch to user app stacks here.
4019        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
4020                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4021                null, options, false, userId, null, null);
4022    }
4023
4024    @Override
4025    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4026        synchronized (this) {
4027            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4028                if (keepAwake) {
4029                    mVoiceWakeLock.acquire();
4030                } else {
4031                    mVoiceWakeLock.release();
4032                }
4033            }
4034        }
4035    }
4036
4037    @Override
4038    public boolean startNextMatchingActivity(IBinder callingActivity,
4039            Intent intent, Bundle options) {
4040        // Refuse possible leaked file descriptors
4041        if (intent != null && intent.hasFileDescriptors() == true) {
4042            throw new IllegalArgumentException("File descriptors passed in Intent");
4043        }
4044
4045        synchronized (this) {
4046            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4047            if (r == null) {
4048                ActivityOptions.abort(options);
4049                return false;
4050            }
4051            if (r.app == null || r.app.thread == null) {
4052                // The caller is not running...  d'oh!
4053                ActivityOptions.abort(options);
4054                return false;
4055            }
4056            intent = new Intent(intent);
4057            // The caller is not allowed to change the data.
4058            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4059            // And we are resetting to find the next component...
4060            intent.setComponent(null);
4061
4062            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4063
4064            ActivityInfo aInfo = null;
4065            try {
4066                List<ResolveInfo> resolves =
4067                    AppGlobals.getPackageManager().queryIntentActivities(
4068                            intent, r.resolvedType,
4069                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4070                            UserHandle.getCallingUserId());
4071
4072                // Look for the original activity in the list...
4073                final int N = resolves != null ? resolves.size() : 0;
4074                for (int i=0; i<N; i++) {
4075                    ResolveInfo rInfo = resolves.get(i);
4076                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4077                            && rInfo.activityInfo.name.equals(r.info.name)) {
4078                        // We found the current one...  the next matching is
4079                        // after it.
4080                        i++;
4081                        if (i<N) {
4082                            aInfo = resolves.get(i).activityInfo;
4083                        }
4084                        if (debug) {
4085                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4086                                    + "/" + r.info.name);
4087                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
4088                                    + "/" + aInfo.name);
4089                        }
4090                        break;
4091                    }
4092                }
4093            } catch (RemoteException e) {
4094            }
4095
4096            if (aInfo == null) {
4097                // Nobody who is next!
4098                ActivityOptions.abort(options);
4099                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4100                return false;
4101            }
4102
4103            intent.setComponent(new ComponentName(
4104                    aInfo.applicationInfo.packageName, aInfo.name));
4105            intent.setFlags(intent.getFlags()&~(
4106                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4107                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4108                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4109                    Intent.FLAG_ACTIVITY_NEW_TASK));
4110
4111            // Okay now we need to start the new activity, replacing the
4112            // currently running activity.  This is a little tricky because
4113            // we want to start the new one as if the current one is finished,
4114            // but not finish the current one first so that there is no flicker.
4115            // And thus...
4116            final boolean wasFinishing = r.finishing;
4117            r.finishing = true;
4118
4119            // Propagate reply information over to the new activity.
4120            final ActivityRecord resultTo = r.resultTo;
4121            final String resultWho = r.resultWho;
4122            final int requestCode = r.requestCode;
4123            r.resultTo = null;
4124            if (resultTo != null) {
4125                resultTo.removeResultsLocked(r, resultWho, requestCode);
4126            }
4127
4128            final long origId = Binder.clearCallingIdentity();
4129            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
4130                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
4131                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
4132                    -1, r.launchedFromUid, 0, options, false, false, null, null, null);
4133            Binder.restoreCallingIdentity(origId);
4134
4135            r.finishing = wasFinishing;
4136            if (res != ActivityManager.START_SUCCESS) {
4137                return false;
4138            }
4139            return true;
4140        }
4141    }
4142
4143    @Override
4144    public final int startActivityFromRecents(int taskId, Bundle options) {
4145        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4146            String msg = "Permission Denial: startActivityFromRecents called without " +
4147                    START_TASKS_FROM_RECENTS;
4148            Slog.w(TAG, msg);
4149            throw new SecurityException(msg);
4150        }
4151        return startActivityFromRecentsInner(taskId, options);
4152    }
4153
4154    final int startActivityFromRecentsInner(int taskId, Bundle options) {
4155        final TaskRecord task;
4156        final int callingUid;
4157        final String callingPackage;
4158        final Intent intent;
4159        final int userId;
4160        synchronized (this) {
4161            task = mStackSupervisor.anyTaskForIdLocked(taskId);
4162            if (task == null) {
4163                throw new IllegalArgumentException("Task " + taskId + " not found.");
4164            }
4165            if (task.getRootActivity() != null) {
4166                moveTaskToFrontLocked(task.taskId, 0, null);
4167                return ActivityManager.START_TASK_TO_FRONT;
4168            }
4169            callingUid = task.mCallingUid;
4170            callingPackage = task.mCallingPackage;
4171            intent = task.intent;
4172            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4173            userId = task.userId;
4174        }
4175        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4176                options, userId, null, task);
4177    }
4178
4179    final int startActivityInPackage(int uid, String callingPackage,
4180            Intent intent, String resolvedType, IBinder resultTo,
4181            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
4182            IActivityContainer container, TaskRecord inTask) {
4183
4184        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4185                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4186
4187        // TODO: Switch to user app stacks here.
4188        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
4189                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4190                null, null, null, options, false, userId, container, inTask);
4191        return ret;
4192    }
4193
4194    @Override
4195    public final int startActivities(IApplicationThread caller, String callingPackage,
4196            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
4197            int userId) {
4198        enforceNotIsolatedCaller("startActivities");
4199        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4200                false, ALLOW_FULL_ONLY, "startActivity", null);
4201        // TODO: Switch to user app stacks here.
4202        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
4203                resolvedTypes, resultTo, options, userId);
4204        return ret;
4205    }
4206
4207    final int startActivitiesInPackage(int uid, String callingPackage,
4208            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4209            Bundle options, int userId) {
4210
4211        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4212                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4213        // TODO: Switch to user app stacks here.
4214        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4215                resultTo, options, userId);
4216        return ret;
4217    }
4218
4219    @Override
4220    public void reportActivityFullyDrawn(IBinder token) {
4221        synchronized (this) {
4222            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4223            if (r == null) {
4224                return;
4225            }
4226            r.reportFullyDrawnLocked();
4227        }
4228    }
4229
4230    @Override
4231    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4232        synchronized (this) {
4233            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4234            if (r == null) {
4235                return;
4236            }
4237            if (r.task != null && r.task.mResizeable) {
4238                // Fixed screen orientation isn't supported with resizeable activities.
4239                return;
4240            }
4241            final long origId = Binder.clearCallingIdentity();
4242            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4243            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4244                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4245            if (config != null) {
4246                r.frozenBeforeDestroy = true;
4247                if (!updateConfigurationLocked(config, r, false, false)) {
4248                    mStackSupervisor.resumeTopActivitiesLocked();
4249                }
4250            }
4251            Binder.restoreCallingIdentity(origId);
4252        }
4253    }
4254
4255    @Override
4256    public int getRequestedOrientation(IBinder token) {
4257        synchronized (this) {
4258            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4259            if (r == null) {
4260                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4261            }
4262            return mWindowManager.getAppOrientation(r.appToken);
4263        }
4264    }
4265
4266    /**
4267     * This is the internal entry point for handling Activity.finish().
4268     *
4269     * @param token The Binder token referencing the Activity we want to finish.
4270     * @param resultCode Result code, if any, from this Activity.
4271     * @param resultData Result data (Intent), if any, from this Activity.
4272     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4273     *            the root Activity in the task.
4274     *
4275     * @return Returns true if the activity successfully finished, or false if it is still running.
4276     */
4277    @Override
4278    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4279            boolean finishTask) {
4280        // Refuse possible leaked file descriptors
4281        if (resultData != null && resultData.hasFileDescriptors() == true) {
4282            throw new IllegalArgumentException("File descriptors passed in Intent");
4283        }
4284
4285        synchronized(this) {
4286            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4287            if (r == null) {
4288                return true;
4289            }
4290            // Keep track of the root activity of the task before we finish it
4291            TaskRecord tr = r.task;
4292            ActivityRecord rootR = tr.getRootActivity();
4293            if (rootR == null) {
4294                Slog.w(TAG, "Finishing task with all activities already finished");
4295            }
4296            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4297            // finish.
4298            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4299                    mStackSupervisor.isLastLockedTask(tr)) {
4300                Slog.i(TAG, "Not finishing task in lock task mode");
4301                mStackSupervisor.showLockTaskToast();
4302                return false;
4303            }
4304            if (mController != null) {
4305                // Find the first activity that is not finishing.
4306                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4307                if (next != null) {
4308                    // ask watcher if this is allowed
4309                    boolean resumeOK = true;
4310                    try {
4311                        resumeOK = mController.activityResuming(next.packageName);
4312                    } catch (RemoteException e) {
4313                        mController = null;
4314                        Watchdog.getInstance().setActivityController(null);
4315                    }
4316
4317                    if (!resumeOK) {
4318                        Slog.i(TAG, "Not finishing activity because controller resumed");
4319                        return false;
4320                    }
4321                }
4322            }
4323            final long origId = Binder.clearCallingIdentity();
4324            try {
4325                boolean res;
4326                if (finishTask && r == rootR) {
4327                    // If requested, remove the task that is associated to this activity only if it
4328                    // was the root activity in the task. The result code and data is ignored
4329                    // because we don't support returning them across task boundaries.
4330                    res = removeTaskByIdLocked(tr.taskId, false);
4331                    if (!res) {
4332                        Slog.i(TAG, "Removing task failed to finish activity");
4333                    }
4334                } else {
4335                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4336                            resultData, "app-request", true);
4337                    if (!res) {
4338                        Slog.i(TAG, "Failed to finish by app-request");
4339                    }
4340                }
4341                return res;
4342            } finally {
4343                Binder.restoreCallingIdentity(origId);
4344            }
4345        }
4346    }
4347
4348    @Override
4349    public final void finishHeavyWeightApp() {
4350        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4351                != PackageManager.PERMISSION_GRANTED) {
4352            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4353                    + Binder.getCallingPid()
4354                    + ", uid=" + Binder.getCallingUid()
4355                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4356            Slog.w(TAG, msg);
4357            throw new SecurityException(msg);
4358        }
4359
4360        synchronized(this) {
4361            if (mHeavyWeightProcess == null) {
4362                return;
4363            }
4364
4365            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4366            for (int i = 0; i < activities.size(); i++) {
4367                ActivityRecord r = activities.get(i);
4368                if (!r.finishing && r.isInStackLocked()) {
4369                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4370                            null, "finish-heavy", true);
4371                }
4372            }
4373
4374            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4375                    mHeavyWeightProcess.userId, 0));
4376            mHeavyWeightProcess = null;
4377        }
4378    }
4379
4380    @Override
4381    public void crashApplication(int uid, int initialPid, String packageName,
4382            String message) {
4383        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4384                != PackageManager.PERMISSION_GRANTED) {
4385            String msg = "Permission Denial: crashApplication() from pid="
4386                    + Binder.getCallingPid()
4387                    + ", uid=" + Binder.getCallingUid()
4388                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4389            Slog.w(TAG, msg);
4390            throw new SecurityException(msg);
4391        }
4392
4393        synchronized(this) {
4394            ProcessRecord proc = null;
4395
4396            // Figure out which process to kill.  We don't trust that initialPid
4397            // still has any relation to current pids, so must scan through the
4398            // list.
4399            synchronized (mPidsSelfLocked) {
4400                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4401                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4402                    if (p.uid != uid) {
4403                        continue;
4404                    }
4405                    if (p.pid == initialPid) {
4406                        proc = p;
4407                        break;
4408                    }
4409                    if (p.pkgList.containsKey(packageName)) {
4410                        proc = p;
4411                    }
4412                }
4413            }
4414
4415            if (proc == null) {
4416                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4417                        + " initialPid=" + initialPid
4418                        + " packageName=" + packageName);
4419                return;
4420            }
4421
4422            if (proc.thread != null) {
4423                if (proc.pid == Process.myPid()) {
4424                    Log.w(TAG, "crashApplication: trying to crash self!");
4425                    return;
4426                }
4427                long ident = Binder.clearCallingIdentity();
4428                try {
4429                    proc.thread.scheduleCrash(message);
4430                } catch (RemoteException e) {
4431                }
4432                Binder.restoreCallingIdentity(ident);
4433            }
4434        }
4435    }
4436
4437    @Override
4438    public final void finishSubActivity(IBinder token, String resultWho,
4439            int requestCode) {
4440        synchronized(this) {
4441            final long origId = Binder.clearCallingIdentity();
4442            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4443            if (r != null) {
4444                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4445            }
4446            Binder.restoreCallingIdentity(origId);
4447        }
4448    }
4449
4450    @Override
4451    public boolean finishActivityAffinity(IBinder token) {
4452        synchronized(this) {
4453            final long origId = Binder.clearCallingIdentity();
4454            try {
4455                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4456                if (r == null) {
4457                    return false;
4458                }
4459
4460                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4461                // can finish.
4462                final TaskRecord task = r.task;
4463                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4464                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4465                    mStackSupervisor.showLockTaskToast();
4466                    return false;
4467                }
4468                return task.stack.finishActivityAffinityLocked(r);
4469            } finally {
4470                Binder.restoreCallingIdentity(origId);
4471            }
4472        }
4473    }
4474
4475    @Override
4476    public void finishVoiceTask(IVoiceInteractionSession session) {
4477        synchronized(this) {
4478            final long origId = Binder.clearCallingIdentity();
4479            try {
4480                mStackSupervisor.finishVoiceTask(session);
4481            } finally {
4482                Binder.restoreCallingIdentity(origId);
4483            }
4484        }
4485
4486    }
4487
4488    @Override
4489    public boolean releaseActivityInstance(IBinder token) {
4490        synchronized(this) {
4491            final long origId = Binder.clearCallingIdentity();
4492            try {
4493                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4494                if (r == null) {
4495                    return false;
4496                }
4497                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4498            } finally {
4499                Binder.restoreCallingIdentity(origId);
4500            }
4501        }
4502    }
4503
4504    @Override
4505    public void releaseSomeActivities(IApplicationThread appInt) {
4506        synchronized(this) {
4507            final long origId = Binder.clearCallingIdentity();
4508            try {
4509                ProcessRecord app = getRecordForAppLocked(appInt);
4510                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4511            } finally {
4512                Binder.restoreCallingIdentity(origId);
4513            }
4514        }
4515    }
4516
4517    @Override
4518    public boolean willActivityBeVisible(IBinder token) {
4519        synchronized(this) {
4520            ActivityStack stack = ActivityRecord.getStackLocked(token);
4521            if (stack != null) {
4522                return stack.willActivityBeVisibleLocked(token);
4523            }
4524            return false;
4525        }
4526    }
4527
4528    @Override
4529    public void overridePendingTransition(IBinder token, String packageName,
4530            int enterAnim, int exitAnim) {
4531        synchronized(this) {
4532            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4533            if (self == null) {
4534                return;
4535            }
4536
4537            final long origId = Binder.clearCallingIdentity();
4538
4539            if (self.state == ActivityState.RESUMED
4540                    || self.state == ActivityState.PAUSING) {
4541                mWindowManager.overridePendingAppTransition(packageName,
4542                        enterAnim, exitAnim, null);
4543            }
4544
4545            Binder.restoreCallingIdentity(origId);
4546        }
4547    }
4548
4549    /**
4550     * Main function for removing an existing process from the activity manager
4551     * as a result of that process going away.  Clears out all connections
4552     * to the process.
4553     */
4554    private final void handleAppDiedLocked(ProcessRecord app,
4555            boolean restarting, boolean allowRestart) {
4556        int pid = app.pid;
4557        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4558        if (!kept && !restarting) {
4559            removeLruProcessLocked(app);
4560            if (pid > 0) {
4561                ProcessList.remove(pid);
4562            }
4563        }
4564
4565        if (mProfileProc == app) {
4566            clearProfilerLocked();
4567        }
4568
4569        // Remove this application's activities from active lists.
4570        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4571
4572        app.activities.clear();
4573
4574        if (app.instrumentationClass != null) {
4575            Slog.w(TAG, "Crash of app " + app.processName
4576                  + " running instrumentation " + app.instrumentationClass);
4577            Bundle info = new Bundle();
4578            info.putString("shortMsg", "Process crashed.");
4579            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4580        }
4581
4582        if (!restarting && hasVisibleActivities && !mStackSupervisor.resumeTopActivitiesLocked()) {
4583            // If there was nothing to resume, and we are not already
4584            // restarting this process, but there is a visible activity that
4585            // is hosted by the process...  then make sure all visible
4586            // activities are running, taking care of restarting this
4587            // process.
4588            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4589        }
4590    }
4591
4592    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4593        IBinder threadBinder = thread.asBinder();
4594        // Find the application record.
4595        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4596            ProcessRecord rec = mLruProcesses.get(i);
4597            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4598                return i;
4599            }
4600        }
4601        return -1;
4602    }
4603
4604    final ProcessRecord getRecordForAppLocked(
4605            IApplicationThread thread) {
4606        if (thread == null) {
4607            return null;
4608        }
4609
4610        int appIndex = getLRURecordIndexForAppLocked(thread);
4611        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4612    }
4613
4614    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4615        // If there are no longer any background processes running,
4616        // and the app that died was not running instrumentation,
4617        // then tell everyone we are now low on memory.
4618        boolean haveBg = false;
4619        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4620            ProcessRecord rec = mLruProcesses.get(i);
4621            if (rec.thread != null
4622                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4623                haveBg = true;
4624                break;
4625            }
4626        }
4627
4628        if (!haveBg) {
4629            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4630            if (doReport) {
4631                long now = SystemClock.uptimeMillis();
4632                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4633                    doReport = false;
4634                } else {
4635                    mLastMemUsageReportTime = now;
4636                }
4637            }
4638            final ArrayList<ProcessMemInfo> memInfos
4639                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4640            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4641            long now = SystemClock.uptimeMillis();
4642            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4643                ProcessRecord rec = mLruProcesses.get(i);
4644                if (rec == dyingProc || rec.thread == null) {
4645                    continue;
4646                }
4647                if (doReport) {
4648                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4649                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4650                }
4651                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4652                    // The low memory report is overriding any current
4653                    // state for a GC request.  Make sure to do
4654                    // heavy/important/visible/foreground processes first.
4655                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4656                        rec.lastRequestedGc = 0;
4657                    } else {
4658                        rec.lastRequestedGc = rec.lastLowMemory;
4659                    }
4660                    rec.reportLowMemory = true;
4661                    rec.lastLowMemory = now;
4662                    mProcessesToGc.remove(rec);
4663                    addProcessToGcListLocked(rec);
4664                }
4665            }
4666            if (doReport) {
4667                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4668                mHandler.sendMessage(msg);
4669            }
4670            scheduleAppGcsLocked();
4671        }
4672    }
4673
4674    final void appDiedLocked(ProcessRecord app) {
4675       appDiedLocked(app, app.pid, app.thread, false);
4676    }
4677
4678    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4679            boolean fromBinderDied) {
4680        // First check if this ProcessRecord is actually active for the pid.
4681        synchronized (mPidsSelfLocked) {
4682            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4683            if (curProc != app) {
4684                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4685                return;
4686            }
4687        }
4688
4689        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4690        synchronized (stats) {
4691            stats.noteProcessDiedLocked(app.info.uid, pid);
4692        }
4693
4694        if (!app.killed) {
4695            if (!fromBinderDied) {
4696                Process.killProcessQuiet(pid);
4697            }
4698            killProcessGroup(app.info.uid, pid);
4699            app.killed = true;
4700        }
4701
4702        // Clean up already done if the process has been re-started.
4703        if (app.pid == pid && app.thread != null &&
4704                app.thread.asBinder() == thread.asBinder()) {
4705            boolean doLowMem = app.instrumentationClass == null;
4706            boolean doOomAdj = doLowMem;
4707            if (!app.killedByAm) {
4708                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4709                        + ") has died");
4710                mAllowLowerMemLevel = true;
4711            } else {
4712                // Note that we always want to do oom adj to update our state with the
4713                // new number of procs.
4714                mAllowLowerMemLevel = false;
4715                doLowMem = false;
4716            }
4717            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4718            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4719                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
4720            handleAppDiedLocked(app, false, true);
4721
4722            if (doOomAdj) {
4723                updateOomAdjLocked();
4724            }
4725            if (doLowMem) {
4726                doLowMemReportIfNeededLocked(app);
4727            }
4728        } else if (app.pid != pid) {
4729            // A new process has already been started.
4730            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4731                    + ") has died and restarted (pid " + app.pid + ").");
4732            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4733        } else if (DEBUG_PROCESSES) {
4734            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
4735                    + thread.asBinder());
4736        }
4737    }
4738
4739    /**
4740     * If a stack trace dump file is configured, dump process stack traces.
4741     * @param clearTraces causes the dump file to be erased prior to the new
4742     *    traces being written, if true; when false, the new traces will be
4743     *    appended to any existing file content.
4744     * @param firstPids of dalvik VM processes to dump stack traces for first
4745     * @param lastPids of dalvik VM processes to dump stack traces for last
4746     * @param nativeProcs optional list of native process names to dump stack crawls
4747     * @return file containing stack traces, or null if no dump file is configured
4748     */
4749    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4750            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4751        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4752        if (tracesPath == null || tracesPath.length() == 0) {
4753            return null;
4754        }
4755
4756        File tracesFile = new File(tracesPath);
4757        try {
4758            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4759            tracesFile.createNewFile();
4760            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4761        } catch (IOException e) {
4762            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4763            return null;
4764        }
4765
4766        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4767        return tracesFile;
4768    }
4769
4770    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4771            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4772        // Use a FileObserver to detect when traces finish writing.
4773        // The order of traces is considered important to maintain for legibility.
4774        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4775            @Override
4776            public synchronized void onEvent(int event, String path) { notify(); }
4777        };
4778
4779        try {
4780            observer.startWatching();
4781
4782            // First collect all of the stacks of the most important pids.
4783            if (firstPids != null) {
4784                try {
4785                    int num = firstPids.size();
4786                    for (int i = 0; i < num; i++) {
4787                        synchronized (observer) {
4788                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4789                            observer.wait(200);  // Wait for write-close, give up after 200msec
4790                        }
4791                    }
4792                } catch (InterruptedException e) {
4793                    Slog.wtf(TAG, e);
4794                }
4795            }
4796
4797            // Next collect the stacks of the native pids
4798            if (nativeProcs != null) {
4799                int[] pids = Process.getPidsForCommands(nativeProcs);
4800                if (pids != null) {
4801                    for (int pid : pids) {
4802                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4803                    }
4804                }
4805            }
4806
4807            // Lastly, measure CPU usage.
4808            if (processCpuTracker != null) {
4809                processCpuTracker.init();
4810                System.gc();
4811                processCpuTracker.update();
4812                try {
4813                    synchronized (processCpuTracker) {
4814                        processCpuTracker.wait(500); // measure over 1/2 second.
4815                    }
4816                } catch (InterruptedException e) {
4817                }
4818                processCpuTracker.update();
4819
4820                // We'll take the stack crawls of just the top apps using CPU.
4821                final int N = processCpuTracker.countWorkingStats();
4822                int numProcs = 0;
4823                for (int i=0; i<N && numProcs<5; i++) {
4824                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4825                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4826                        numProcs++;
4827                        try {
4828                            synchronized (observer) {
4829                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4830                                observer.wait(200);  // Wait for write-close, give up after 200msec
4831                            }
4832                        } catch (InterruptedException e) {
4833                            Slog.wtf(TAG, e);
4834                        }
4835
4836                    }
4837                }
4838            }
4839        } finally {
4840            observer.stopWatching();
4841        }
4842    }
4843
4844    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4845        if (true || IS_USER_BUILD) {
4846            return;
4847        }
4848        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4849        if (tracesPath == null || tracesPath.length() == 0) {
4850            return;
4851        }
4852
4853        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4854        StrictMode.allowThreadDiskWrites();
4855        try {
4856            final File tracesFile = new File(tracesPath);
4857            final File tracesDir = tracesFile.getParentFile();
4858            final File tracesTmp = new File(tracesDir, "__tmp__");
4859            try {
4860                if (tracesFile.exists()) {
4861                    tracesTmp.delete();
4862                    tracesFile.renameTo(tracesTmp);
4863                }
4864                StringBuilder sb = new StringBuilder();
4865                Time tobj = new Time();
4866                tobj.set(System.currentTimeMillis());
4867                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4868                sb.append(": ");
4869                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4870                sb.append(" since ");
4871                sb.append(msg);
4872                FileOutputStream fos = new FileOutputStream(tracesFile);
4873                fos.write(sb.toString().getBytes());
4874                if (app == null) {
4875                    fos.write("\n*** No application process!".getBytes());
4876                }
4877                fos.close();
4878                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4879            } catch (IOException e) {
4880                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4881                return;
4882            }
4883
4884            if (app != null) {
4885                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4886                firstPids.add(app.pid);
4887                dumpStackTraces(tracesPath, firstPids, null, null, null);
4888            }
4889
4890            File lastTracesFile = null;
4891            File curTracesFile = null;
4892            for (int i=9; i>=0; i--) {
4893                String name = String.format(Locale.US, "slow%02d.txt", i);
4894                curTracesFile = new File(tracesDir, name);
4895                if (curTracesFile.exists()) {
4896                    if (lastTracesFile != null) {
4897                        curTracesFile.renameTo(lastTracesFile);
4898                    } else {
4899                        curTracesFile.delete();
4900                    }
4901                }
4902                lastTracesFile = curTracesFile;
4903            }
4904            tracesFile.renameTo(curTracesFile);
4905            if (tracesTmp.exists()) {
4906                tracesTmp.renameTo(tracesFile);
4907            }
4908        } finally {
4909            StrictMode.setThreadPolicy(oldPolicy);
4910        }
4911    }
4912
4913    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4914            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4915        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4916        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4917
4918        if (mController != null) {
4919            try {
4920                // 0 == continue, -1 = kill process immediately
4921                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4922                if (res < 0 && app.pid != MY_PID) {
4923                    app.kill("anr", true);
4924                }
4925            } catch (RemoteException e) {
4926                mController = null;
4927                Watchdog.getInstance().setActivityController(null);
4928            }
4929        }
4930
4931        long anrTime = SystemClock.uptimeMillis();
4932        if (MONITOR_CPU_USAGE) {
4933            updateCpuStatsNow();
4934        }
4935
4936        synchronized (this) {
4937            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4938            if (mShuttingDown) {
4939                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4940                return;
4941            } else if (app.notResponding) {
4942                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4943                return;
4944            } else if (app.crashing) {
4945                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4946                return;
4947            }
4948
4949            // In case we come through here for the same app before completing
4950            // this one, mark as anring now so we will bail out.
4951            app.notResponding = true;
4952
4953            // Log the ANR to the event log.
4954            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4955                    app.processName, app.info.flags, annotation);
4956
4957            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4958            firstPids.add(app.pid);
4959
4960            int parentPid = app.pid;
4961            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4962            if (parentPid != app.pid) firstPids.add(parentPid);
4963
4964            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4965
4966            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4967                ProcessRecord r = mLruProcesses.get(i);
4968                if (r != null && r.thread != null) {
4969                    int pid = r.pid;
4970                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4971                        if (r.persistent) {
4972                            firstPids.add(pid);
4973                        } else {
4974                            lastPids.put(pid, Boolean.TRUE);
4975                        }
4976                    }
4977                }
4978            }
4979        }
4980
4981        // Log the ANR to the main log.
4982        StringBuilder info = new StringBuilder();
4983        info.setLength(0);
4984        info.append("ANR in ").append(app.processName);
4985        if (activity != null && activity.shortComponentName != null) {
4986            info.append(" (").append(activity.shortComponentName).append(")");
4987        }
4988        info.append("\n");
4989        info.append("PID: ").append(app.pid).append("\n");
4990        if (annotation != null) {
4991            info.append("Reason: ").append(annotation).append("\n");
4992        }
4993        if (parent != null && parent != activity) {
4994            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4995        }
4996
4997        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4998
4999        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5000                NATIVE_STACKS_OF_INTEREST);
5001
5002        String cpuInfo = null;
5003        if (MONITOR_CPU_USAGE) {
5004            updateCpuStatsNow();
5005            synchronized (mProcessCpuTracker) {
5006                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5007            }
5008            info.append(processCpuTracker.printCurrentLoad());
5009            info.append(cpuInfo);
5010        }
5011
5012        info.append(processCpuTracker.printCurrentState(anrTime));
5013
5014        Slog.e(TAG, info.toString());
5015        if (tracesFile == null) {
5016            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5017            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5018        }
5019
5020        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5021                cpuInfo, tracesFile, null);
5022
5023        if (mController != null) {
5024            try {
5025                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5026                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5027                if (res != 0) {
5028                    if (res < 0 && app.pid != MY_PID) {
5029                        app.kill("anr", true);
5030                    } else {
5031                        synchronized (this) {
5032                            mServices.scheduleServiceTimeoutLocked(app);
5033                        }
5034                    }
5035                    return;
5036                }
5037            } catch (RemoteException e) {
5038                mController = null;
5039                Watchdog.getInstance().setActivityController(null);
5040            }
5041        }
5042
5043        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5044        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5045                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5046
5047        synchronized (this) {
5048            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5049
5050            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5051                app.kill("bg anr", true);
5052                return;
5053            }
5054
5055            // Set the app's notResponding state, and look up the errorReportReceiver
5056            makeAppNotRespondingLocked(app,
5057                    activity != null ? activity.shortComponentName : null,
5058                    annotation != null ? "ANR " + annotation : "ANR",
5059                    info.toString());
5060
5061            // Bring up the infamous App Not Responding dialog
5062            Message msg = Message.obtain();
5063            HashMap<String, Object> map = new HashMap<String, Object>();
5064            msg.what = SHOW_NOT_RESPONDING_MSG;
5065            msg.obj = map;
5066            msg.arg1 = aboveSystem ? 1 : 0;
5067            map.put("app", app);
5068            if (activity != null) {
5069                map.put("activity", activity);
5070            }
5071
5072            mUiHandler.sendMessage(msg);
5073        }
5074    }
5075
5076    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5077        if (!mLaunchWarningShown) {
5078            mLaunchWarningShown = true;
5079            mUiHandler.post(new Runnable() {
5080                @Override
5081                public void run() {
5082                    synchronized (ActivityManagerService.this) {
5083                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5084                        d.show();
5085                        mUiHandler.postDelayed(new Runnable() {
5086                            @Override
5087                            public void run() {
5088                                synchronized (ActivityManagerService.this) {
5089                                    d.dismiss();
5090                                    mLaunchWarningShown = false;
5091                                }
5092                            }
5093                        }, 4000);
5094                    }
5095                }
5096            });
5097        }
5098    }
5099
5100    @Override
5101    public boolean clearApplicationUserData(final String packageName,
5102            final IPackageDataObserver observer, int userId) {
5103        enforceNotIsolatedCaller("clearApplicationUserData");
5104        if (packageName != null && packageName.equals(mDeviceOwnerName)) {
5105            throw new SecurityException("Clearing DeviceOwner data is forbidden.");
5106        }
5107        int uid = Binder.getCallingUid();
5108        int pid = Binder.getCallingPid();
5109        userId = handleIncomingUser(pid, uid,
5110                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5111        long callingId = Binder.clearCallingIdentity();
5112        try {
5113            IPackageManager pm = AppGlobals.getPackageManager();
5114            int pkgUid = -1;
5115            synchronized(this) {
5116                try {
5117                    pkgUid = pm.getPackageUid(packageName, userId);
5118                } catch (RemoteException e) {
5119                }
5120                if (pkgUid == -1) {
5121                    Slog.w(TAG, "Invalid packageName: " + packageName);
5122                    if (observer != null) {
5123                        try {
5124                            observer.onRemoveCompleted(packageName, false);
5125                        } catch (RemoteException e) {
5126                            Slog.i(TAG, "Observer no longer exists.");
5127                        }
5128                    }
5129                    return false;
5130                }
5131                if (uid == pkgUid || checkComponentPermission(
5132                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5133                        pid, uid, -1, true)
5134                        == PackageManager.PERMISSION_GRANTED) {
5135                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5136                } else {
5137                    throw new SecurityException("PID " + pid + " does not have permission "
5138                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5139                                    + " of package " + packageName);
5140                }
5141
5142                // Remove all tasks match the cleared application package and user
5143                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5144                    final TaskRecord tr = mRecentTasks.get(i);
5145                    final String taskPackageName =
5146                            tr.getBaseIntent().getComponent().getPackageName();
5147                    if (tr.userId != userId) continue;
5148                    if (!taskPackageName.equals(packageName)) continue;
5149                    removeTaskByIdLocked(tr.taskId, false);
5150                }
5151            }
5152
5153            try {
5154                // Clear application user data
5155                pm.clearApplicationUserData(packageName, observer, userId);
5156
5157                synchronized(this) {
5158                    // Remove all permissions granted from/to this package
5159                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5160                }
5161
5162                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5163                        Uri.fromParts("package", packageName, null));
5164                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5165                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5166                        null, null, 0, null, null, null, null, false, false, userId);
5167            } catch (RemoteException e) {
5168            }
5169        } finally {
5170            Binder.restoreCallingIdentity(callingId);
5171        }
5172        return true;
5173    }
5174
5175    @Override
5176    public void killBackgroundProcesses(final String packageName, int userId) {
5177        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5178                != PackageManager.PERMISSION_GRANTED &&
5179                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5180                        != PackageManager.PERMISSION_GRANTED) {
5181            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5182                    + Binder.getCallingPid()
5183                    + ", uid=" + Binder.getCallingUid()
5184                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5185            Slog.w(TAG, msg);
5186            throw new SecurityException(msg);
5187        }
5188
5189        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5190                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5191        long callingId = Binder.clearCallingIdentity();
5192        try {
5193            IPackageManager pm = AppGlobals.getPackageManager();
5194            synchronized(this) {
5195                int appId = -1;
5196                try {
5197                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5198                } catch (RemoteException e) {
5199                }
5200                if (appId == -1) {
5201                    Slog.w(TAG, "Invalid packageName: " + packageName);
5202                    return;
5203                }
5204                killPackageProcessesLocked(packageName, appId, userId,
5205                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5206            }
5207        } finally {
5208            Binder.restoreCallingIdentity(callingId);
5209        }
5210    }
5211
5212    @Override
5213    public void killAllBackgroundProcesses() {
5214        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5215                != PackageManager.PERMISSION_GRANTED) {
5216            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5217                    + Binder.getCallingPid()
5218                    + ", uid=" + Binder.getCallingUid()
5219                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5220            Slog.w(TAG, msg);
5221            throw new SecurityException(msg);
5222        }
5223
5224        long callingId = Binder.clearCallingIdentity();
5225        try {
5226            synchronized(this) {
5227                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5228                final int NP = mProcessNames.getMap().size();
5229                for (int ip=0; ip<NP; ip++) {
5230                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5231                    final int NA = apps.size();
5232                    for (int ia=0; ia<NA; ia++) {
5233                        ProcessRecord app = apps.valueAt(ia);
5234                        if (app.persistent) {
5235                            // we don't kill persistent processes
5236                            continue;
5237                        }
5238                        if (app.removed) {
5239                            procs.add(app);
5240                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5241                            app.removed = true;
5242                            procs.add(app);
5243                        }
5244                    }
5245                }
5246
5247                int N = procs.size();
5248                for (int i=0; i<N; i++) {
5249                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5250                }
5251                mAllowLowerMemLevel = true;
5252                updateOomAdjLocked();
5253                doLowMemReportIfNeededLocked(null);
5254            }
5255        } finally {
5256            Binder.restoreCallingIdentity(callingId);
5257        }
5258    }
5259
5260    @Override
5261    public void forceStopPackage(final String packageName, int userId) {
5262        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5263                != PackageManager.PERMISSION_GRANTED) {
5264            String msg = "Permission Denial: forceStopPackage() from pid="
5265                    + Binder.getCallingPid()
5266                    + ", uid=" + Binder.getCallingUid()
5267                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5268            Slog.w(TAG, msg);
5269            throw new SecurityException(msg);
5270        }
5271        final int callingPid = Binder.getCallingPid();
5272        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5273                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5274        long callingId = Binder.clearCallingIdentity();
5275        try {
5276            IPackageManager pm = AppGlobals.getPackageManager();
5277            synchronized(this) {
5278                int[] users = userId == UserHandle.USER_ALL
5279                        ? getUsersLocked() : new int[] { userId };
5280                for (int user : users) {
5281                    int pkgUid = -1;
5282                    try {
5283                        pkgUid = pm.getPackageUid(packageName, user);
5284                    } catch (RemoteException e) {
5285                    }
5286                    if (pkgUid == -1) {
5287                        Slog.w(TAG, "Invalid packageName: " + packageName);
5288                        continue;
5289                    }
5290                    try {
5291                        pm.setPackageStoppedState(packageName, true, user);
5292                    } catch (RemoteException e) {
5293                    } catch (IllegalArgumentException e) {
5294                        Slog.w(TAG, "Failed trying to unstop package "
5295                                + packageName + ": " + e);
5296                    }
5297                    if (isUserRunningLocked(user, false)) {
5298                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5299                    }
5300                }
5301            }
5302        } finally {
5303            Binder.restoreCallingIdentity(callingId);
5304        }
5305    }
5306
5307    @Override
5308    public void addPackageDependency(String packageName) {
5309        synchronized (this) {
5310            int callingPid = Binder.getCallingPid();
5311            if (callingPid == Process.myPid()) {
5312                //  Yeah, um, no.
5313                return;
5314            }
5315            ProcessRecord proc;
5316            synchronized (mPidsSelfLocked) {
5317                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5318            }
5319            if (proc != null) {
5320                if (proc.pkgDeps == null) {
5321                    proc.pkgDeps = new ArraySet<String>(1);
5322                }
5323                proc.pkgDeps.add(packageName);
5324            }
5325        }
5326    }
5327
5328    /*
5329     * The pkg name and app id have to be specified.
5330     */
5331    @Override
5332    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5333        if (pkg == null) {
5334            return;
5335        }
5336        // Make sure the uid is valid.
5337        if (appid < 0) {
5338            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5339            return;
5340        }
5341        int callerUid = Binder.getCallingUid();
5342        // Only the system server can kill an application
5343        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5344            // Post an aysnc message to kill the application
5345            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5346            msg.arg1 = appid;
5347            msg.arg2 = 0;
5348            Bundle bundle = new Bundle();
5349            bundle.putString("pkg", pkg);
5350            bundle.putString("reason", reason);
5351            msg.obj = bundle;
5352            mHandler.sendMessage(msg);
5353        } else {
5354            throw new SecurityException(callerUid + " cannot kill pkg: " +
5355                    pkg);
5356        }
5357    }
5358
5359    @Override
5360    public void closeSystemDialogs(String reason) {
5361        enforceNotIsolatedCaller("closeSystemDialogs");
5362
5363        final int pid = Binder.getCallingPid();
5364        final int uid = Binder.getCallingUid();
5365        final long origId = Binder.clearCallingIdentity();
5366        try {
5367            synchronized (this) {
5368                // Only allow this from foreground processes, so that background
5369                // applications can't abuse it to prevent system UI from being shown.
5370                if (uid >= Process.FIRST_APPLICATION_UID) {
5371                    ProcessRecord proc;
5372                    synchronized (mPidsSelfLocked) {
5373                        proc = mPidsSelfLocked.get(pid);
5374                    }
5375                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5376                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5377                                + " from background process " + proc);
5378                        return;
5379                    }
5380                }
5381                closeSystemDialogsLocked(reason);
5382            }
5383        } finally {
5384            Binder.restoreCallingIdentity(origId);
5385        }
5386    }
5387
5388    void closeSystemDialogsLocked(String reason) {
5389        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5390        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5391                | Intent.FLAG_RECEIVER_FOREGROUND);
5392        if (reason != null) {
5393            intent.putExtra("reason", reason);
5394        }
5395        mWindowManager.closeSystemDialogs(reason);
5396
5397        mStackSupervisor.closeSystemDialogsLocked();
5398
5399        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5400                AppOpsManager.OP_NONE, null, false, false,
5401                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5402    }
5403
5404    @Override
5405    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5406        enforceNotIsolatedCaller("getProcessMemoryInfo");
5407        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5408        for (int i=pids.length-1; i>=0; i--) {
5409            ProcessRecord proc;
5410            int oomAdj;
5411            synchronized (this) {
5412                synchronized (mPidsSelfLocked) {
5413                    proc = mPidsSelfLocked.get(pids[i]);
5414                    oomAdj = proc != null ? proc.setAdj : 0;
5415                }
5416            }
5417            infos[i] = new Debug.MemoryInfo();
5418            Debug.getMemoryInfo(pids[i], infos[i]);
5419            if (proc != null) {
5420                synchronized (this) {
5421                    if (proc.thread != null && proc.setAdj == oomAdj) {
5422                        // Record this for posterity if the process has been stable.
5423                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5424                                infos[i].getTotalUss(), false, proc.pkgList);
5425                    }
5426                }
5427            }
5428        }
5429        return infos;
5430    }
5431
5432    @Override
5433    public long[] getProcessPss(int[] pids) {
5434        enforceNotIsolatedCaller("getProcessPss");
5435        long[] pss = new long[pids.length];
5436        for (int i=pids.length-1; i>=0; i--) {
5437            ProcessRecord proc;
5438            int oomAdj;
5439            synchronized (this) {
5440                synchronized (mPidsSelfLocked) {
5441                    proc = mPidsSelfLocked.get(pids[i]);
5442                    oomAdj = proc != null ? proc.setAdj : 0;
5443                }
5444            }
5445            long[] tmpUss = new long[1];
5446            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5447            if (proc != null) {
5448                synchronized (this) {
5449                    if (proc.thread != null && proc.setAdj == oomAdj) {
5450                        // Record this for posterity if the process has been stable.
5451                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5452                    }
5453                }
5454            }
5455        }
5456        return pss;
5457    }
5458
5459    @Override
5460    public void killApplicationProcess(String processName, int uid) {
5461        if (processName == null) {
5462            return;
5463        }
5464
5465        int callerUid = Binder.getCallingUid();
5466        // Only the system server can kill an application
5467        if (callerUid == Process.SYSTEM_UID) {
5468            synchronized (this) {
5469                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5470                if (app != null && app.thread != null) {
5471                    try {
5472                        app.thread.scheduleSuicide();
5473                    } catch (RemoteException e) {
5474                        // If the other end already died, then our work here is done.
5475                    }
5476                } else {
5477                    Slog.w(TAG, "Process/uid not found attempting kill of "
5478                            + processName + " / " + uid);
5479                }
5480            }
5481        } else {
5482            throw new SecurityException(callerUid + " cannot kill app process: " +
5483                    processName);
5484        }
5485    }
5486
5487    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5488        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5489                false, true, false, false, UserHandle.getUserId(uid), reason);
5490        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5491                Uri.fromParts("package", packageName, null));
5492        if (!mProcessesReady) {
5493            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5494                    | Intent.FLAG_RECEIVER_FOREGROUND);
5495        }
5496        intent.putExtra(Intent.EXTRA_UID, uid);
5497        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5498        broadcastIntentLocked(null, null, intent,
5499                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5500                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5501    }
5502
5503    private void forceStopUserLocked(int userId, String reason) {
5504        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5505        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5506        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5507                | Intent.FLAG_RECEIVER_FOREGROUND);
5508        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5509        broadcastIntentLocked(null, null, intent,
5510                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5511                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5512    }
5513
5514    private final boolean killPackageProcessesLocked(String packageName, int appId,
5515            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5516            boolean doit, boolean evenPersistent, String reason) {
5517        ArrayList<ProcessRecord> procs = new ArrayList<>();
5518
5519        // Remove all processes this package may have touched: all with the
5520        // same UID (except for the system or root user), and all whose name
5521        // matches the package name.
5522        final int NP = mProcessNames.getMap().size();
5523        for (int ip=0; ip<NP; ip++) {
5524            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5525            final int NA = apps.size();
5526            for (int ia=0; ia<NA; ia++) {
5527                ProcessRecord app = apps.valueAt(ia);
5528                if (app.persistent && !evenPersistent) {
5529                    // we don't kill persistent processes
5530                    continue;
5531                }
5532                if (app.removed) {
5533                    if (doit) {
5534                        procs.add(app);
5535                    }
5536                    continue;
5537                }
5538
5539                // Skip process if it doesn't meet our oom adj requirement.
5540                if (app.setAdj < minOomAdj) {
5541                    continue;
5542                }
5543
5544                // If no package is specified, we call all processes under the
5545                // give user id.
5546                if (packageName == null) {
5547                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5548                        continue;
5549                    }
5550                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5551                        continue;
5552                    }
5553                // Package has been specified, we want to hit all processes
5554                // that match it.  We need to qualify this by the processes
5555                // that are running under the specified app and user ID.
5556                } else {
5557                    final boolean isDep = app.pkgDeps != null
5558                            && app.pkgDeps.contains(packageName);
5559                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5560                        continue;
5561                    }
5562                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5563                        continue;
5564                    }
5565                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5566                        continue;
5567                    }
5568                }
5569
5570                // Process has passed all conditions, kill it!
5571                if (!doit) {
5572                    return true;
5573                }
5574                app.removed = true;
5575                procs.add(app);
5576            }
5577        }
5578
5579        int N = procs.size();
5580        for (int i=0; i<N; i++) {
5581            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5582        }
5583        updateOomAdjLocked();
5584        return N > 0;
5585    }
5586
5587    private void cleanupDisabledPackageComponentsLocked(
5588            String packageName, int userId, String[] changedClasses) {
5589
5590        Set<String> disabledClasses = null;
5591        boolean packageDisabled = false;
5592        IPackageManager pm = AppGlobals.getPackageManager();
5593
5594        if (changedClasses == null) {
5595            // Nothing changed...
5596            return;
5597        }
5598
5599        // Determine enable/disable state of the package and its components.
5600        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5601        for (int i = changedClasses.length - 1; i >= 0; i--) {
5602            final String changedClass = changedClasses[i];
5603
5604            if (changedClass.equals(packageName)) {
5605                try {
5606                    // Entire package setting changed
5607                    enabled = pm.getApplicationEnabledSetting(packageName,
5608                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5609                } catch (Exception e) {
5610                    // No such package/component; probably racing with uninstall.  In any
5611                    // event it means we have nothing further to do here.
5612                    return;
5613                }
5614                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5615                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5616                if (packageDisabled) {
5617                    // Entire package is disabled.
5618                    // No need to continue to check component states.
5619                    disabledClasses = null;
5620                    break;
5621                }
5622            } else {
5623                try {
5624                    enabled = pm.getComponentEnabledSetting(
5625                            new ComponentName(packageName, changedClass),
5626                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5627                } catch (Exception e) {
5628                    // As above, probably racing with uninstall.
5629                    return;
5630                }
5631                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5632                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5633                    if (disabledClasses == null) {
5634                        disabledClasses = new ArraySet<>(changedClasses.length);
5635                    }
5636                    disabledClasses.add(changedClass);
5637                }
5638            }
5639        }
5640
5641        if (!packageDisabled && disabledClasses == null) {
5642            // Nothing to do here...
5643            return;
5644        }
5645
5646        // Clean-up disabled activities.
5647        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5648                packageName, disabledClasses, true, false, userId) && mBooted) {
5649            mStackSupervisor.resumeTopActivitiesLocked();
5650            mStackSupervisor.scheduleIdleLocked();
5651        }
5652
5653        // Clean-up disabled tasks
5654        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5655
5656        // Clean-up disabled services.
5657        mServices.bringDownDisabledPackageServicesLocked(
5658                packageName, disabledClasses, userId, false, true);
5659
5660        // Clean-up disabled providers.
5661        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5662        mProviderMap.collectPackageProvidersLocked(
5663                packageName, disabledClasses, true, false, userId, providers);
5664        for (int i = providers.size() - 1; i >= 0; i--) {
5665            removeDyingProviderLocked(null, providers.get(i), true);
5666        }
5667
5668        // Clean-up disabled broadcast receivers.
5669        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5670            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5671                    packageName, disabledClasses, userId, true);
5672        }
5673
5674    }
5675
5676    private final boolean forceStopPackageLocked(String packageName, int appId,
5677            boolean callerWillRestart, boolean purgeCache, boolean doit,
5678            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5679        int i;
5680
5681        if (userId == UserHandle.USER_ALL && packageName == null) {
5682            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5683        }
5684
5685        if (appId < 0 && packageName != null) {
5686            try {
5687                appId = UserHandle.getAppId(
5688                        AppGlobals.getPackageManager().getPackageUid(packageName, 0));
5689            } catch (RemoteException e) {
5690            }
5691        }
5692
5693        if (doit) {
5694            if (packageName != null) {
5695                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5696                        + " user=" + userId + ": " + reason);
5697            } else {
5698                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5699            }
5700
5701            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5702            for (int ip = pmap.size() - 1; ip >= 0; ip--) {
5703                SparseArray<Long> ba = pmap.valueAt(ip);
5704                for (i = ba.size() - 1; i >= 0; i--) {
5705                    boolean remove = false;
5706                    final int entUid = ba.keyAt(i);
5707                    if (packageName != null) {
5708                        if (userId == UserHandle.USER_ALL) {
5709                            if (UserHandle.getAppId(entUid) == appId) {
5710                                remove = true;
5711                            }
5712                        } else {
5713                            if (entUid == UserHandle.getUid(userId, appId)) {
5714                                remove = true;
5715                            }
5716                        }
5717                    } else if (UserHandle.getUserId(entUid) == userId) {
5718                        remove = true;
5719                    }
5720                    if (remove) {
5721                        ba.removeAt(i);
5722                    }
5723                }
5724                if (ba.size() == 0) {
5725                    pmap.removeAt(ip);
5726                }
5727            }
5728        }
5729
5730        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5731                -100, callerWillRestart, true, doit, evenPersistent,
5732                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5733
5734        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5735                packageName, null, doit, evenPersistent, userId)) {
5736            if (!doit) {
5737                return true;
5738            }
5739            didSomething = true;
5740        }
5741
5742        if (mServices.bringDownDisabledPackageServicesLocked(
5743                packageName, null, userId, evenPersistent, doit)) {
5744            if (!doit) {
5745                return true;
5746            }
5747            didSomething = true;
5748        }
5749
5750        if (packageName == null) {
5751            // Remove all sticky broadcasts from this user.
5752            mStickyBroadcasts.remove(userId);
5753        }
5754
5755        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5756        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5757                userId, providers)) {
5758            if (!doit) {
5759                return true;
5760            }
5761            didSomething = true;
5762        }
5763        for (i = providers.size() - 1; i >= 0; i--) {
5764            removeDyingProviderLocked(null, providers.get(i), true);
5765        }
5766
5767        // Remove transient permissions granted from/to this package/user
5768        removeUriPermissionsForPackageLocked(packageName, userId, false);
5769
5770        if (doit) {
5771            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
5772                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5773                        packageName, null, userId, doit);
5774            }
5775        }
5776
5777        if (packageName == null || uninstalling) {
5778            // Remove pending intents.  For now we only do this when force
5779            // stopping users, because we have some problems when doing this
5780            // for packages -- app widgets are not currently cleaned up for
5781            // such packages, so they can be left with bad pending intents.
5782            if (mIntentSenderRecords.size() > 0) {
5783                Iterator<WeakReference<PendingIntentRecord>> it
5784                        = mIntentSenderRecords.values().iterator();
5785                while (it.hasNext()) {
5786                    WeakReference<PendingIntentRecord> wpir = it.next();
5787                    if (wpir == null) {
5788                        it.remove();
5789                        continue;
5790                    }
5791                    PendingIntentRecord pir = wpir.get();
5792                    if (pir == null) {
5793                        it.remove();
5794                        continue;
5795                    }
5796                    if (packageName == null) {
5797                        // Stopping user, remove all objects for the user.
5798                        if (pir.key.userId != userId) {
5799                            // Not the same user, skip it.
5800                            continue;
5801                        }
5802                    } else {
5803                        if (UserHandle.getAppId(pir.uid) != appId) {
5804                            // Different app id, skip it.
5805                            continue;
5806                        }
5807                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5808                            // Different user, skip it.
5809                            continue;
5810                        }
5811                        if (!pir.key.packageName.equals(packageName)) {
5812                            // Different package, skip it.
5813                            continue;
5814                        }
5815                    }
5816                    if (!doit) {
5817                        return true;
5818                    }
5819                    didSomething = true;
5820                    it.remove();
5821                    pir.canceled = true;
5822                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5823                        pir.key.activity.pendingResults.remove(pir.ref);
5824                    }
5825                }
5826            }
5827        }
5828
5829        if (doit) {
5830            if (purgeCache && packageName != null) {
5831                AttributeCache ac = AttributeCache.instance();
5832                if (ac != null) {
5833                    ac.removePackage(packageName);
5834                }
5835            }
5836            if (mBooted) {
5837                mStackSupervisor.resumeTopActivitiesLocked();
5838                mStackSupervisor.scheduleIdleLocked();
5839            }
5840        }
5841
5842        return didSomething;
5843    }
5844
5845    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
5846        ProcessRecord old = mProcessNames.remove(name, uid);
5847        if (old != null) {
5848            old.uidRecord.numProcs--;
5849            if (old.uidRecord.numProcs == 0) {
5850                // No more processes using this uid, tell clients it is gone.
5851                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5852                        "No more processes in " + old.uidRecord);
5853                enqueueUidChangeLocked(old.uidRecord, true);
5854                mActiveUids.remove(uid);
5855            }
5856            old.uidRecord = null;
5857        }
5858        mIsolatedProcesses.remove(uid);
5859        return old;
5860    }
5861
5862    private final void addProcessNameLocked(ProcessRecord proc) {
5863        // We shouldn't already have a process under this name, but just in case we
5864        // need to clean up whatever may be there now.
5865        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
5866        if (old == proc && proc.persistent) {
5867            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
5868            Slog.w(TAG, "Re-adding persistent process " + proc);
5869        } else if (old != null) {
5870            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
5871        }
5872        UidRecord uidRec = mActiveUids.get(proc.uid);
5873        if (uidRec == null) {
5874            uidRec = new UidRecord(proc.uid);
5875            // This is the first appearance of the uid, report it now!
5876            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5877                    "Creating new process uid: " + uidRec);
5878            mActiveUids.put(proc.uid, uidRec);
5879            enqueueUidChangeLocked(uidRec, false);
5880        }
5881        proc.uidRecord = uidRec;
5882        uidRec.numProcs++;
5883        mProcessNames.put(proc.processName, proc.uid, proc);
5884        if (proc.isolated) {
5885            mIsolatedProcesses.put(proc.uid, proc);
5886        }
5887    }
5888
5889    private final boolean removeProcessLocked(ProcessRecord app,
5890            boolean callerWillRestart, boolean allowRestart, String reason) {
5891        final String name = app.processName;
5892        final int uid = app.uid;
5893        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
5894            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
5895
5896        removeProcessNameLocked(name, uid);
5897        if (mHeavyWeightProcess == app) {
5898            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5899                    mHeavyWeightProcess.userId, 0));
5900            mHeavyWeightProcess = null;
5901        }
5902        boolean needRestart = false;
5903        if (app.pid > 0 && app.pid != MY_PID) {
5904            int pid = app.pid;
5905            synchronized (mPidsSelfLocked) {
5906                mPidsSelfLocked.remove(pid);
5907                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5908            }
5909            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5910            if (app.isolated) {
5911                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5912            }
5913            boolean willRestart = false;
5914            if (app.persistent && !app.isolated) {
5915                if (!callerWillRestart) {
5916                    willRestart = true;
5917                } else {
5918                    needRestart = true;
5919                }
5920            }
5921            app.kill(reason, true);
5922            handleAppDiedLocked(app, willRestart, allowRestart);
5923            if (willRestart) {
5924                removeLruProcessLocked(app);
5925                addAppLocked(app.info, false, null /* ABI override */);
5926            }
5927        } else {
5928            mRemovedProcesses.add(app);
5929        }
5930
5931        return needRestart;
5932    }
5933
5934    private final void processStartTimedOutLocked(ProcessRecord app) {
5935        final int pid = app.pid;
5936        boolean gone = false;
5937        synchronized (mPidsSelfLocked) {
5938            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5939            if (knownApp != null && knownApp.thread == null) {
5940                mPidsSelfLocked.remove(pid);
5941                gone = true;
5942            }
5943        }
5944
5945        if (gone) {
5946            Slog.w(TAG, "Process " + app + " failed to attach");
5947            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5948                    pid, app.uid, app.processName);
5949            removeProcessNameLocked(app.processName, app.uid);
5950            if (mHeavyWeightProcess == app) {
5951                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5952                        mHeavyWeightProcess.userId, 0));
5953                mHeavyWeightProcess = null;
5954            }
5955            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5956            if (app.isolated) {
5957                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5958            }
5959            // Take care of any launching providers waiting for this process.
5960            checkAppInLaunchingProvidersLocked(app, true);
5961            // Take care of any services that are waiting for the process.
5962            mServices.processStartTimedOutLocked(app);
5963            app.kill("start timeout", true);
5964            removeLruProcessLocked(app);
5965            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5966                Slog.w(TAG, "Unattached app died before backup, skipping");
5967                try {
5968                    IBackupManager bm = IBackupManager.Stub.asInterface(
5969                            ServiceManager.getService(Context.BACKUP_SERVICE));
5970                    bm.agentDisconnected(app.info.packageName);
5971                } catch (RemoteException e) {
5972                    // Can't happen; the backup manager is local
5973                }
5974            }
5975            if (isPendingBroadcastProcessLocked(pid)) {
5976                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5977                skipPendingBroadcastLocked(pid);
5978            }
5979        } else {
5980            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5981        }
5982    }
5983
5984    private final boolean attachApplicationLocked(IApplicationThread thread,
5985            int pid) {
5986
5987        // Find the application record that is being attached...  either via
5988        // the pid if we are running in multiple processes, or just pull the
5989        // next app record if we are emulating process with anonymous threads.
5990        ProcessRecord app;
5991        if (pid != MY_PID && pid >= 0) {
5992            synchronized (mPidsSelfLocked) {
5993                app = mPidsSelfLocked.get(pid);
5994            }
5995        } else {
5996            app = null;
5997        }
5998
5999        if (app == null) {
6000            Slog.w(TAG, "No pending application record for pid " + pid
6001                    + " (IApplicationThread " + thread + "); dropping process");
6002            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6003            if (pid > 0 && pid != MY_PID) {
6004                Process.killProcessQuiet(pid);
6005                //TODO: killProcessGroup(app.info.uid, pid);
6006            } else {
6007                try {
6008                    thread.scheduleExit();
6009                } catch (Exception e) {
6010                    // Ignore exceptions.
6011                }
6012            }
6013            return false;
6014        }
6015
6016        // If this application record is still attached to a previous
6017        // process, clean it up now.
6018        if (app.thread != null) {
6019            handleAppDiedLocked(app, true, true);
6020        }
6021
6022        // Tell the process all about itself.
6023
6024        if (DEBUG_ALL) Slog.v(
6025                TAG, "Binding process pid " + pid + " to record " + app);
6026
6027        final String processName = app.processName;
6028        try {
6029            AppDeathRecipient adr = new AppDeathRecipient(
6030                    app, pid, thread);
6031            thread.asBinder().linkToDeath(adr, 0);
6032            app.deathRecipient = adr;
6033        } catch (RemoteException e) {
6034            app.resetPackageList(mProcessStats);
6035            startProcessLocked(app, "link fail", processName);
6036            return false;
6037        }
6038
6039        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6040
6041        app.makeActive(thread, mProcessStats);
6042        app.curAdj = app.setAdj = -100;
6043        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6044        app.forcingToForeground = null;
6045        updateProcessForegroundLocked(app, false, false);
6046        app.hasShownUi = false;
6047        app.debugging = false;
6048        app.cached = false;
6049        app.killedByAm = false;
6050
6051        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6052
6053        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6054        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6055
6056        if (!normalMode) {
6057            Slog.i(TAG, "Launching preboot mode app: " + app);
6058        }
6059
6060        if (DEBUG_ALL) Slog.v(
6061            TAG, "New app record " + app
6062            + " thread=" + thread.asBinder() + " pid=" + pid);
6063        try {
6064            int testMode = IApplicationThread.DEBUG_OFF;
6065            if (mDebugApp != null && mDebugApp.equals(processName)) {
6066                testMode = mWaitForDebugger
6067                    ? IApplicationThread.DEBUG_WAIT
6068                    : IApplicationThread.DEBUG_ON;
6069                app.debugging = true;
6070                if (mDebugTransient) {
6071                    mDebugApp = mOrigDebugApp;
6072                    mWaitForDebugger = mOrigWaitForDebugger;
6073                }
6074            }
6075            String profileFile = app.instrumentationProfileFile;
6076            ParcelFileDescriptor profileFd = null;
6077            int samplingInterval = 0;
6078            boolean profileAutoStop = false;
6079            if (mProfileApp != null && mProfileApp.equals(processName)) {
6080                mProfileProc = app;
6081                profileFile = mProfileFile;
6082                profileFd = mProfileFd;
6083                samplingInterval = mSamplingInterval;
6084                profileAutoStop = mAutoStopProfiler;
6085            }
6086            boolean enableOpenGlTrace = false;
6087            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6088                enableOpenGlTrace = true;
6089                mOpenGlTraceApp = null;
6090            }
6091            boolean enableTrackAllocation = false;
6092            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6093                enableTrackAllocation = true;
6094                mTrackAllocationApp = null;
6095            }
6096
6097            // If the app is being launched for restore or full backup, set it up specially
6098            boolean isRestrictedBackupMode = false;
6099            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6100                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6101                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6102                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6103            }
6104
6105            ensurePackageDexOpt(app.instrumentationInfo != null
6106                    ? app.instrumentationInfo.packageName
6107                    : app.info.packageName);
6108            if (app.instrumentationClass != null) {
6109                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6110            }
6111            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6112                    + processName + " with config " + mConfiguration);
6113            ApplicationInfo appInfo = app.instrumentationInfo != null
6114                    ? app.instrumentationInfo : app.info;
6115            app.compat = compatibilityInfoForPackageLocked(appInfo);
6116            if (profileFd != null) {
6117                profileFd = profileFd.dup();
6118            }
6119            ProfilerInfo profilerInfo = profileFile == null ? null
6120                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6121            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6122                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6123                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6124                    enableTrackAllocation, isRestrictedBackupMode || !normalMode, app.persistent,
6125                    new Configuration(mConfiguration), app.compat,
6126                    getCommonServicesLocked(app.isolated),
6127                    mCoreSettingsObserver.getCoreSettingsLocked());
6128            updateLruProcessLocked(app, false, null);
6129            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6130        } catch (Exception e) {
6131            // todo: Yikes!  What should we do?  For now we will try to
6132            // start another process, but that could easily get us in
6133            // an infinite loop of restarting processes...
6134            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6135
6136            app.resetPackageList(mProcessStats);
6137            app.unlinkDeathRecipient();
6138            startProcessLocked(app, "bind fail", processName);
6139            return false;
6140        }
6141
6142        // Remove this record from the list of starting applications.
6143        mPersistentStartingProcesses.remove(app);
6144        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6145                "Attach application locked removing on hold: " + app);
6146        mProcessesOnHold.remove(app);
6147
6148        boolean badApp = false;
6149        boolean didSomething = false;
6150
6151        // See if the top visible activity is waiting to run in this process...
6152        if (normalMode) {
6153            try {
6154                if (mStackSupervisor.attachApplicationLocked(app)) {
6155                    didSomething = true;
6156                }
6157            } catch (Exception e) {
6158                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6159                badApp = true;
6160            }
6161        }
6162
6163        // Find any services that should be running in this process...
6164        if (!badApp) {
6165            try {
6166                didSomething |= mServices.attachApplicationLocked(app, processName);
6167            } catch (Exception e) {
6168                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6169                badApp = true;
6170            }
6171        }
6172
6173        // Check if a next-broadcast receiver is in this process...
6174        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6175            try {
6176                didSomething |= sendPendingBroadcastsLocked(app);
6177            } catch (Exception e) {
6178                // If the app died trying to launch the receiver we declare it 'bad'
6179                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6180                badApp = true;
6181            }
6182        }
6183
6184        // Check whether the next backup agent is in this process...
6185        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6186            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6187                    "New app is backup target, launching agent for " + app);
6188            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6189            try {
6190                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6191                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6192                        mBackupTarget.backupMode);
6193            } catch (Exception e) {
6194                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6195                badApp = true;
6196            }
6197        }
6198
6199        if (badApp) {
6200            app.kill("error during init", true);
6201            handleAppDiedLocked(app, false, true);
6202            return false;
6203        }
6204
6205        if (!didSomething) {
6206            updateOomAdjLocked();
6207        }
6208
6209        return true;
6210    }
6211
6212    @Override
6213    public final void attachApplication(IApplicationThread thread) {
6214        synchronized (this) {
6215            int callingPid = Binder.getCallingPid();
6216            final long origId = Binder.clearCallingIdentity();
6217            attachApplicationLocked(thread, callingPid);
6218            Binder.restoreCallingIdentity(origId);
6219        }
6220    }
6221
6222    @Override
6223    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6224        final long origId = Binder.clearCallingIdentity();
6225        synchronized (this) {
6226            ActivityStack stack = ActivityRecord.getStackLocked(token);
6227            if (stack != null) {
6228                ActivityRecord r =
6229                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6230                if (stopProfiling) {
6231                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6232                        try {
6233                            mProfileFd.close();
6234                        } catch (IOException e) {
6235                        }
6236                        clearProfilerLocked();
6237                    }
6238                }
6239            }
6240        }
6241        Binder.restoreCallingIdentity(origId);
6242    }
6243
6244    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6245        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6246                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6247    }
6248
6249    void enableScreenAfterBoot() {
6250        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6251                SystemClock.uptimeMillis());
6252        mWindowManager.enableScreenAfterBoot();
6253
6254        synchronized (this) {
6255            updateEventDispatchingLocked();
6256        }
6257    }
6258
6259    @Override
6260    public void showBootMessage(final CharSequence msg, final boolean always) {
6261        if (Binder.getCallingUid() != Process.myUid()) {
6262            // These days only the core system can call this, so apps can't get in
6263            // the way of what we show about running them.
6264        }
6265        mWindowManager.showBootMessage(msg, always);
6266    }
6267
6268    @Override
6269    public void keyguardWaitingForActivityDrawn() {
6270        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6271        final long token = Binder.clearCallingIdentity();
6272        try {
6273            synchronized (this) {
6274                if (DEBUG_LOCKSCREEN) logLockScreen("");
6275                mWindowManager.keyguardWaitingForActivityDrawn();
6276                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6277                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6278                    updateSleepIfNeededLocked();
6279                }
6280            }
6281        } finally {
6282            Binder.restoreCallingIdentity(token);
6283        }
6284    }
6285
6286    @Override
6287    public void keyguardGoingAway(boolean disableWindowAnimations,
6288            boolean keyguardGoingToNotificationShade) {
6289        enforceNotIsolatedCaller("keyguardGoingAway");
6290        final long token = Binder.clearCallingIdentity();
6291        try {
6292            synchronized (this) {
6293                if (DEBUG_LOCKSCREEN) logLockScreen("");
6294                mWindowManager.keyguardGoingAway(disableWindowAnimations,
6295                        keyguardGoingToNotificationShade);
6296                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6297                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6298                    updateSleepIfNeededLocked();
6299                }
6300            }
6301        } finally {
6302            Binder.restoreCallingIdentity(token);
6303        }
6304    }
6305
6306    final void finishBooting() {
6307        synchronized (this) {
6308            if (!mBootAnimationComplete) {
6309                mCallFinishBooting = true;
6310                return;
6311            }
6312            mCallFinishBooting = false;
6313        }
6314
6315        ArraySet<String> completedIsas = new ArraySet<String>();
6316        for (String abi : Build.SUPPORTED_ABIS) {
6317            Process.establishZygoteConnectionForAbi(abi);
6318            final String instructionSet = VMRuntime.getInstructionSet(abi);
6319            if (!completedIsas.contains(instructionSet)) {
6320                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6321                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6322                }
6323                completedIsas.add(instructionSet);
6324            }
6325        }
6326
6327        IntentFilter pkgFilter = new IntentFilter();
6328        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6329        pkgFilter.addDataScheme("package");
6330        mContext.registerReceiver(new BroadcastReceiver() {
6331            @Override
6332            public void onReceive(Context context, Intent intent) {
6333                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6334                if (pkgs != null) {
6335                    for (String pkg : pkgs) {
6336                        synchronized (ActivityManagerService.this) {
6337                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6338                                    0, "query restart")) {
6339                                setResultCode(Activity.RESULT_OK);
6340                                return;
6341                            }
6342                        }
6343                    }
6344                }
6345            }
6346        }, pkgFilter);
6347
6348        IntentFilter dumpheapFilter = new IntentFilter();
6349        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6350        mContext.registerReceiver(new BroadcastReceiver() {
6351            @Override
6352            public void onReceive(Context context, Intent intent) {
6353                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6354                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6355                } else {
6356                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6357                }
6358            }
6359        }, dumpheapFilter);
6360
6361        // Let system services know.
6362        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6363
6364        synchronized (this) {
6365            // Ensure that any processes we had put on hold are now started
6366            // up.
6367            final int NP = mProcessesOnHold.size();
6368            if (NP > 0) {
6369                ArrayList<ProcessRecord> procs =
6370                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6371                for (int ip=0; ip<NP; ip++) {
6372                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6373                            + procs.get(ip));
6374                    startProcessLocked(procs.get(ip), "on-hold", null);
6375                }
6376            }
6377
6378            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6379                // Start looking for apps that are abusing wake locks.
6380                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6381                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6382                // Tell anyone interested that we are done booting!
6383                SystemProperties.set("sys.boot_completed", "1");
6384
6385                // And trigger dev.bootcomplete if we are not showing encryption progress
6386                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6387                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6388                    SystemProperties.set("dev.bootcomplete", "1");
6389                }
6390                for (int i=0; i<mStartedUsers.size(); i++) {
6391                    UserState uss = mStartedUsers.valueAt(i);
6392                    if (uss.mState == UserState.STATE_BOOTING) {
6393                        uss.mState = UserState.STATE_RUNNING;
6394                        final int userId = mStartedUsers.keyAt(i);
6395                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6396                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6397                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6398                        broadcastIntentLocked(null, null, intent, null,
6399                                new IIntentReceiver.Stub() {
6400                                    @Override
6401                                    public void performReceive(Intent intent, int resultCode,
6402                                            String data, Bundle extras, boolean ordered,
6403                                            boolean sticky, int sendingUser) {
6404                                        synchronized (ActivityManagerService.this) {
6405                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6406                                                    true, false);
6407                                        }
6408                                    }
6409                                },
6410                                0, null, null,
6411                                new String[] {android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
6412                                AppOpsManager.OP_NONE, null, true, false,
6413                                MY_PID, Process.SYSTEM_UID, userId);
6414                    }
6415                }
6416                scheduleStartProfilesLocked();
6417            }
6418        }
6419    }
6420
6421    @Override
6422    public void bootAnimationComplete() {
6423        final boolean callFinishBooting;
6424        synchronized (this) {
6425            callFinishBooting = mCallFinishBooting;
6426            mBootAnimationComplete = true;
6427        }
6428        if (callFinishBooting) {
6429            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6430            finishBooting();
6431            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6432        }
6433    }
6434
6435    final void ensureBootCompleted() {
6436        boolean booting;
6437        boolean enableScreen;
6438        synchronized (this) {
6439            booting = mBooting;
6440            mBooting = false;
6441            enableScreen = !mBooted;
6442            mBooted = true;
6443        }
6444
6445        if (booting) {
6446            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6447            finishBooting();
6448            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6449        }
6450
6451        if (enableScreen) {
6452            enableScreenAfterBoot();
6453        }
6454    }
6455
6456    @Override
6457    public final void activityResumed(IBinder token) {
6458        final long origId = Binder.clearCallingIdentity();
6459        synchronized(this) {
6460            ActivityStack stack = ActivityRecord.getStackLocked(token);
6461            if (stack != null) {
6462                ActivityRecord.activityResumedLocked(token);
6463            }
6464        }
6465        Binder.restoreCallingIdentity(origId);
6466    }
6467
6468    @Override
6469    public final void activityPaused(IBinder token) {
6470        final long origId = Binder.clearCallingIdentity();
6471        synchronized(this) {
6472            ActivityStack stack = ActivityRecord.getStackLocked(token);
6473            if (stack != null) {
6474                stack.activityPausedLocked(token, false);
6475            }
6476        }
6477        Binder.restoreCallingIdentity(origId);
6478    }
6479
6480    @Override
6481    public final void activityStopped(IBinder token, Bundle icicle,
6482            PersistableBundle persistentState, CharSequence description) {
6483        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6484
6485        // Refuse possible leaked file descriptors
6486        if (icicle != null && icicle.hasFileDescriptors()) {
6487            throw new IllegalArgumentException("File descriptors passed in Bundle");
6488        }
6489
6490        final long origId = Binder.clearCallingIdentity();
6491
6492        synchronized (this) {
6493            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6494            if (r != null) {
6495                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6496            }
6497        }
6498
6499        trimApplications();
6500
6501        Binder.restoreCallingIdentity(origId);
6502    }
6503
6504    @Override
6505    public final void activityDestroyed(IBinder token) {
6506        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6507        synchronized (this) {
6508            ActivityStack stack = ActivityRecord.getStackLocked(token);
6509            if (stack != null) {
6510                stack.activityDestroyedLocked(token, "activityDestroyed");
6511            }
6512        }
6513    }
6514
6515    @Override
6516    public final void backgroundResourcesReleased(IBinder token) {
6517        final long origId = Binder.clearCallingIdentity();
6518        try {
6519            synchronized (this) {
6520                ActivityStack stack = ActivityRecord.getStackLocked(token);
6521                if (stack != null) {
6522                    stack.backgroundResourcesReleased();
6523                }
6524            }
6525        } finally {
6526            Binder.restoreCallingIdentity(origId);
6527        }
6528    }
6529
6530    @Override
6531    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6532        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6533    }
6534
6535    @Override
6536    public final void notifyEnterAnimationComplete(IBinder token) {
6537        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6538    }
6539
6540    @Override
6541    public String getCallingPackage(IBinder token) {
6542        synchronized (this) {
6543            ActivityRecord r = getCallingRecordLocked(token);
6544            return r != null ? r.info.packageName : null;
6545        }
6546    }
6547
6548    @Override
6549    public ComponentName getCallingActivity(IBinder token) {
6550        synchronized (this) {
6551            ActivityRecord r = getCallingRecordLocked(token);
6552            return r != null ? r.intent.getComponent() : null;
6553        }
6554    }
6555
6556    private ActivityRecord getCallingRecordLocked(IBinder token) {
6557        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6558        if (r == null) {
6559            return null;
6560        }
6561        return r.resultTo;
6562    }
6563
6564    @Override
6565    public ComponentName getActivityClassForToken(IBinder token) {
6566        synchronized(this) {
6567            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6568            if (r == null) {
6569                return null;
6570            }
6571            return r.intent.getComponent();
6572        }
6573    }
6574
6575    @Override
6576    public String getPackageForToken(IBinder token) {
6577        synchronized(this) {
6578            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6579            if (r == null) {
6580                return null;
6581            }
6582            return r.packageName;
6583        }
6584    }
6585
6586    @Override
6587    public boolean isRootVoiceInteraction(IBinder token) {
6588        synchronized(this) {
6589            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6590            if (r == null) {
6591                return false;
6592            }
6593            return r.rootVoiceInteraction;
6594        }
6595    }
6596
6597    @Override
6598    public IIntentSender getIntentSender(int type,
6599            String packageName, IBinder token, String resultWho,
6600            int requestCode, Intent[] intents, String[] resolvedTypes,
6601            int flags, Bundle options, int userId) {
6602        enforceNotIsolatedCaller("getIntentSender");
6603        // Refuse possible leaked file descriptors
6604        if (intents != null) {
6605            if (intents.length < 1) {
6606                throw new IllegalArgumentException("Intents array length must be >= 1");
6607            }
6608            for (int i=0; i<intents.length; i++) {
6609                Intent intent = intents[i];
6610                if (intent != null) {
6611                    if (intent.hasFileDescriptors()) {
6612                        throw new IllegalArgumentException("File descriptors passed in Intent");
6613                    }
6614                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6615                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6616                        throw new IllegalArgumentException(
6617                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6618                    }
6619                    intents[i] = new Intent(intent);
6620                }
6621            }
6622            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6623                throw new IllegalArgumentException(
6624                        "Intent array length does not match resolvedTypes length");
6625            }
6626        }
6627        if (options != null) {
6628            if (options.hasFileDescriptors()) {
6629                throw new IllegalArgumentException("File descriptors passed in options");
6630            }
6631        }
6632
6633        synchronized(this) {
6634            int callingUid = Binder.getCallingUid();
6635            int origUserId = userId;
6636            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6637                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6638                    ALLOW_NON_FULL, "getIntentSender", null);
6639            if (origUserId == UserHandle.USER_CURRENT) {
6640                // We don't want to evaluate this until the pending intent is
6641                // actually executed.  However, we do want to always do the
6642                // security checking for it above.
6643                userId = UserHandle.USER_CURRENT;
6644            }
6645            try {
6646                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6647                    int uid = AppGlobals.getPackageManager()
6648                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6649                    if (!UserHandle.isSameApp(callingUid, uid)) {
6650                        String msg = "Permission Denial: getIntentSender() from pid="
6651                            + Binder.getCallingPid()
6652                            + ", uid=" + Binder.getCallingUid()
6653                            + ", (need uid=" + uid + ")"
6654                            + " is not allowed to send as package " + packageName;
6655                        Slog.w(TAG, msg);
6656                        throw new SecurityException(msg);
6657                    }
6658                }
6659
6660                return getIntentSenderLocked(type, packageName, callingUid, userId,
6661                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6662
6663            } catch (RemoteException e) {
6664                throw new SecurityException(e);
6665            }
6666        }
6667    }
6668
6669    IIntentSender getIntentSenderLocked(int type, String packageName,
6670            int callingUid, int userId, IBinder token, String resultWho,
6671            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6672            Bundle options) {
6673        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6674        ActivityRecord activity = null;
6675        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6676            activity = ActivityRecord.isInStackLocked(token);
6677            if (activity == null) {
6678                return null;
6679            }
6680            if (activity.finishing) {
6681                return null;
6682            }
6683        }
6684
6685        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6686        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6687        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6688        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6689                |PendingIntent.FLAG_UPDATE_CURRENT);
6690
6691        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6692                type, packageName, activity, resultWho,
6693                requestCode, intents, resolvedTypes, flags, options, userId);
6694        WeakReference<PendingIntentRecord> ref;
6695        ref = mIntentSenderRecords.get(key);
6696        PendingIntentRecord rec = ref != null ? ref.get() : null;
6697        if (rec != null) {
6698            if (!cancelCurrent) {
6699                if (updateCurrent) {
6700                    if (rec.key.requestIntent != null) {
6701                        rec.key.requestIntent.replaceExtras(intents != null ?
6702                                intents[intents.length - 1] : null);
6703                    }
6704                    if (intents != null) {
6705                        intents[intents.length-1] = rec.key.requestIntent;
6706                        rec.key.allIntents = intents;
6707                        rec.key.allResolvedTypes = resolvedTypes;
6708                    } else {
6709                        rec.key.allIntents = null;
6710                        rec.key.allResolvedTypes = null;
6711                    }
6712                }
6713                return rec;
6714            }
6715            rec.canceled = true;
6716            mIntentSenderRecords.remove(key);
6717        }
6718        if (noCreate) {
6719            return rec;
6720        }
6721        rec = new PendingIntentRecord(this, key, callingUid);
6722        mIntentSenderRecords.put(key, rec.ref);
6723        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6724            if (activity.pendingResults == null) {
6725                activity.pendingResults
6726                        = new HashSet<WeakReference<PendingIntentRecord>>();
6727            }
6728            activity.pendingResults.add(rec.ref);
6729        }
6730        return rec;
6731    }
6732
6733    @Override
6734    public void cancelIntentSender(IIntentSender sender) {
6735        if (!(sender instanceof PendingIntentRecord)) {
6736            return;
6737        }
6738        synchronized(this) {
6739            PendingIntentRecord rec = (PendingIntentRecord)sender;
6740            try {
6741                int uid = AppGlobals.getPackageManager()
6742                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6743                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6744                    String msg = "Permission Denial: cancelIntentSender() from pid="
6745                        + Binder.getCallingPid()
6746                        + ", uid=" + Binder.getCallingUid()
6747                        + " is not allowed to cancel packges "
6748                        + rec.key.packageName;
6749                    Slog.w(TAG, msg);
6750                    throw new SecurityException(msg);
6751                }
6752            } catch (RemoteException e) {
6753                throw new SecurityException(e);
6754            }
6755            cancelIntentSenderLocked(rec, true);
6756        }
6757    }
6758
6759    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6760        rec.canceled = true;
6761        mIntentSenderRecords.remove(rec.key);
6762        if (cleanActivity && rec.key.activity != null) {
6763            rec.key.activity.pendingResults.remove(rec.ref);
6764        }
6765    }
6766
6767    @Override
6768    public String getPackageForIntentSender(IIntentSender pendingResult) {
6769        if (!(pendingResult instanceof PendingIntentRecord)) {
6770            return null;
6771        }
6772        try {
6773            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6774            return res.key.packageName;
6775        } catch (ClassCastException e) {
6776        }
6777        return null;
6778    }
6779
6780    @Override
6781    public int getUidForIntentSender(IIntentSender sender) {
6782        if (sender instanceof PendingIntentRecord) {
6783            try {
6784                PendingIntentRecord res = (PendingIntentRecord)sender;
6785                return res.uid;
6786            } catch (ClassCastException e) {
6787            }
6788        }
6789        return -1;
6790    }
6791
6792    @Override
6793    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6794        if (!(pendingResult instanceof PendingIntentRecord)) {
6795            return false;
6796        }
6797        try {
6798            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6799            if (res.key.allIntents == null) {
6800                return false;
6801            }
6802            for (int i=0; i<res.key.allIntents.length; i++) {
6803                Intent intent = res.key.allIntents[i];
6804                if (intent.getPackage() != null && intent.getComponent() != null) {
6805                    return false;
6806                }
6807            }
6808            return true;
6809        } catch (ClassCastException e) {
6810        }
6811        return false;
6812    }
6813
6814    @Override
6815    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6816        if (!(pendingResult instanceof PendingIntentRecord)) {
6817            return false;
6818        }
6819        try {
6820            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6821            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6822                return true;
6823            }
6824            return false;
6825        } catch (ClassCastException e) {
6826        }
6827        return false;
6828    }
6829
6830    @Override
6831    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6832        if (!(pendingResult instanceof PendingIntentRecord)) {
6833            return null;
6834        }
6835        try {
6836            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6837            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6838        } catch (ClassCastException e) {
6839        }
6840        return null;
6841    }
6842
6843    @Override
6844    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6845        if (!(pendingResult instanceof PendingIntentRecord)) {
6846            return null;
6847        }
6848        try {
6849            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6850            synchronized (this) {
6851                return getTagForIntentSenderLocked(res, prefix);
6852            }
6853        } catch (ClassCastException e) {
6854        }
6855        return null;
6856    }
6857
6858    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
6859        final Intent intent = res.key.requestIntent;
6860        if (intent != null) {
6861            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6862                    || res.lastTagPrefix.equals(prefix))) {
6863                return res.lastTag;
6864            }
6865            res.lastTagPrefix = prefix;
6866            final StringBuilder sb = new StringBuilder(128);
6867            if (prefix != null) {
6868                sb.append(prefix);
6869            }
6870            if (intent.getAction() != null) {
6871                sb.append(intent.getAction());
6872            } else if (intent.getComponent() != null) {
6873                intent.getComponent().appendShortString(sb);
6874            } else {
6875                sb.append("?");
6876            }
6877            return res.lastTag = sb.toString();
6878        }
6879        return null;
6880    }
6881
6882    @Override
6883    public void setProcessLimit(int max) {
6884        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6885                "setProcessLimit()");
6886        synchronized (this) {
6887            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6888            mProcessLimitOverride = max;
6889        }
6890        trimApplications();
6891    }
6892
6893    @Override
6894    public int getProcessLimit() {
6895        synchronized (this) {
6896            return mProcessLimitOverride;
6897        }
6898    }
6899
6900    void foregroundTokenDied(ForegroundToken token) {
6901        synchronized (ActivityManagerService.this) {
6902            synchronized (mPidsSelfLocked) {
6903                ForegroundToken cur
6904                    = mForegroundProcesses.get(token.pid);
6905                if (cur != token) {
6906                    return;
6907                }
6908                mForegroundProcesses.remove(token.pid);
6909                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6910                if (pr == null) {
6911                    return;
6912                }
6913                pr.forcingToForeground = null;
6914                updateProcessForegroundLocked(pr, false, false);
6915            }
6916            updateOomAdjLocked();
6917        }
6918    }
6919
6920    @Override
6921    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6922        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6923                "setProcessForeground()");
6924        synchronized(this) {
6925            boolean changed = false;
6926
6927            synchronized (mPidsSelfLocked) {
6928                ProcessRecord pr = mPidsSelfLocked.get(pid);
6929                if (pr == null && isForeground) {
6930                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6931                    return;
6932                }
6933                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6934                if (oldToken != null) {
6935                    oldToken.token.unlinkToDeath(oldToken, 0);
6936                    mForegroundProcesses.remove(pid);
6937                    if (pr != null) {
6938                        pr.forcingToForeground = null;
6939                    }
6940                    changed = true;
6941                }
6942                if (isForeground && token != null) {
6943                    ForegroundToken newToken = new ForegroundToken() {
6944                        @Override
6945                        public void binderDied() {
6946                            foregroundTokenDied(this);
6947                        }
6948                    };
6949                    newToken.pid = pid;
6950                    newToken.token = token;
6951                    try {
6952                        token.linkToDeath(newToken, 0);
6953                        mForegroundProcesses.put(pid, newToken);
6954                        pr.forcingToForeground = token;
6955                        changed = true;
6956                    } catch (RemoteException e) {
6957                        // If the process died while doing this, we will later
6958                        // do the cleanup with the process death link.
6959                    }
6960                }
6961            }
6962
6963            if (changed) {
6964                updateOomAdjLocked();
6965            }
6966        }
6967    }
6968
6969    // =========================================================
6970    // PROCESS INFO
6971    // =========================================================
6972
6973    static class ProcessInfoService extends IProcessInfoService.Stub {
6974        final ActivityManagerService mActivityManagerService;
6975        ProcessInfoService(ActivityManagerService activityManagerService) {
6976            mActivityManagerService = activityManagerService;
6977        }
6978
6979        @Override
6980        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
6981            mActivityManagerService.getProcessStatesForPIDs(/*in*/ pids, /*out*/ states);
6982        }
6983    }
6984
6985    /**
6986     * For each PID in the given input array, write the current process state
6987     * for that process into the output array, or -1 to indicate that no
6988     * process with the given PID exists.
6989     */
6990    public void getProcessStatesForPIDs(/*in*/ int[] pids, /*out*/ int[] states) {
6991        if (pids == null) {
6992            throw new NullPointerException("pids");
6993        } else if (states == null) {
6994            throw new NullPointerException("states");
6995        } else if (pids.length != states.length) {
6996            throw new IllegalArgumentException("input and output arrays have different lengths!");
6997        }
6998
6999        synchronized (mPidsSelfLocked) {
7000            for (int i = 0; i < pids.length; i++) {
7001                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7002                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7003                        pr.curProcState;
7004            }
7005        }
7006    }
7007
7008    // =========================================================
7009    // PERMISSIONS
7010    // =========================================================
7011
7012    static class PermissionController extends IPermissionController.Stub {
7013        ActivityManagerService mActivityManagerService;
7014        PermissionController(ActivityManagerService activityManagerService) {
7015            mActivityManagerService = activityManagerService;
7016        }
7017
7018        @Override
7019        public boolean checkPermission(String permission, int pid, int uid) {
7020            return mActivityManagerService.checkPermission(permission, pid,
7021                    uid) == PackageManager.PERMISSION_GRANTED;
7022        }
7023
7024        @Override
7025        public String[] getPackagesForUid(int uid) {
7026            return mActivityManagerService.mContext.getPackageManager()
7027                    .getPackagesForUid(uid);
7028        }
7029
7030        @Override
7031        public boolean isRuntimePermission(String permission) {
7032            try {
7033                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7034                        .getPermissionInfo(permission, 0);
7035                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7036            } catch (NameNotFoundException nnfe) {
7037                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7038            }
7039            return false;
7040        }
7041    }
7042
7043    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7044        @Override
7045        public int checkComponentPermission(String permission, int pid, int uid,
7046                int owningUid, boolean exported) {
7047            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7048                    owningUid, exported);
7049        }
7050
7051        @Override
7052        public Object getAMSLock() {
7053            return ActivityManagerService.this;
7054        }
7055    }
7056
7057    /**
7058     * This can be called with or without the global lock held.
7059     */
7060    int checkComponentPermission(String permission, int pid, int uid,
7061            int owningUid, boolean exported) {
7062        if (pid == MY_PID) {
7063            return PackageManager.PERMISSION_GRANTED;
7064        }
7065        return ActivityManager.checkComponentPermission(permission, uid,
7066                owningUid, exported);
7067    }
7068
7069    /**
7070     * As the only public entry point for permissions checking, this method
7071     * can enforce the semantic that requesting a check on a null global
7072     * permission is automatically denied.  (Internally a null permission
7073     * string is used when calling {@link #checkComponentPermission} in cases
7074     * when only uid-based security is needed.)
7075     *
7076     * This can be called with or without the global lock held.
7077     */
7078    @Override
7079    public int checkPermission(String permission, int pid, int uid) {
7080        if (permission == null) {
7081            return PackageManager.PERMISSION_DENIED;
7082        }
7083        return checkComponentPermission(permission, pid, uid, -1, true);
7084    }
7085
7086    @Override
7087    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7088        if (permission == null) {
7089            return PackageManager.PERMISSION_DENIED;
7090        }
7091
7092        // We might be performing an operation on behalf of an indirect binder
7093        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7094        // client identity accordingly before proceeding.
7095        Identity tlsIdentity = sCallerIdentity.get();
7096        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7097            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7098                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7099            uid = tlsIdentity.uid;
7100            pid = tlsIdentity.pid;
7101        }
7102
7103        return checkComponentPermission(permission, pid, uid, -1, true);
7104    }
7105
7106    /**
7107     * Binder IPC calls go through the public entry point.
7108     * This can be called with or without the global lock held.
7109     */
7110    int checkCallingPermission(String permission) {
7111        return checkPermission(permission,
7112                Binder.getCallingPid(),
7113                UserHandle.getAppId(Binder.getCallingUid()));
7114    }
7115
7116    /**
7117     * This can be called with or without the global lock held.
7118     */
7119    void enforceCallingPermission(String permission, String func) {
7120        if (checkCallingPermission(permission)
7121                == PackageManager.PERMISSION_GRANTED) {
7122            return;
7123        }
7124
7125        String msg = "Permission Denial: " + func + " from pid="
7126                + Binder.getCallingPid()
7127                + ", uid=" + Binder.getCallingUid()
7128                + " requires " + permission;
7129        Slog.w(TAG, msg);
7130        throw new SecurityException(msg);
7131    }
7132
7133    /**
7134     * Determine if UID is holding permissions required to access {@link Uri} in
7135     * the given {@link ProviderInfo}. Final permission checking is always done
7136     * in {@link ContentProvider}.
7137     */
7138    private final boolean checkHoldingPermissionsLocked(
7139            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7140        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7141                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7142        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7143            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7144                    != PERMISSION_GRANTED) {
7145                return false;
7146            }
7147        }
7148        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7149    }
7150
7151    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7152            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7153        if (pi.applicationInfo.uid == uid) {
7154            return true;
7155        } else if (!pi.exported) {
7156            return false;
7157        }
7158
7159        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7160        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7161        try {
7162            // check if target holds top-level <provider> permissions
7163            if (!readMet && pi.readPermission != null && considerUidPermissions
7164                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7165                readMet = true;
7166            }
7167            if (!writeMet && pi.writePermission != null && considerUidPermissions
7168                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7169                writeMet = true;
7170            }
7171
7172            // track if unprotected read/write is allowed; any denied
7173            // <path-permission> below removes this ability
7174            boolean allowDefaultRead = pi.readPermission == null;
7175            boolean allowDefaultWrite = pi.writePermission == null;
7176
7177            // check if target holds any <path-permission> that match uri
7178            final PathPermission[] pps = pi.pathPermissions;
7179            if (pps != null) {
7180                final String path = grantUri.uri.getPath();
7181                int i = pps.length;
7182                while (i > 0 && (!readMet || !writeMet)) {
7183                    i--;
7184                    PathPermission pp = pps[i];
7185                    if (pp.match(path)) {
7186                        if (!readMet) {
7187                            final String pprperm = pp.getReadPermission();
7188                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7189                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7190                                    + ": match=" + pp.match(path)
7191                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7192                            if (pprperm != null) {
7193                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7194                                        == PERMISSION_GRANTED) {
7195                                    readMet = true;
7196                                } else {
7197                                    allowDefaultRead = false;
7198                                }
7199                            }
7200                        }
7201                        if (!writeMet) {
7202                            final String ppwperm = pp.getWritePermission();
7203                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7204                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7205                                    + ": match=" + pp.match(path)
7206                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7207                            if (ppwperm != null) {
7208                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7209                                        == PERMISSION_GRANTED) {
7210                                    writeMet = true;
7211                                } else {
7212                                    allowDefaultWrite = false;
7213                                }
7214                            }
7215                        }
7216                    }
7217                }
7218            }
7219
7220            // grant unprotected <provider> read/write, if not blocked by
7221            // <path-permission> above
7222            if (allowDefaultRead) readMet = true;
7223            if (allowDefaultWrite) writeMet = true;
7224
7225        } catch (RemoteException e) {
7226            return false;
7227        }
7228
7229        return readMet && writeMet;
7230    }
7231
7232    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7233        ProviderInfo pi = null;
7234        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7235        if (cpr != null) {
7236            pi = cpr.info;
7237        } else {
7238            try {
7239                pi = AppGlobals.getPackageManager().resolveContentProvider(
7240                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7241            } catch (RemoteException ex) {
7242            }
7243        }
7244        return pi;
7245    }
7246
7247    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7248        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7249        if (targetUris != null) {
7250            return targetUris.get(grantUri);
7251        }
7252        return null;
7253    }
7254
7255    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7256            String targetPkg, int targetUid, GrantUri grantUri) {
7257        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7258        if (targetUris == null) {
7259            targetUris = Maps.newArrayMap();
7260            mGrantedUriPermissions.put(targetUid, targetUris);
7261        }
7262
7263        UriPermission perm = targetUris.get(grantUri);
7264        if (perm == null) {
7265            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7266            targetUris.put(grantUri, perm);
7267        }
7268
7269        return perm;
7270    }
7271
7272    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7273            final int modeFlags) {
7274        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7275        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7276                : UriPermission.STRENGTH_OWNED;
7277
7278        // Root gets to do everything.
7279        if (uid == 0) {
7280            return true;
7281        }
7282
7283        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7284        if (perms == null) return false;
7285
7286        // First look for exact match
7287        final UriPermission exactPerm = perms.get(grantUri);
7288        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7289            return true;
7290        }
7291
7292        // No exact match, look for prefixes
7293        final int N = perms.size();
7294        for (int i = 0; i < N; i++) {
7295            final UriPermission perm = perms.valueAt(i);
7296            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7297                    && perm.getStrength(modeFlags) >= minStrength) {
7298                return true;
7299            }
7300        }
7301
7302        return false;
7303    }
7304
7305    /**
7306     * @param uri This uri must NOT contain an embedded userId.
7307     * @param userId The userId in which the uri is to be resolved.
7308     */
7309    @Override
7310    public int checkUriPermission(Uri uri, int pid, int uid,
7311            final int modeFlags, int userId, IBinder callerToken) {
7312        enforceNotIsolatedCaller("checkUriPermission");
7313
7314        // Another redirected-binder-call permissions check as in
7315        // {@link checkPermissionWithToken}.
7316        Identity tlsIdentity = sCallerIdentity.get();
7317        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7318            uid = tlsIdentity.uid;
7319            pid = tlsIdentity.pid;
7320        }
7321
7322        // Our own process gets to do everything.
7323        if (pid == MY_PID) {
7324            return PackageManager.PERMISSION_GRANTED;
7325        }
7326        synchronized (this) {
7327            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7328                    ? PackageManager.PERMISSION_GRANTED
7329                    : PackageManager.PERMISSION_DENIED;
7330        }
7331    }
7332
7333    /**
7334     * Check if the targetPkg can be granted permission to access uri by
7335     * the callingUid using the given modeFlags.  Throws a security exception
7336     * if callingUid is not allowed to do this.  Returns the uid of the target
7337     * if the URI permission grant should be performed; returns -1 if it is not
7338     * needed (for example targetPkg already has permission to access the URI).
7339     * If you already know the uid of the target, you can supply it in
7340     * lastTargetUid else set that to -1.
7341     */
7342    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7343            final int modeFlags, int lastTargetUid) {
7344        if (!Intent.isAccessUriMode(modeFlags)) {
7345            return -1;
7346        }
7347
7348        if (targetPkg != null) {
7349            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7350                    "Checking grant " + targetPkg + " permission to " + grantUri);
7351        }
7352
7353        final IPackageManager pm = AppGlobals.getPackageManager();
7354
7355        // If this is not a content: uri, we can't do anything with it.
7356        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7357            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7358                    "Can't grant URI permission for non-content URI: " + grantUri);
7359            return -1;
7360        }
7361
7362        final String authority = grantUri.uri.getAuthority();
7363        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7364        if (pi == null) {
7365            Slog.w(TAG, "No content provider found for permission check: " +
7366                    grantUri.uri.toSafeString());
7367            return -1;
7368        }
7369
7370        int targetUid = lastTargetUid;
7371        if (targetUid < 0 && targetPkg != null) {
7372            try {
7373                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7374                if (targetUid < 0) {
7375                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7376                            "Can't grant URI permission no uid for: " + targetPkg);
7377                    return -1;
7378                }
7379            } catch (RemoteException ex) {
7380                return -1;
7381            }
7382        }
7383
7384        if (targetUid >= 0) {
7385            // First...  does the target actually need this permission?
7386            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7387                // No need to grant the target this permission.
7388                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7389                        "Target " + targetPkg + " already has full permission to " + grantUri);
7390                return -1;
7391            }
7392        } else {
7393            // First...  there is no target package, so can anyone access it?
7394            boolean allowed = pi.exported;
7395            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7396                if (pi.readPermission != null) {
7397                    allowed = false;
7398                }
7399            }
7400            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7401                if (pi.writePermission != null) {
7402                    allowed = false;
7403                }
7404            }
7405            if (allowed) {
7406                return -1;
7407            }
7408        }
7409
7410        /* There is a special cross user grant if:
7411         * - The target is on another user.
7412         * - Apps on the current user can access the uri without any uid permissions.
7413         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7414         * grant uri permissions.
7415         */
7416        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7417                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7418                modeFlags, false /*without considering the uid permissions*/);
7419
7420        // Second...  is the provider allowing granting of URI permissions?
7421        if (!specialCrossUserGrant) {
7422            if (!pi.grantUriPermissions) {
7423                throw new SecurityException("Provider " + pi.packageName
7424                        + "/" + pi.name
7425                        + " does not allow granting of Uri permissions (uri "
7426                        + grantUri + ")");
7427            }
7428            if (pi.uriPermissionPatterns != null) {
7429                final int N = pi.uriPermissionPatterns.length;
7430                boolean allowed = false;
7431                for (int i=0; i<N; i++) {
7432                    if (pi.uriPermissionPatterns[i] != null
7433                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7434                        allowed = true;
7435                        break;
7436                    }
7437                }
7438                if (!allowed) {
7439                    throw new SecurityException("Provider " + pi.packageName
7440                            + "/" + pi.name
7441                            + " does not allow granting of permission to path of Uri "
7442                            + grantUri);
7443                }
7444            }
7445        }
7446
7447        // Third...  does the caller itself have permission to access
7448        // this uri?
7449        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7450            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7451                // Require they hold a strong enough Uri permission
7452                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7453                    throw new SecurityException("Uid " + callingUid
7454                            + " does not have permission to uri " + grantUri);
7455                }
7456            }
7457        }
7458        return targetUid;
7459    }
7460
7461    /**
7462     * @param uri This uri must NOT contain an embedded userId.
7463     * @param userId The userId in which the uri is to be resolved.
7464     */
7465    @Override
7466    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7467            final int modeFlags, int userId) {
7468        enforceNotIsolatedCaller("checkGrantUriPermission");
7469        synchronized(this) {
7470            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7471                    new GrantUri(userId, uri, false), modeFlags, -1);
7472        }
7473    }
7474
7475    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7476            final int modeFlags, UriPermissionOwner owner) {
7477        if (!Intent.isAccessUriMode(modeFlags)) {
7478            return;
7479        }
7480
7481        // So here we are: the caller has the assumed permission
7482        // to the uri, and the target doesn't.  Let's now give this to
7483        // the target.
7484
7485        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7486                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7487
7488        final String authority = grantUri.uri.getAuthority();
7489        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7490        if (pi == null) {
7491            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7492            return;
7493        }
7494
7495        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7496            grantUri.prefix = true;
7497        }
7498        final UriPermission perm = findOrCreateUriPermissionLocked(
7499                pi.packageName, targetPkg, targetUid, grantUri);
7500        perm.grantModes(modeFlags, owner);
7501    }
7502
7503    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7504            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7505        if (targetPkg == null) {
7506            throw new NullPointerException("targetPkg");
7507        }
7508        int targetUid;
7509        final IPackageManager pm = AppGlobals.getPackageManager();
7510        try {
7511            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7512        } catch (RemoteException ex) {
7513            return;
7514        }
7515
7516        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7517                targetUid);
7518        if (targetUid < 0) {
7519            return;
7520        }
7521
7522        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7523                owner);
7524    }
7525
7526    static class NeededUriGrants extends ArrayList<GrantUri> {
7527        final String targetPkg;
7528        final int targetUid;
7529        final int flags;
7530
7531        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7532            this.targetPkg = targetPkg;
7533            this.targetUid = targetUid;
7534            this.flags = flags;
7535        }
7536    }
7537
7538    /**
7539     * Like checkGrantUriPermissionLocked, but takes an Intent.
7540     */
7541    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7542            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7543        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7544                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7545                + " clip=" + (intent != null ? intent.getClipData() : null)
7546                + " from " + intent + "; flags=0x"
7547                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7548
7549        if (targetPkg == null) {
7550            throw new NullPointerException("targetPkg");
7551        }
7552
7553        if (intent == null) {
7554            return null;
7555        }
7556        Uri data = intent.getData();
7557        ClipData clip = intent.getClipData();
7558        if (data == null && clip == null) {
7559            return null;
7560        }
7561        // Default userId for uris in the intent (if they don't specify it themselves)
7562        int contentUserHint = intent.getContentUserHint();
7563        if (contentUserHint == UserHandle.USER_CURRENT) {
7564            contentUserHint = UserHandle.getUserId(callingUid);
7565        }
7566        final IPackageManager pm = AppGlobals.getPackageManager();
7567        int targetUid;
7568        if (needed != null) {
7569            targetUid = needed.targetUid;
7570        } else {
7571            try {
7572                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7573            } catch (RemoteException ex) {
7574                return null;
7575            }
7576            if (targetUid < 0) {
7577                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7578                        "Can't grant URI permission no uid for: " + targetPkg
7579                        + " on user " + targetUserId);
7580                return null;
7581            }
7582        }
7583        if (data != null) {
7584            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7585            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7586                    targetUid);
7587            if (targetUid > 0) {
7588                if (needed == null) {
7589                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7590                }
7591                needed.add(grantUri);
7592            }
7593        }
7594        if (clip != null) {
7595            for (int i=0; i<clip.getItemCount(); i++) {
7596                Uri uri = clip.getItemAt(i).getUri();
7597                if (uri != null) {
7598                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7599                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7600                            targetUid);
7601                    if (targetUid > 0) {
7602                        if (needed == null) {
7603                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7604                        }
7605                        needed.add(grantUri);
7606                    }
7607                } else {
7608                    Intent clipIntent = clip.getItemAt(i).getIntent();
7609                    if (clipIntent != null) {
7610                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7611                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7612                        if (newNeeded != null) {
7613                            needed = newNeeded;
7614                        }
7615                    }
7616                }
7617            }
7618        }
7619
7620        return needed;
7621    }
7622
7623    /**
7624     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7625     */
7626    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7627            UriPermissionOwner owner) {
7628        if (needed != null) {
7629            for (int i=0; i<needed.size(); i++) {
7630                GrantUri grantUri = needed.get(i);
7631                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7632                        grantUri, needed.flags, owner);
7633            }
7634        }
7635    }
7636
7637    void grantUriPermissionFromIntentLocked(int callingUid,
7638            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7639        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7640                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7641        if (needed == null) {
7642            return;
7643        }
7644
7645        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7646    }
7647
7648    /**
7649     * @param uri This uri must NOT contain an embedded userId.
7650     * @param userId The userId in which the uri is to be resolved.
7651     */
7652    @Override
7653    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7654            final int modeFlags, int userId) {
7655        enforceNotIsolatedCaller("grantUriPermission");
7656        GrantUri grantUri = new GrantUri(userId, uri, false);
7657        synchronized(this) {
7658            final ProcessRecord r = getRecordForAppLocked(caller);
7659            if (r == null) {
7660                throw new SecurityException("Unable to find app for caller "
7661                        + caller
7662                        + " when granting permission to uri " + grantUri);
7663            }
7664            if (targetPkg == null) {
7665                throw new IllegalArgumentException("null target");
7666            }
7667            if (grantUri == null) {
7668                throw new IllegalArgumentException("null uri");
7669            }
7670
7671            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7672                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7673                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7674                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7675
7676            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7677                    UserHandle.getUserId(r.uid));
7678        }
7679    }
7680
7681    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7682        if (perm.modeFlags == 0) {
7683            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7684                    perm.targetUid);
7685            if (perms != null) {
7686                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7687                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7688
7689                perms.remove(perm.uri);
7690                if (perms.isEmpty()) {
7691                    mGrantedUriPermissions.remove(perm.targetUid);
7692                }
7693            }
7694        }
7695    }
7696
7697    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7698        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7699                "Revoking all granted permissions to " + grantUri);
7700
7701        final IPackageManager pm = AppGlobals.getPackageManager();
7702        final String authority = grantUri.uri.getAuthority();
7703        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7704        if (pi == null) {
7705            Slog.w(TAG, "No content provider found for permission revoke: "
7706                    + grantUri.toSafeString());
7707            return;
7708        }
7709
7710        // Does the caller have this permission on the URI?
7711        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7712            // If they don't have direct access to the URI, then revoke any
7713            // ownerless URI permissions that have been granted to them.
7714            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7715            if (perms != null) {
7716                boolean persistChanged = false;
7717                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7718                    final UriPermission perm = it.next();
7719                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7720                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7721                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7722                                "Revoking non-owned " + perm.targetUid
7723                                + " permission to " + perm.uri);
7724                        persistChanged |= perm.revokeModes(
7725                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7726                        if (perm.modeFlags == 0) {
7727                            it.remove();
7728                        }
7729                    }
7730                }
7731                if (perms.isEmpty()) {
7732                    mGrantedUriPermissions.remove(callingUid);
7733                }
7734                if (persistChanged) {
7735                    schedulePersistUriGrants();
7736                }
7737            }
7738            return;
7739        }
7740
7741        boolean persistChanged = false;
7742
7743        // Go through all of the permissions and remove any that match.
7744        int N = mGrantedUriPermissions.size();
7745        for (int i = 0; i < N; i++) {
7746            final int targetUid = mGrantedUriPermissions.keyAt(i);
7747            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7748
7749            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7750                final UriPermission perm = it.next();
7751                if (perm.uri.sourceUserId == grantUri.sourceUserId
7752                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7753                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7754                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7755                    persistChanged |= perm.revokeModes(
7756                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7757                    if (perm.modeFlags == 0) {
7758                        it.remove();
7759                    }
7760                }
7761            }
7762
7763            if (perms.isEmpty()) {
7764                mGrantedUriPermissions.remove(targetUid);
7765                N--;
7766                i--;
7767            }
7768        }
7769
7770        if (persistChanged) {
7771            schedulePersistUriGrants();
7772        }
7773    }
7774
7775    /**
7776     * @param uri This uri must NOT contain an embedded userId.
7777     * @param userId The userId in which the uri is to be resolved.
7778     */
7779    @Override
7780    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7781            int userId) {
7782        enforceNotIsolatedCaller("revokeUriPermission");
7783        synchronized(this) {
7784            final ProcessRecord r = getRecordForAppLocked(caller);
7785            if (r == null) {
7786                throw new SecurityException("Unable to find app for caller "
7787                        + caller
7788                        + " when revoking permission to uri " + uri);
7789            }
7790            if (uri == null) {
7791                Slog.w(TAG, "revokeUriPermission: null uri");
7792                return;
7793            }
7794
7795            if (!Intent.isAccessUriMode(modeFlags)) {
7796                return;
7797            }
7798
7799            final String authority = uri.getAuthority();
7800            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7801            if (pi == null) {
7802                Slog.w(TAG, "No content provider found for permission revoke: "
7803                        + uri.toSafeString());
7804                return;
7805            }
7806
7807            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7808        }
7809    }
7810
7811    /**
7812     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7813     * given package.
7814     *
7815     * @param packageName Package name to match, or {@code null} to apply to all
7816     *            packages.
7817     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7818     *            to all users.
7819     * @param persistable If persistable grants should be removed.
7820     */
7821    private void removeUriPermissionsForPackageLocked(
7822            String packageName, int userHandle, boolean persistable) {
7823        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7824            throw new IllegalArgumentException("Must narrow by either package or user");
7825        }
7826
7827        boolean persistChanged = false;
7828
7829        int N = mGrantedUriPermissions.size();
7830        for (int i = 0; i < N; i++) {
7831            final int targetUid = mGrantedUriPermissions.keyAt(i);
7832            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7833
7834            // Only inspect grants matching user
7835            if (userHandle == UserHandle.USER_ALL
7836                    || userHandle == UserHandle.getUserId(targetUid)) {
7837                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7838                    final UriPermission perm = it.next();
7839
7840                    // Only inspect grants matching package
7841                    if (packageName == null || perm.sourcePkg.equals(packageName)
7842                            || perm.targetPkg.equals(packageName)) {
7843                        persistChanged |= perm.revokeModes(persistable
7844                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7845
7846                        // Only remove when no modes remain; any persisted grants
7847                        // will keep this alive.
7848                        if (perm.modeFlags == 0) {
7849                            it.remove();
7850                        }
7851                    }
7852                }
7853
7854                if (perms.isEmpty()) {
7855                    mGrantedUriPermissions.remove(targetUid);
7856                    N--;
7857                    i--;
7858                }
7859            }
7860        }
7861
7862        if (persistChanged) {
7863            schedulePersistUriGrants();
7864        }
7865    }
7866
7867    @Override
7868    public IBinder newUriPermissionOwner(String name) {
7869        enforceNotIsolatedCaller("newUriPermissionOwner");
7870        synchronized(this) {
7871            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7872            return owner.getExternalTokenLocked();
7873        }
7874    }
7875
7876    /**
7877     * @param uri This uri must NOT contain an embedded userId.
7878     * @param sourceUserId The userId in which the uri is to be resolved.
7879     * @param targetUserId The userId of the app that receives the grant.
7880     */
7881    @Override
7882    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7883            final int modeFlags, int sourceUserId, int targetUserId) {
7884        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7885                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7886        synchronized(this) {
7887            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7888            if (owner == null) {
7889                throw new IllegalArgumentException("Unknown owner: " + token);
7890            }
7891            if (fromUid != Binder.getCallingUid()) {
7892                if (Binder.getCallingUid() != Process.myUid()) {
7893                    // Only system code can grant URI permissions on behalf
7894                    // of other users.
7895                    throw new SecurityException("nice try");
7896                }
7897            }
7898            if (targetPkg == null) {
7899                throw new IllegalArgumentException("null target");
7900            }
7901            if (uri == null) {
7902                throw new IllegalArgumentException("null uri");
7903            }
7904
7905            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7906                    modeFlags, owner, targetUserId);
7907        }
7908    }
7909
7910    /**
7911     * @param uri This uri must NOT contain an embedded userId.
7912     * @param userId The userId in which the uri is to be resolved.
7913     */
7914    @Override
7915    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7916        synchronized(this) {
7917            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7918            if (owner == null) {
7919                throw new IllegalArgumentException("Unknown owner: " + token);
7920            }
7921
7922            if (uri == null) {
7923                owner.removeUriPermissionsLocked(mode);
7924            } else {
7925                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7926            }
7927        }
7928    }
7929
7930    private void schedulePersistUriGrants() {
7931        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7932            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7933                    10 * DateUtils.SECOND_IN_MILLIS);
7934        }
7935    }
7936
7937    private void writeGrantedUriPermissions() {
7938        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
7939
7940        // Snapshot permissions so we can persist without lock
7941        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7942        synchronized (this) {
7943            final int size = mGrantedUriPermissions.size();
7944            for (int i = 0; i < size; i++) {
7945                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7946                for (UriPermission perm : perms.values()) {
7947                    if (perm.persistedModeFlags != 0) {
7948                        persist.add(perm.snapshot());
7949                    }
7950                }
7951            }
7952        }
7953
7954        FileOutputStream fos = null;
7955        try {
7956            fos = mGrantFile.startWrite();
7957
7958            XmlSerializer out = new FastXmlSerializer();
7959            out.setOutput(fos, StandardCharsets.UTF_8.name());
7960            out.startDocument(null, true);
7961            out.startTag(null, TAG_URI_GRANTS);
7962            for (UriPermission.Snapshot perm : persist) {
7963                out.startTag(null, TAG_URI_GRANT);
7964                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7965                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7966                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7967                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7968                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7969                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7970                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7971                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7972                out.endTag(null, TAG_URI_GRANT);
7973            }
7974            out.endTag(null, TAG_URI_GRANTS);
7975            out.endDocument();
7976
7977            mGrantFile.finishWrite(fos);
7978        } catch (IOException e) {
7979            if (fos != null) {
7980                mGrantFile.failWrite(fos);
7981            }
7982        }
7983    }
7984
7985    private void readGrantedUriPermissionsLocked() {
7986        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
7987
7988        final long now = System.currentTimeMillis();
7989
7990        FileInputStream fis = null;
7991        try {
7992            fis = mGrantFile.openRead();
7993            final XmlPullParser in = Xml.newPullParser();
7994            in.setInput(fis, StandardCharsets.UTF_8.name());
7995
7996            int type;
7997            while ((type = in.next()) != END_DOCUMENT) {
7998                final String tag = in.getName();
7999                if (type == START_TAG) {
8000                    if (TAG_URI_GRANT.equals(tag)) {
8001                        final int sourceUserId;
8002                        final int targetUserId;
8003                        final int userHandle = readIntAttribute(in,
8004                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8005                        if (userHandle != UserHandle.USER_NULL) {
8006                            // For backwards compatibility.
8007                            sourceUserId = userHandle;
8008                            targetUserId = userHandle;
8009                        } else {
8010                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8011                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8012                        }
8013                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8014                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8015                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8016                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8017                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8018                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8019
8020                        // Sanity check that provider still belongs to source package
8021                        final ProviderInfo pi = getProviderInfoLocked(
8022                                uri.getAuthority(), sourceUserId);
8023                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8024                            int targetUid = -1;
8025                            try {
8026                                targetUid = AppGlobals.getPackageManager()
8027                                        .getPackageUid(targetPkg, targetUserId);
8028                            } catch (RemoteException e) {
8029                            }
8030                            if (targetUid != -1) {
8031                                final UriPermission perm = findOrCreateUriPermissionLocked(
8032                                        sourcePkg, targetPkg, targetUid,
8033                                        new GrantUri(sourceUserId, uri, prefix));
8034                                perm.initPersistedModes(modeFlags, createdTime);
8035                            }
8036                        } else {
8037                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8038                                    + " but instead found " + pi);
8039                        }
8040                    }
8041                }
8042            }
8043        } catch (FileNotFoundException e) {
8044            // Missing grants is okay
8045        } catch (IOException e) {
8046            Slog.wtf(TAG, "Failed reading Uri grants", e);
8047        } catch (XmlPullParserException e) {
8048            Slog.wtf(TAG, "Failed reading Uri grants", e);
8049        } finally {
8050            IoUtils.closeQuietly(fis);
8051        }
8052    }
8053
8054    /**
8055     * @param uri This uri must NOT contain an embedded userId.
8056     * @param userId The userId in which the uri is to be resolved.
8057     */
8058    @Override
8059    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8060        enforceNotIsolatedCaller("takePersistableUriPermission");
8061
8062        Preconditions.checkFlagsArgument(modeFlags,
8063                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8064
8065        synchronized (this) {
8066            final int callingUid = Binder.getCallingUid();
8067            boolean persistChanged = false;
8068            GrantUri grantUri = new GrantUri(userId, uri, false);
8069
8070            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8071                    new GrantUri(userId, uri, false));
8072            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8073                    new GrantUri(userId, uri, true));
8074
8075            final boolean exactValid = (exactPerm != null)
8076                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8077            final boolean prefixValid = (prefixPerm != null)
8078                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8079
8080            if (!(exactValid || prefixValid)) {
8081                throw new SecurityException("No persistable permission grants found for UID "
8082                        + callingUid + " and Uri " + grantUri.toSafeString());
8083            }
8084
8085            if (exactValid) {
8086                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8087            }
8088            if (prefixValid) {
8089                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8090            }
8091
8092            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8093
8094            if (persistChanged) {
8095                schedulePersistUriGrants();
8096            }
8097        }
8098    }
8099
8100    /**
8101     * @param uri This uri must NOT contain an embedded userId.
8102     * @param userId The userId in which the uri is to be resolved.
8103     */
8104    @Override
8105    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8106        enforceNotIsolatedCaller("releasePersistableUriPermission");
8107
8108        Preconditions.checkFlagsArgument(modeFlags,
8109                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8110
8111        synchronized (this) {
8112            final int callingUid = Binder.getCallingUid();
8113            boolean persistChanged = false;
8114
8115            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8116                    new GrantUri(userId, uri, false));
8117            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8118                    new GrantUri(userId, uri, true));
8119            if (exactPerm == null && prefixPerm == null) {
8120                throw new SecurityException("No permission grants found for UID " + callingUid
8121                        + " and Uri " + uri.toSafeString());
8122            }
8123
8124            if (exactPerm != null) {
8125                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8126                removeUriPermissionIfNeededLocked(exactPerm);
8127            }
8128            if (prefixPerm != null) {
8129                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8130                removeUriPermissionIfNeededLocked(prefixPerm);
8131            }
8132
8133            if (persistChanged) {
8134                schedulePersistUriGrants();
8135            }
8136        }
8137    }
8138
8139    /**
8140     * Prune any older {@link UriPermission} for the given UID until outstanding
8141     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8142     *
8143     * @return if any mutations occured that require persisting.
8144     */
8145    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8146        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8147        if (perms == null) return false;
8148        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8149
8150        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8151        for (UriPermission perm : perms.values()) {
8152            if (perm.persistedModeFlags != 0) {
8153                persisted.add(perm);
8154            }
8155        }
8156
8157        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8158        if (trimCount <= 0) return false;
8159
8160        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8161        for (int i = 0; i < trimCount; i++) {
8162            final UriPermission perm = persisted.get(i);
8163
8164            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8165                    "Trimming grant created at " + perm.persistedCreateTime);
8166
8167            perm.releasePersistableModes(~0);
8168            removeUriPermissionIfNeededLocked(perm);
8169        }
8170
8171        return true;
8172    }
8173
8174    @Override
8175    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8176            String packageName, boolean incoming) {
8177        enforceNotIsolatedCaller("getPersistedUriPermissions");
8178        Preconditions.checkNotNull(packageName, "packageName");
8179
8180        final int callingUid = Binder.getCallingUid();
8181        final IPackageManager pm = AppGlobals.getPackageManager();
8182        try {
8183            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8184            if (packageUid != callingUid) {
8185                throw new SecurityException(
8186                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8187            }
8188        } catch (RemoteException e) {
8189            throw new SecurityException("Failed to verify package name ownership");
8190        }
8191
8192        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8193        synchronized (this) {
8194            if (incoming) {
8195                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8196                        callingUid);
8197                if (perms == null) {
8198                    Slog.w(TAG, "No permission grants found for " + packageName);
8199                } else {
8200                    for (UriPermission perm : perms.values()) {
8201                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8202                            result.add(perm.buildPersistedPublicApiObject());
8203                        }
8204                    }
8205                }
8206            } else {
8207                final int size = mGrantedUriPermissions.size();
8208                for (int i = 0; i < size; i++) {
8209                    final ArrayMap<GrantUri, UriPermission> perms =
8210                            mGrantedUriPermissions.valueAt(i);
8211                    for (UriPermission perm : perms.values()) {
8212                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8213                            result.add(perm.buildPersistedPublicApiObject());
8214                        }
8215                    }
8216                }
8217            }
8218        }
8219        return new ParceledListSlice<android.content.UriPermission>(result);
8220    }
8221
8222    @Override
8223    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8224        synchronized (this) {
8225            ProcessRecord app =
8226                who != null ? getRecordForAppLocked(who) : null;
8227            if (app == null) return;
8228
8229            Message msg = Message.obtain();
8230            msg.what = WAIT_FOR_DEBUGGER_MSG;
8231            msg.obj = app;
8232            msg.arg1 = waiting ? 1 : 0;
8233            mUiHandler.sendMessage(msg);
8234        }
8235    }
8236
8237    @Override
8238    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8239        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8240        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8241        outInfo.availMem = Process.getFreeMemory();
8242        outInfo.totalMem = Process.getTotalMemory();
8243        outInfo.threshold = homeAppMem;
8244        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8245        outInfo.hiddenAppThreshold = cachedAppMem;
8246        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8247                ProcessList.SERVICE_ADJ);
8248        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8249                ProcessList.VISIBLE_APP_ADJ);
8250        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8251                ProcessList.FOREGROUND_APP_ADJ);
8252    }
8253
8254    // =========================================================
8255    // TASK MANAGEMENT
8256    // =========================================================
8257
8258    @Override
8259    public List<IAppTask> getAppTasks(String callingPackage) {
8260        int callingUid = Binder.getCallingUid();
8261        long ident = Binder.clearCallingIdentity();
8262
8263        synchronized(this) {
8264            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8265            try {
8266                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8267
8268                final int N = mRecentTasks.size();
8269                for (int i = 0; i < N; i++) {
8270                    TaskRecord tr = mRecentTasks.get(i);
8271                    // Skip tasks that do not match the caller.  We don't need to verify
8272                    // callingPackage, because we are also limiting to callingUid and know
8273                    // that will limit to the correct security sandbox.
8274                    if (tr.effectiveUid != callingUid) {
8275                        continue;
8276                    }
8277                    Intent intent = tr.getBaseIntent();
8278                    if (intent == null ||
8279                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8280                        continue;
8281                    }
8282                    ActivityManager.RecentTaskInfo taskInfo =
8283                            createRecentTaskInfoFromTaskRecord(tr);
8284                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8285                    list.add(taskImpl);
8286                }
8287            } finally {
8288                Binder.restoreCallingIdentity(ident);
8289            }
8290            return list;
8291        }
8292    }
8293
8294    @Override
8295    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8296        final int callingUid = Binder.getCallingUid();
8297        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8298
8299        synchronized(this) {
8300            if (DEBUG_ALL) Slog.v(
8301                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8302
8303            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8304                    callingUid);
8305
8306            // TODO: Improve with MRU list from all ActivityStacks.
8307            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8308        }
8309
8310        return list;
8311    }
8312
8313    /**
8314     * Creates a new RecentTaskInfo from a TaskRecord.
8315     */
8316    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8317        // Update the task description to reflect any changes in the task stack
8318        tr.updateTaskDescription();
8319
8320        // Compose the recent task info
8321        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8322        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8323        rti.persistentId = tr.taskId;
8324        rti.baseIntent = new Intent(tr.getBaseIntent());
8325        rti.origActivity = tr.origActivity;
8326        rti.description = tr.lastDescription;
8327        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8328        rti.userId = tr.userId;
8329        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8330        rti.firstActiveTime = tr.firstActiveTime;
8331        rti.lastActiveTime = tr.lastActiveTime;
8332        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8333        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8334        rti.numActivities = 0;
8335
8336        ActivityRecord base = null;
8337        ActivityRecord top = null;
8338        ActivityRecord tmp;
8339
8340        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8341            tmp = tr.mActivities.get(i);
8342            if (tmp.finishing) {
8343                continue;
8344            }
8345            base = tmp;
8346            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8347                top = base;
8348            }
8349            rti.numActivities++;
8350        }
8351
8352        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8353        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8354
8355        return rti;
8356    }
8357
8358    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8359        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8360                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8361        if (!allowed) {
8362            if (checkPermission(android.Manifest.permission.GET_TASKS,
8363                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8364                // Temporary compatibility: some existing apps on the system image may
8365                // still be requesting the old permission and not switched to the new
8366                // one; if so, we'll still allow them full access.  This means we need
8367                // to see if they are holding the old permission and are a system app.
8368                try {
8369                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8370                        allowed = true;
8371                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8372                                + " is using old GET_TASKS but privileged; allowing");
8373                    }
8374                } catch (RemoteException e) {
8375                }
8376            }
8377        }
8378        if (!allowed) {
8379            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8380                    + " does not hold REAL_GET_TASKS; limiting output");
8381        }
8382        return allowed;
8383    }
8384
8385    @Override
8386    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8387        final int callingUid = Binder.getCallingUid();
8388        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8389                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8390
8391        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8392        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8393        synchronized (this) {
8394            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8395                    callingUid);
8396            final boolean detailed = checkCallingPermission(
8397                    android.Manifest.permission.GET_DETAILED_TASKS)
8398                    == PackageManager.PERMISSION_GRANTED;
8399
8400            final int recentsCount = mRecentTasks.size();
8401            ArrayList<ActivityManager.RecentTaskInfo> res =
8402                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8403
8404            final Set<Integer> includedUsers;
8405            if (includeProfiles) {
8406                includedUsers = getProfileIdsLocked(userId);
8407            } else {
8408                includedUsers = new HashSet<>();
8409            }
8410            includedUsers.add(Integer.valueOf(userId));
8411
8412            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8413                TaskRecord tr = mRecentTasks.get(i);
8414                // Only add calling user or related users recent tasks
8415                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8416                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8417                    continue;
8418                }
8419
8420                // Return the entry if desired by the caller.  We always return
8421                // the first entry, because callers always expect this to be the
8422                // foreground app.  We may filter others if the caller has
8423                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8424                // we should exclude the entry.
8425
8426                if (i == 0
8427                        || withExcluded
8428                        || (tr.intent == null)
8429                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8430                                == 0)) {
8431                    if (!allowed) {
8432                        // If the caller doesn't have the GET_TASKS permission, then only
8433                        // allow them to see a small subset of tasks -- their own and home.
8434                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8435                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8436                            continue;
8437                        }
8438                    }
8439                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8440                        if (tr.stack != null && tr.stack.isHomeStack()) {
8441                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8442                                    "Skipping, home stack task: " + tr);
8443                            continue;
8444                        }
8445                    }
8446                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8447                        // Don't include auto remove tasks that are finished or finishing.
8448                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8449                                "Skipping, auto-remove without activity: " + tr);
8450                        continue;
8451                    }
8452                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8453                            && !tr.isAvailable) {
8454                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8455                                "Skipping, unavail real act: " + tr);
8456                        continue;
8457                    }
8458
8459                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8460                    if (!detailed) {
8461                        rti.baseIntent.replaceExtras((Bundle)null);
8462                    }
8463
8464                    res.add(rti);
8465                    maxNum--;
8466                }
8467            }
8468            return res;
8469        }
8470    }
8471
8472    @Override
8473    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8474        synchronized (this) {
8475            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8476                    "getTaskThumbnail()");
8477            TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id, false);
8478            if (tr != null) {
8479                return tr.getTaskThumbnailLocked();
8480            }
8481        }
8482        return null;
8483    }
8484
8485    @Override
8486    public int addAppTask(IBinder activityToken, Intent intent,
8487            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8488        final int callingUid = Binder.getCallingUid();
8489        final long callingIdent = Binder.clearCallingIdentity();
8490
8491        try {
8492            synchronized (this) {
8493                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8494                if (r == null) {
8495                    throw new IllegalArgumentException("Activity does not exist; token="
8496                            + activityToken);
8497                }
8498                ComponentName comp = intent.getComponent();
8499                if (comp == null) {
8500                    throw new IllegalArgumentException("Intent " + intent
8501                            + " must specify explicit component");
8502                }
8503                if (thumbnail.getWidth() != mThumbnailWidth
8504                        || thumbnail.getHeight() != mThumbnailHeight) {
8505                    throw new IllegalArgumentException("Bad thumbnail size: got "
8506                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8507                            + mThumbnailWidth + "x" + mThumbnailHeight);
8508                }
8509                if (intent.getSelector() != null) {
8510                    intent.setSelector(null);
8511                }
8512                if (intent.getSourceBounds() != null) {
8513                    intent.setSourceBounds(null);
8514                }
8515                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8516                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8517                        // The caller has added this as an auto-remove task...  that makes no
8518                        // sense, so turn off auto-remove.
8519                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8520                    }
8521                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8522                    // Must be a new task.
8523                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8524                }
8525                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8526                    mLastAddedTaskActivity = null;
8527                }
8528                ActivityInfo ainfo = mLastAddedTaskActivity;
8529                if (ainfo == null) {
8530                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8531                            comp, 0, UserHandle.getUserId(callingUid));
8532                    if (ainfo.applicationInfo.uid != callingUid) {
8533                        throw new SecurityException(
8534                                "Can't add task for another application: target uid="
8535                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8536                    }
8537                }
8538
8539                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8540                        intent, description);
8541
8542                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
8543                if (trimIdx >= 0) {
8544                    // If this would have caused a trim, then we'll abort because that
8545                    // means it would be added at the end of the list but then just removed.
8546                    return INVALID_TASK_ID;
8547                }
8548
8549                final int N = mRecentTasks.size();
8550                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8551                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8552                    tr.removedFromRecents();
8553                }
8554
8555                task.inRecents = true;
8556                mRecentTasks.add(task);
8557                r.task.stack.addTask(task, false, false);
8558
8559                task.setLastThumbnail(thumbnail);
8560                task.freeLastThumbnail();
8561
8562                return task.taskId;
8563            }
8564        } finally {
8565            Binder.restoreCallingIdentity(callingIdent);
8566        }
8567    }
8568
8569    @Override
8570    public Point getAppTaskThumbnailSize() {
8571        synchronized (this) {
8572            return new Point(mThumbnailWidth,  mThumbnailHeight);
8573        }
8574    }
8575
8576    @Override
8577    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8578        synchronized (this) {
8579            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8580            if (r != null) {
8581                r.setTaskDescription(td);
8582                r.task.updateTaskDescription();
8583            }
8584        }
8585    }
8586
8587    @Override
8588    public void setTaskResizeable(int taskId, boolean resizeable) {
8589        synchronized (this) {
8590            TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8591            if (task == null) {
8592                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
8593                return;
8594            }
8595            if (task.mResizeable != resizeable) {
8596                task.mResizeable = resizeable;
8597                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8598                mStackSupervisor.resumeTopActivitiesLocked();
8599            }
8600        }
8601    }
8602
8603    @Override
8604    public void resizeTask(int taskId, Rect bounds) {
8605        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8606                "resizeTask()");
8607        long ident = Binder.clearCallingIdentity();
8608        try {
8609            synchronized (this) {
8610                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8611                if (task == null) {
8612                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
8613                    return;
8614                }
8615                mStackSupervisor.resizeTaskLocked(task, bounds);
8616            }
8617        } finally {
8618            Binder.restoreCallingIdentity(ident);
8619        }
8620    }
8621
8622    @Override
8623    public Bitmap getTaskDescriptionIcon(String filename) {
8624        if (!FileUtils.isValidExtFilename(filename)
8625                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8626            throw new IllegalArgumentException("Bad filename: " + filename);
8627        }
8628        return mTaskPersister.getTaskDescriptionIcon(filename);
8629    }
8630
8631    @Override
8632    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8633            throws RemoteException {
8634        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8635                opts.getCustomInPlaceResId() == 0) {
8636            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8637                    "with valid animation");
8638        }
8639        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8640        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8641                opts.getCustomInPlaceResId());
8642        mWindowManager.executeAppTransition();
8643    }
8644
8645    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8646        mRecentTasks.remove(tr);
8647        tr.removedFromRecents();
8648        ComponentName component = tr.getBaseIntent().getComponent();
8649        if (component == null) {
8650            Slog.w(TAG, "No component for base intent of task: " + tr);
8651            return;
8652        }
8653
8654        // Find any running services associated with this app and stop if needed.
8655        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8656
8657        if (!killProcess) {
8658            return;
8659        }
8660
8661        // Determine if the process(es) for this task should be killed.
8662        final String pkg = component.getPackageName();
8663        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
8664        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8665        for (int i = 0; i < pmap.size(); i++) {
8666
8667            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8668            for (int j = 0; j < uids.size(); j++) {
8669                ProcessRecord proc = uids.valueAt(j);
8670                if (proc.userId != tr.userId) {
8671                    // Don't kill process for a different user.
8672                    continue;
8673                }
8674                if (proc == mHomeProcess) {
8675                    // Don't kill the home process along with tasks from the same package.
8676                    continue;
8677                }
8678                if (!proc.pkgList.containsKey(pkg)) {
8679                    // Don't kill process that is not associated with this task.
8680                    continue;
8681                }
8682
8683                for (int k = 0; k < proc.activities.size(); k++) {
8684                    TaskRecord otherTask = proc.activities.get(k).task;
8685                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8686                        // Don't kill process(es) that has an activity in a different task that is
8687                        // also in recents.
8688                        return;
8689                    }
8690                }
8691
8692                if (proc.foregroundServices) {
8693                    // Don't kill process(es) with foreground service.
8694                    return;
8695                }
8696
8697                // Add process to kill list.
8698                procsToKill.add(proc);
8699            }
8700        }
8701
8702        // Kill the running processes.
8703        for (int i = 0; i < procsToKill.size(); i++) {
8704            ProcessRecord pr = procsToKill.get(i);
8705            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
8706                    && pr.curReceiver == null) {
8707                pr.kill("remove task", true);
8708            } else {
8709                // We delay killing processes that are not in the background or running a receiver.
8710                pr.waitingToKill = "remove task";
8711            }
8712        }
8713    }
8714
8715    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8716        // Remove all tasks with activities in the specified package from the list of recent tasks
8717        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8718            TaskRecord tr = mRecentTasks.get(i);
8719            if (tr.userId != userId) continue;
8720
8721            ComponentName cn = tr.intent.getComponent();
8722            if (cn != null && cn.getPackageName().equals(packageName)) {
8723                // If the package name matches, remove the task.
8724                removeTaskByIdLocked(tr.taskId, true);
8725            }
8726        }
8727    }
8728
8729    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
8730            int userId) {
8731
8732        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8733            TaskRecord tr = mRecentTasks.get(i);
8734            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
8735                continue;
8736            }
8737
8738            ComponentName cn = tr.intent.getComponent();
8739            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
8740                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
8741            if (sameComponent) {
8742                removeTaskByIdLocked(tr.taskId, false);
8743            }
8744        }
8745    }
8746
8747    /**
8748     * Removes the task with the specified task id.
8749     *
8750     * @param taskId Identifier of the task to be removed.
8751     * @param killProcess Kill any process associated with the task if possible.
8752     * @return Returns true if the given task was found and removed.
8753     */
8754    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8755        TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8756        if (tr != null) {
8757            tr.removeTaskActivitiesLocked();
8758            cleanUpRemovedTaskLocked(tr, killProcess);
8759            if (tr.isPersistable) {
8760                notifyTaskPersisterLocked(null, true);
8761            }
8762            return true;
8763        }
8764        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8765        return false;
8766    }
8767
8768    @Override
8769    public boolean removeTask(int taskId) {
8770        synchronized (this) {
8771            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8772                    "removeTask()");
8773            long ident = Binder.clearCallingIdentity();
8774            try {
8775                return removeTaskByIdLocked(taskId, true);
8776            } finally {
8777                Binder.restoreCallingIdentity(ident);
8778            }
8779        }
8780    }
8781
8782    /**
8783     * TODO: Add mController hook
8784     */
8785    @Override
8786    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8787        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
8788
8789        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
8790        synchronized(this) {
8791            moveTaskToFrontLocked(taskId, flags, options);
8792        }
8793    }
8794
8795    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8796        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8797                Binder.getCallingUid(), -1, -1, "Task to front")) {
8798            ActivityOptions.abort(options);
8799            return;
8800        }
8801        final long origId = Binder.clearCallingIdentity();
8802        try {
8803            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8804            if (task == null) {
8805                Slog.d(TAG, "Could not find task for id: "+ taskId);
8806                return;
8807            }
8808            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8809                mStackSupervisor.showLockTaskToast();
8810                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8811                return;
8812            }
8813            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8814            if (prev != null && prev.isRecentsActivity()) {
8815                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8816            }
8817            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
8818        } finally {
8819            Binder.restoreCallingIdentity(origId);
8820        }
8821        ActivityOptions.abort(options);
8822    }
8823
8824    /**
8825     * Moves an activity, and all of the other activities within the same task, to the bottom
8826     * of the history stack.  The activity's order within the task is unchanged.
8827     *
8828     * @param token A reference to the activity we wish to move
8829     * @param nonRoot If false then this only works if the activity is the root
8830     *                of a task; if true it will work for any activity in a task.
8831     * @return Returns true if the move completed, false if not.
8832     */
8833    @Override
8834    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8835        enforceNotIsolatedCaller("moveActivityTaskToBack");
8836        synchronized(this) {
8837            final long origId = Binder.clearCallingIdentity();
8838            try {
8839                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8840                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8841                if (task != null) {
8842                    if (mStackSupervisor.isLockedTask(task)) {
8843                        mStackSupervisor.showLockTaskToast();
8844                        return false;
8845                    }
8846                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
8847                }
8848            } finally {
8849                Binder.restoreCallingIdentity(origId);
8850            }
8851        }
8852        return false;
8853    }
8854
8855    @Override
8856    public void moveTaskBackwards(int task) {
8857        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8858                "moveTaskBackwards()");
8859
8860        synchronized(this) {
8861            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8862                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8863                return;
8864            }
8865            final long origId = Binder.clearCallingIdentity();
8866            moveTaskBackwardsLocked(task);
8867            Binder.restoreCallingIdentity(origId);
8868        }
8869    }
8870
8871    private final void moveTaskBackwardsLocked(int task) {
8872        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8873    }
8874
8875    @Override
8876    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
8877            IActivityContainerCallback callback) throws RemoteException {
8878        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8879                "createActivityContainer()");
8880        synchronized (this) {
8881            if (parentActivityToken == null) {
8882                throw new IllegalArgumentException("parent token must not be null");
8883            }
8884            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
8885            if (r == null) {
8886                return null;
8887            }
8888            if (callback == null) {
8889                throw new IllegalArgumentException("callback must not be null");
8890            }
8891            return mStackSupervisor.createVirtualActivityContainer(r, callback);
8892        }
8893    }
8894
8895    @Override
8896    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8897        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8898                "deleteActivityContainer()");
8899        synchronized (this) {
8900            mStackSupervisor.deleteActivityContainer(container);
8901        }
8902    }
8903
8904    @Override
8905    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
8906        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8907                "createStackOnDisplay()");
8908        synchronized (this) {
8909            final int stackId = mStackSupervisor.getNextStackId();
8910            final ActivityStack stack = mStackSupervisor.createStackOnDisplay(stackId, displayId);
8911            if (stack == null) {
8912                return null;
8913            }
8914            return stack.mActivityContainer;
8915        }
8916    }
8917
8918    @Override
8919    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
8920        synchronized (this) {
8921            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8922            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
8923                return stack.mActivityContainer.getDisplayId();
8924            }
8925            return Display.DEFAULT_DISPLAY;
8926        }
8927    }
8928
8929    @Override
8930    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8931        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8932                "moveTaskToStack()");
8933        if (stackId == HOME_STACK_ID) {
8934            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8935                    new RuntimeException("here").fillInStackTrace());
8936        }
8937        synchronized (this) {
8938            long ident = Binder.clearCallingIdentity();
8939            try {
8940                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
8941                        + " to stackId=" + stackId + " toTop=" + toTop);
8942                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop);
8943            } finally {
8944                Binder.restoreCallingIdentity(ident);
8945            }
8946        }
8947    }
8948
8949    @Override
8950    public void resizeStack(int stackId, Rect bounds) {
8951        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8952                "resizeStack()");
8953        long ident = Binder.clearCallingIdentity();
8954        try {
8955            synchronized (this) {
8956                mStackSupervisor.resizeStackLocked(stackId, bounds);
8957            }
8958        } finally {
8959            Binder.restoreCallingIdentity(ident);
8960        }
8961    }
8962
8963    @Override
8964    public List<StackInfo> getAllStackInfos() {
8965        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8966                "getAllStackInfos()");
8967        long ident = Binder.clearCallingIdentity();
8968        try {
8969            synchronized (this) {
8970                return mStackSupervisor.getAllStackInfosLocked();
8971            }
8972        } finally {
8973            Binder.restoreCallingIdentity(ident);
8974        }
8975    }
8976
8977    @Override
8978    public StackInfo getStackInfo(int stackId) {
8979        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8980                "getStackInfo()");
8981        long ident = Binder.clearCallingIdentity();
8982        try {
8983            synchronized (this) {
8984                return mStackSupervisor.getStackInfoLocked(stackId);
8985            }
8986        } finally {
8987            Binder.restoreCallingIdentity(ident);
8988        }
8989    }
8990
8991    @Override
8992    public boolean isInHomeStack(int taskId) {
8993        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8994                "getStackInfo()");
8995        long ident = Binder.clearCallingIdentity();
8996        try {
8997            synchronized (this) {
8998                TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8999                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9000            }
9001        } finally {
9002            Binder.restoreCallingIdentity(ident);
9003        }
9004    }
9005
9006    @Override
9007    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9008        synchronized(this) {
9009            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9010        }
9011    }
9012
9013    @Override
9014    public void updateDeviceOwner(String packageName) {
9015        final int callingUid = Binder.getCallingUid();
9016        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9017            throw new SecurityException("updateDeviceOwner called from non-system process");
9018        }
9019        synchronized (this) {
9020            mDeviceOwnerName = packageName;
9021        }
9022    }
9023
9024    @Override
9025    public void updateLockTaskPackages(int userId, String[] packages) {
9026        final int callingUid = Binder.getCallingUid();
9027        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9028            throw new SecurityException("updateLockTaskPackage called from non-system process");
9029        }
9030        synchronized (this) {
9031            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9032                    Arrays.toString(packages));
9033            mLockTaskPackages.put(userId, packages);
9034            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9035        }
9036    }
9037
9038
9039    void startLockTaskModeLocked(TaskRecord task) {
9040        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9041        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9042            return;
9043        }
9044
9045        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9046        // is initiated by system after the pinning request was shown and locked mode is initiated
9047        // by an authorized app directly
9048        final int callingUid = Binder.getCallingUid();
9049        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9050        long ident = Binder.clearCallingIdentity();
9051        try {
9052            final ActivityStack stack = mStackSupervisor.getFocusedStack();
9053            if (!isSystemInitiated) {
9054                task.mLockTaskUid = callingUid;
9055                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9056                    // startLockTask() called by app and task mode is lockTaskModeDefault.
9057                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9058                    StatusBarManagerInternal statusBarManager =
9059                            LocalServices.getService(StatusBarManagerInternal.class);
9060                    if (statusBarManager != null) {
9061                        statusBarManager.showScreenPinningRequest();
9062                    }
9063                    return;
9064                }
9065
9066                if (stack == null || task != stack.topTask()) {
9067                    throw new IllegalArgumentException("Invalid task, not in foreground");
9068                }
9069            }
9070            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9071                    "Locking fully");
9072            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9073                    ActivityManager.LOCK_TASK_MODE_PINNED :
9074                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9075                    "startLockTask", true);
9076        } finally {
9077            Binder.restoreCallingIdentity(ident);
9078        }
9079    }
9080
9081    @Override
9082    public void startLockTaskMode(int taskId) {
9083        synchronized (this) {
9084            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9085            if (task != null) {
9086                startLockTaskModeLocked(task);
9087            }
9088        }
9089    }
9090
9091    @Override
9092    public void startLockTaskMode(IBinder token) {
9093        synchronized (this) {
9094            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9095            if (r == null) {
9096                return;
9097            }
9098            final TaskRecord task = r.task;
9099            if (task != null) {
9100                startLockTaskModeLocked(task);
9101            }
9102        }
9103    }
9104
9105    @Override
9106    public void startLockTaskModeOnCurrent() throws RemoteException {
9107        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9108                "startLockTaskModeOnCurrent");
9109        long ident = Binder.clearCallingIdentity();
9110        try {
9111            synchronized (this) {
9112                ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9113                if (r != null) {
9114                    startLockTaskModeLocked(r.task);
9115                }
9116            }
9117        } finally {
9118            Binder.restoreCallingIdentity(ident);
9119        }
9120    }
9121
9122    @Override
9123    public void stopLockTaskMode() {
9124        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9125        if (lockTask == null) {
9126            // Our work here is done.
9127            return;
9128        }
9129
9130        final int callingUid = Binder.getCallingUid();
9131        final int lockTaskUid = lockTask.mLockTaskUid;
9132        // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9133        // It is possible lockTaskMode was started by the system process because
9134        // android:lockTaskMode is set to a locking value in the application manifest instead of
9135        // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9136        // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9137        if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9138                callingUid != lockTaskUid
9139                && (lockTaskUid != 0
9140                    || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9141            throw new SecurityException("Invalid uid, expected " + lockTaskUid
9142                    + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9143        }
9144
9145        long ident = Binder.clearCallingIdentity();
9146        try {
9147            Log.d(TAG, "stopLockTaskMode");
9148            // Stop lock task
9149            synchronized (this) {
9150                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9151                        "stopLockTask", true);
9152            }
9153        } finally {
9154            Binder.restoreCallingIdentity(ident);
9155        }
9156    }
9157
9158    @Override
9159    public void stopLockTaskModeOnCurrent() throws RemoteException {
9160        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9161                "stopLockTaskModeOnCurrent");
9162        long ident = Binder.clearCallingIdentity();
9163        try {
9164            stopLockTaskMode();
9165        } finally {
9166            Binder.restoreCallingIdentity(ident);
9167        }
9168    }
9169
9170    @Override
9171    public boolean isInLockTaskMode() {
9172        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9173    }
9174
9175    @Override
9176    public int getLockTaskModeState() {
9177        synchronized (this) {
9178            return mStackSupervisor.getLockTaskModeState();
9179        }
9180    }
9181
9182    @Override
9183    public void showLockTaskEscapeMessage(IBinder token) {
9184        synchronized (this) {
9185            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9186            if (r == null) {
9187                return;
9188            }
9189            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9190        }
9191    }
9192
9193    // =========================================================
9194    // CONTENT PROVIDERS
9195    // =========================================================
9196
9197    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9198        List<ProviderInfo> providers = null;
9199        try {
9200            ParceledListSlice<ProviderInfo> slice = AppGlobals.getPackageManager().
9201                queryContentProviders(app.processName, app.uid,
9202                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
9203            providers = slice != null ? slice.getList() : null;
9204        } catch (RemoteException ex) {
9205        }
9206        if (DEBUG_MU) Slog.v(TAG_MU,
9207                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9208        int userId = app.userId;
9209        if (providers != null) {
9210            int N = providers.size();
9211            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9212            for (int i=0; i<N; i++) {
9213                ProviderInfo cpi =
9214                    (ProviderInfo)providers.get(i);
9215                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9216                        cpi.name, cpi.flags);
9217                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_OWNER) {
9218                    // This is a singleton provider, but a user besides the
9219                    // default user is asking to initialize a process it runs
9220                    // in...  well, no, it doesn't actually run in this process,
9221                    // it runs in the process of the default user.  Get rid of it.
9222                    providers.remove(i);
9223                    N--;
9224                    i--;
9225                    continue;
9226                }
9227
9228                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9229                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9230                if (cpr == null) {
9231                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9232                    mProviderMap.putProviderByClass(comp, cpr);
9233                }
9234                if (DEBUG_MU) Slog.v(TAG_MU,
9235                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9236                app.pubProviders.put(cpi.name, cpr);
9237                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9238                    // Don't add this if it is a platform component that is marked
9239                    // to run in multiple processes, because this is actually
9240                    // part of the framework so doesn't make sense to track as a
9241                    // separate apk in the process.
9242                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9243                            mProcessStats);
9244                }
9245                ensurePackageDexOpt(cpi.applicationInfo.packageName);
9246            }
9247        }
9248        return providers;
9249    }
9250
9251    /**
9252     * Check if {@link ProcessRecord} has a possible chance at accessing the
9253     * given {@link ProviderInfo}. Final permission checking is always done
9254     * in {@link ContentProvider}.
9255     */
9256    private final String checkContentProviderPermissionLocked(
9257            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9258        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9259        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9260        boolean checkedGrants = false;
9261        if (checkUser) {
9262            // Looking for cross-user grants before enforcing the typical cross-users permissions
9263            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
9264            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9265                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9266                    return null;
9267                }
9268                checkedGrants = true;
9269            }
9270            userId = handleIncomingUser(callingPid, callingUid, userId,
9271                    false, ALLOW_NON_FULL,
9272                    "checkContentProviderPermissionLocked " + cpi.authority, null);
9273            if (userId != tmpTargetUserId) {
9274                // When we actually went to determine the final targer user ID, this ended
9275                // up different than our initial check for the authority.  This is because
9276                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9277                // SELF.  So we need to re-check the grants again.
9278                checkedGrants = false;
9279            }
9280        }
9281        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9282                cpi.applicationInfo.uid, cpi.exported)
9283                == PackageManager.PERMISSION_GRANTED) {
9284            return null;
9285        }
9286        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9287                cpi.applicationInfo.uid, cpi.exported)
9288                == PackageManager.PERMISSION_GRANTED) {
9289            return null;
9290        }
9291
9292        PathPermission[] pps = cpi.pathPermissions;
9293        if (pps != null) {
9294            int i = pps.length;
9295            while (i > 0) {
9296                i--;
9297                PathPermission pp = pps[i];
9298                String pprperm = pp.getReadPermission();
9299                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9300                        cpi.applicationInfo.uid, cpi.exported)
9301                        == PackageManager.PERMISSION_GRANTED) {
9302                    return null;
9303                }
9304                String ppwperm = pp.getWritePermission();
9305                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9306                        cpi.applicationInfo.uid, cpi.exported)
9307                        == PackageManager.PERMISSION_GRANTED) {
9308                    return null;
9309                }
9310            }
9311        }
9312        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9313            return null;
9314        }
9315
9316        String msg;
9317        if (!cpi.exported) {
9318            msg = "Permission Denial: opening provider " + cpi.name
9319                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9320                    + ", uid=" + callingUid + ") that is not exported from uid "
9321                    + cpi.applicationInfo.uid;
9322        } else {
9323            msg = "Permission Denial: opening provider " + cpi.name
9324                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9325                    + ", uid=" + callingUid + ") requires "
9326                    + cpi.readPermission + " or " + cpi.writePermission;
9327        }
9328        Slog.w(TAG, msg);
9329        return msg;
9330    }
9331
9332    /**
9333     * Returns if the ContentProvider has granted a uri to callingUid
9334     */
9335    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9336        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9337        if (perms != null) {
9338            for (int i=perms.size()-1; i>=0; i--) {
9339                GrantUri grantUri = perms.keyAt(i);
9340                if (grantUri.sourceUserId == userId || !checkUser) {
9341                    if (matchesProvider(grantUri.uri, cpi)) {
9342                        return true;
9343                    }
9344                }
9345            }
9346        }
9347        return false;
9348    }
9349
9350    /**
9351     * Returns true if the uri authority is one of the authorities specified in the provider.
9352     */
9353    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9354        String uriAuth = uri.getAuthority();
9355        String cpiAuth = cpi.authority;
9356        if (cpiAuth.indexOf(';') == -1) {
9357            return cpiAuth.equals(uriAuth);
9358        }
9359        String[] cpiAuths = cpiAuth.split(";");
9360        int length = cpiAuths.length;
9361        for (int i = 0; i < length; i++) {
9362            if (cpiAuths[i].equals(uriAuth)) return true;
9363        }
9364        return false;
9365    }
9366
9367    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9368            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9369        if (r != null) {
9370            for (int i=0; i<r.conProviders.size(); i++) {
9371                ContentProviderConnection conn = r.conProviders.get(i);
9372                if (conn.provider == cpr) {
9373                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9374                            "Adding provider requested by "
9375                            + r.processName + " from process "
9376                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9377                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9378                    if (stable) {
9379                        conn.stableCount++;
9380                        conn.numStableIncs++;
9381                    } else {
9382                        conn.unstableCount++;
9383                        conn.numUnstableIncs++;
9384                    }
9385                    return conn;
9386                }
9387            }
9388            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9389            if (stable) {
9390                conn.stableCount = 1;
9391                conn.numStableIncs = 1;
9392            } else {
9393                conn.unstableCount = 1;
9394                conn.numUnstableIncs = 1;
9395            }
9396            cpr.connections.add(conn);
9397            r.conProviders.add(conn);
9398            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9399            return conn;
9400        }
9401        cpr.addExternalProcessHandleLocked(externalProcessToken);
9402        return null;
9403    }
9404
9405    boolean decProviderCountLocked(ContentProviderConnection conn,
9406            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9407        if (conn != null) {
9408            cpr = conn.provider;
9409            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9410                    "Removing provider requested by "
9411                    + conn.client.processName + " from process "
9412                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9413                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9414            if (stable) {
9415                conn.stableCount--;
9416            } else {
9417                conn.unstableCount--;
9418            }
9419            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9420                cpr.connections.remove(conn);
9421                conn.client.conProviders.remove(conn);
9422                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9423                return true;
9424            }
9425            return false;
9426        }
9427        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9428        return false;
9429    }
9430
9431    private void checkTime(long startTime, String where) {
9432        long now = SystemClock.elapsedRealtime();
9433        if ((now-startTime) > 1000) {
9434            // If we are taking more than a second, log about it.
9435            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9436        }
9437    }
9438
9439    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9440            String name, IBinder token, boolean stable, int userId) {
9441        ContentProviderRecord cpr;
9442        ContentProviderConnection conn = null;
9443        ProviderInfo cpi = null;
9444
9445        synchronized(this) {
9446            long startTime = SystemClock.elapsedRealtime();
9447
9448            ProcessRecord r = null;
9449            if (caller != null) {
9450                r = getRecordForAppLocked(caller);
9451                if (r == null) {
9452                    throw new SecurityException(
9453                            "Unable to find app for caller " + caller
9454                          + " (pid=" + Binder.getCallingPid()
9455                          + ") when getting content provider " + name);
9456                }
9457            }
9458
9459            boolean checkCrossUser = true;
9460
9461            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9462
9463            // First check if this content provider has been published...
9464            cpr = mProviderMap.getProviderByName(name, userId);
9465            // If that didn't work, check if it exists for user 0 and then
9466            // verify that it's a singleton provider before using it.
9467            if (cpr == null && userId != UserHandle.USER_OWNER) {
9468                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9469                if (cpr != null) {
9470                    cpi = cpr.info;
9471                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9472                            cpi.name, cpi.flags)
9473                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9474                        userId = UserHandle.USER_OWNER;
9475                        checkCrossUser = false;
9476                    } else {
9477                        cpr = null;
9478                        cpi = null;
9479                    }
9480                }
9481            }
9482
9483            boolean providerRunning = cpr != null;
9484            if (providerRunning) {
9485                cpi = cpr.info;
9486                String msg;
9487                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9488                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9489                        != null) {
9490                    throw new SecurityException(msg);
9491                }
9492                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9493
9494                if (r != null && cpr.canRunHere(r)) {
9495                    // This provider has been published or is in the process
9496                    // of being published...  but it is also allowed to run
9497                    // in the caller's process, so don't make a connection
9498                    // and just let the caller instantiate its own instance.
9499                    ContentProviderHolder holder = cpr.newHolder(null);
9500                    // don't give caller the provider object, it needs
9501                    // to make its own.
9502                    holder.provider = null;
9503                    return holder;
9504                }
9505
9506                final long origId = Binder.clearCallingIdentity();
9507
9508                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9509
9510                // In this case the provider instance already exists, so we can
9511                // return it right away.
9512                conn = incProviderCountLocked(r, cpr, token, stable);
9513                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9514                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9515                        // If this is a perceptible app accessing the provider,
9516                        // make sure to count it as being accessed and thus
9517                        // back up on the LRU list.  This is good because
9518                        // content providers are often expensive to start.
9519                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9520                        updateLruProcessLocked(cpr.proc, false, null);
9521                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9522                    }
9523                }
9524
9525                if (cpr.proc != null) {
9526                    if (false) {
9527                        if (cpr.name.flattenToShortString().equals(
9528                                "com.android.providers.calendar/.CalendarProvider2")) {
9529                            Slog.v(TAG, "****************** KILLING "
9530                                + cpr.name.flattenToShortString());
9531                            Process.killProcess(cpr.proc.pid);
9532                        }
9533                    }
9534                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9535                    boolean success = updateOomAdjLocked(cpr.proc);
9536                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
9537                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9538                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
9539                    // NOTE: there is still a race here where a signal could be
9540                    // pending on the process even though we managed to update its
9541                    // adj level.  Not sure what to do about this, but at least
9542                    // the race is now smaller.
9543                    if (!success) {
9544                        // Uh oh...  it looks like the provider's process
9545                        // has been killed on us.  We need to wait for a new
9546                        // process to be started, and make sure its death
9547                        // doesn't kill our process.
9548                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
9549                                + " is crashing; detaching " + r);
9550                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9551                        checkTime(startTime, "getContentProviderImpl: before appDied");
9552                        appDiedLocked(cpr.proc);
9553                        checkTime(startTime, "getContentProviderImpl: after appDied");
9554                        if (!lastRef) {
9555                            // This wasn't the last ref our process had on
9556                            // the provider...  we have now been killed, bail.
9557                            return null;
9558                        }
9559                        providerRunning = false;
9560                        conn = null;
9561                    }
9562                }
9563
9564                Binder.restoreCallingIdentity(origId);
9565            }
9566
9567            boolean singleton;
9568            if (!providerRunning) {
9569                try {
9570                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9571                    cpi = AppGlobals.getPackageManager().
9572                        resolveContentProvider(name,
9573                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9574                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9575                } catch (RemoteException ex) {
9576                }
9577                if (cpi == null) {
9578                    return null;
9579                }
9580                // If the provider is a singleton AND
9581                // (it's a call within the same user || the provider is a
9582                // privileged app)
9583                // Then allow connecting to the singleton provider
9584                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9585                        cpi.name, cpi.flags)
9586                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9587                if (singleton) {
9588                    userId = UserHandle.USER_OWNER;
9589                }
9590                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9591                checkTime(startTime, "getContentProviderImpl: got app info for user");
9592
9593                String msg;
9594                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9595                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9596                        != null) {
9597                    throw new SecurityException(msg);
9598                }
9599                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9600
9601                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9602                        && !cpi.processName.equals("system")) {
9603                    // If this content provider does not run in the system
9604                    // process, and the system is not yet ready to run other
9605                    // processes, then fail fast instead of hanging.
9606                    throw new IllegalArgumentException(
9607                            "Attempt to launch content provider before system ready");
9608                }
9609
9610                // Make sure that the user who owns this provider is running.  If not,
9611                // we don't want to allow it to run.
9612                if (!isUserRunningLocked(userId, false)) {
9613                    Slog.w(TAG, "Unable to launch app "
9614                            + cpi.applicationInfo.packageName + "/"
9615                            + cpi.applicationInfo.uid + " for provider "
9616                            + name + ": user " + userId + " is stopped");
9617                    return null;
9618                }
9619
9620                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9621                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9622                cpr = mProviderMap.getProviderByClass(comp, userId);
9623                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9624                final boolean firstClass = cpr == null;
9625                if (firstClass) {
9626                    final long ident = Binder.clearCallingIdentity();
9627                    try {
9628                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9629                        ApplicationInfo ai =
9630                            AppGlobals.getPackageManager().
9631                                getApplicationInfo(
9632                                        cpi.applicationInfo.packageName,
9633                                        STOCK_PM_FLAGS, userId);
9634                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9635                        if (ai == null) {
9636                            Slog.w(TAG, "No package info for content provider "
9637                                    + cpi.name);
9638                            return null;
9639                        }
9640                        ai = getAppInfoForUser(ai, userId);
9641                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9642                    } catch (RemoteException ex) {
9643                        // pm is in same process, this will never happen.
9644                    } finally {
9645                        Binder.restoreCallingIdentity(ident);
9646                    }
9647                }
9648
9649                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9650
9651                if (r != null && cpr.canRunHere(r)) {
9652                    // If this is a multiprocess provider, then just return its
9653                    // info and allow the caller to instantiate it.  Only do
9654                    // this if the provider is the same user as the caller's
9655                    // process, or can run as root (so can be in any process).
9656                    return cpr.newHolder(null);
9657                }
9658
9659                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
9660                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
9661                            + cpr.info.name + " callers=" + Debug.getCallers(6));
9662
9663                // This is single process, and our app is now connecting to it.
9664                // See if we are already in the process of launching this
9665                // provider.
9666                final int N = mLaunchingProviders.size();
9667                int i;
9668                for (i = 0; i < N; i++) {
9669                    if (mLaunchingProviders.get(i) == cpr) {
9670                        break;
9671                    }
9672                }
9673
9674                // If the provider is not already being launched, then get it
9675                // started.
9676                if (i >= N) {
9677                    final long origId = Binder.clearCallingIdentity();
9678
9679                    try {
9680                        // Content provider is now in use, its package can't be stopped.
9681                        try {
9682                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9683                            AppGlobals.getPackageManager().setPackageStoppedState(
9684                                    cpr.appInfo.packageName, false, userId);
9685                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9686                        } catch (RemoteException e) {
9687                        } catch (IllegalArgumentException e) {
9688                            Slog.w(TAG, "Failed trying to unstop package "
9689                                    + cpr.appInfo.packageName + ": " + e);
9690                        }
9691
9692                        // Use existing process if already started
9693                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9694                        ProcessRecord proc = getProcessRecordLocked(
9695                                cpi.processName, cpr.appInfo.uid, false);
9696                        if (proc != null && proc.thread != null) {
9697                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
9698                                    "Installing in existing process " + proc);
9699                            if (!proc.pubProviders.containsKey(cpi.name)) {
9700                                checkTime(startTime, "getContentProviderImpl: scheduling install");
9701                                proc.pubProviders.put(cpi.name, cpr);
9702                                try {
9703                                    proc.thread.scheduleInstallProvider(cpi);
9704                                } catch (RemoteException e) {
9705                                }
9706                            }
9707                        } else {
9708                            checkTime(startTime, "getContentProviderImpl: before start process");
9709                            proc = startProcessLocked(cpi.processName,
9710                                    cpr.appInfo, false, 0, "content provider",
9711                                    new ComponentName(cpi.applicationInfo.packageName,
9712                                            cpi.name), false, false, false);
9713                            checkTime(startTime, "getContentProviderImpl: after start process");
9714                            if (proc == null) {
9715                                Slog.w(TAG, "Unable to launch app "
9716                                        + cpi.applicationInfo.packageName + "/"
9717                                        + cpi.applicationInfo.uid + " for provider "
9718                                        + name + ": process is bad");
9719                                return null;
9720                            }
9721                        }
9722                        cpr.launchingApp = proc;
9723                        mLaunchingProviders.add(cpr);
9724                    } finally {
9725                        Binder.restoreCallingIdentity(origId);
9726                    }
9727                }
9728
9729                checkTime(startTime, "getContentProviderImpl: updating data structures");
9730
9731                // Make sure the provider is published (the same provider class
9732                // may be published under multiple names).
9733                if (firstClass) {
9734                    mProviderMap.putProviderByClass(comp, cpr);
9735                }
9736
9737                mProviderMap.putProviderByName(name, cpr);
9738                conn = incProviderCountLocked(r, cpr, token, stable);
9739                if (conn != null) {
9740                    conn.waiting = true;
9741                }
9742            }
9743            checkTime(startTime, "getContentProviderImpl: done!");
9744        }
9745
9746        // Wait for the provider to be published...
9747        synchronized (cpr) {
9748            while (cpr.provider == null) {
9749                if (cpr.launchingApp == null) {
9750                    Slog.w(TAG, "Unable to launch app "
9751                            + cpi.applicationInfo.packageName + "/"
9752                            + cpi.applicationInfo.uid + " for provider "
9753                            + name + ": launching app became null");
9754                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9755                            UserHandle.getUserId(cpi.applicationInfo.uid),
9756                            cpi.applicationInfo.packageName,
9757                            cpi.applicationInfo.uid, name);
9758                    return null;
9759                }
9760                try {
9761                    if (DEBUG_MU) Slog.v(TAG_MU,
9762                            "Waiting to start provider " + cpr
9763                            + " launchingApp=" + cpr.launchingApp);
9764                    if (conn != null) {
9765                        conn.waiting = true;
9766                    }
9767                    cpr.wait();
9768                } catch (InterruptedException ex) {
9769                } finally {
9770                    if (conn != null) {
9771                        conn.waiting = false;
9772                    }
9773                }
9774            }
9775        }
9776        return cpr != null ? cpr.newHolder(conn) : null;
9777    }
9778
9779    @Override
9780    public final ContentProviderHolder getContentProvider(
9781            IApplicationThread caller, String name, int userId, boolean stable) {
9782        enforceNotIsolatedCaller("getContentProvider");
9783        if (caller == null) {
9784            String msg = "null IApplicationThread when getting content provider "
9785                    + name;
9786            Slog.w(TAG, msg);
9787            throw new SecurityException(msg);
9788        }
9789        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9790        // with cross-user grant.
9791        return getContentProviderImpl(caller, name, null, stable, userId);
9792    }
9793
9794    public ContentProviderHolder getContentProviderExternal(
9795            String name, int userId, IBinder token) {
9796        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9797            "Do not have permission in call getContentProviderExternal()");
9798        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9799                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9800        return getContentProviderExternalUnchecked(name, token, userId);
9801    }
9802
9803    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9804            IBinder token, int userId) {
9805        return getContentProviderImpl(null, name, token, true, userId);
9806    }
9807
9808    /**
9809     * Drop a content provider from a ProcessRecord's bookkeeping
9810     */
9811    public void removeContentProvider(IBinder connection, boolean stable) {
9812        enforceNotIsolatedCaller("removeContentProvider");
9813        long ident = Binder.clearCallingIdentity();
9814        try {
9815            synchronized (this) {
9816                ContentProviderConnection conn;
9817                try {
9818                    conn = (ContentProviderConnection)connection;
9819                } catch (ClassCastException e) {
9820                    String msg ="removeContentProvider: " + connection
9821                            + " not a ContentProviderConnection";
9822                    Slog.w(TAG, msg);
9823                    throw new IllegalArgumentException(msg);
9824                }
9825                if (conn == null) {
9826                    throw new NullPointerException("connection is null");
9827                }
9828                if (decProviderCountLocked(conn, null, null, stable)) {
9829                    updateOomAdjLocked();
9830                }
9831            }
9832        } finally {
9833            Binder.restoreCallingIdentity(ident);
9834        }
9835    }
9836
9837    public void removeContentProviderExternal(String name, IBinder token) {
9838        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9839            "Do not have permission in call removeContentProviderExternal()");
9840        int userId = UserHandle.getCallingUserId();
9841        long ident = Binder.clearCallingIdentity();
9842        try {
9843            removeContentProviderExternalUnchecked(name, token, userId);
9844        } finally {
9845            Binder.restoreCallingIdentity(ident);
9846        }
9847    }
9848
9849    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9850        synchronized (this) {
9851            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9852            if(cpr == null) {
9853                //remove from mProvidersByClass
9854                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
9855                return;
9856            }
9857
9858            //update content provider record entry info
9859            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9860            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9861            if (localCpr.hasExternalProcessHandles()) {
9862                if (localCpr.removeExternalProcessHandleLocked(token)) {
9863                    updateOomAdjLocked();
9864                } else {
9865                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9866                            + " with no external reference for token: "
9867                            + token + ".");
9868                }
9869            } else {
9870                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9871                        + " with no external references.");
9872            }
9873        }
9874    }
9875
9876    public final void publishContentProviders(IApplicationThread caller,
9877            List<ContentProviderHolder> providers) {
9878        if (providers == null) {
9879            return;
9880        }
9881
9882        enforceNotIsolatedCaller("publishContentProviders");
9883        synchronized (this) {
9884            final ProcessRecord r = getRecordForAppLocked(caller);
9885            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9886            if (r == null) {
9887                throw new SecurityException(
9888                        "Unable to find app for caller " + caller
9889                      + " (pid=" + Binder.getCallingPid()
9890                      + ") when publishing content providers");
9891            }
9892
9893            final long origId = Binder.clearCallingIdentity();
9894
9895            final int N = providers.size();
9896            for (int i=0; i<N; i++) {
9897                ContentProviderHolder src = providers.get(i);
9898                if (src == null || src.info == null || src.provider == null) {
9899                    continue;
9900                }
9901                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9902                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9903                if (dst != null) {
9904                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9905                    mProviderMap.putProviderByClass(comp, dst);
9906                    String names[] = dst.info.authority.split(";");
9907                    for (int j = 0; j < names.length; j++) {
9908                        mProviderMap.putProviderByName(names[j], dst);
9909                    }
9910
9911                    int NL = mLaunchingProviders.size();
9912                    int j;
9913                    for (j=0; j<NL; j++) {
9914                        if (mLaunchingProviders.get(j) == dst) {
9915                            mLaunchingProviders.remove(j);
9916                            j--;
9917                            NL--;
9918                        }
9919                    }
9920                    synchronized (dst) {
9921                        dst.provider = src.provider;
9922                        dst.proc = r;
9923                        dst.notifyAll();
9924                    }
9925                    updateOomAdjLocked(r);
9926                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
9927                            src.info.authority);
9928                }
9929            }
9930
9931            Binder.restoreCallingIdentity(origId);
9932        }
9933    }
9934
9935    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9936        ContentProviderConnection conn;
9937        try {
9938            conn = (ContentProviderConnection)connection;
9939        } catch (ClassCastException e) {
9940            String msg ="refContentProvider: " + connection
9941                    + " not a ContentProviderConnection";
9942            Slog.w(TAG, msg);
9943            throw new IllegalArgumentException(msg);
9944        }
9945        if (conn == null) {
9946            throw new NullPointerException("connection is null");
9947        }
9948
9949        synchronized (this) {
9950            if (stable > 0) {
9951                conn.numStableIncs += stable;
9952            }
9953            stable = conn.stableCount + stable;
9954            if (stable < 0) {
9955                throw new IllegalStateException("stableCount < 0: " + stable);
9956            }
9957
9958            if (unstable > 0) {
9959                conn.numUnstableIncs += unstable;
9960            }
9961            unstable = conn.unstableCount + unstable;
9962            if (unstable < 0) {
9963                throw new IllegalStateException("unstableCount < 0: " + unstable);
9964            }
9965
9966            if ((stable+unstable) <= 0) {
9967                throw new IllegalStateException("ref counts can't go to zero here: stable="
9968                        + stable + " unstable=" + unstable);
9969            }
9970            conn.stableCount = stable;
9971            conn.unstableCount = unstable;
9972            return !conn.dead;
9973        }
9974    }
9975
9976    public void unstableProviderDied(IBinder connection) {
9977        ContentProviderConnection conn;
9978        try {
9979            conn = (ContentProviderConnection)connection;
9980        } catch (ClassCastException e) {
9981            String msg ="refContentProvider: " + connection
9982                    + " not a ContentProviderConnection";
9983            Slog.w(TAG, msg);
9984            throw new IllegalArgumentException(msg);
9985        }
9986        if (conn == null) {
9987            throw new NullPointerException("connection is null");
9988        }
9989
9990        // Safely retrieve the content provider associated with the connection.
9991        IContentProvider provider;
9992        synchronized (this) {
9993            provider = conn.provider.provider;
9994        }
9995
9996        if (provider == null) {
9997            // Um, yeah, we're way ahead of you.
9998            return;
9999        }
10000
10001        // Make sure the caller is being honest with us.
10002        if (provider.asBinder().pingBinder()) {
10003            // Er, no, still looks good to us.
10004            synchronized (this) {
10005                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10006                        + " says " + conn + " died, but we don't agree");
10007                return;
10008            }
10009        }
10010
10011        // Well look at that!  It's dead!
10012        synchronized (this) {
10013            if (conn.provider.provider != provider) {
10014                // But something changed...  good enough.
10015                return;
10016            }
10017
10018            ProcessRecord proc = conn.provider.proc;
10019            if (proc == null || proc.thread == null) {
10020                // Seems like the process is already cleaned up.
10021                return;
10022            }
10023
10024            // As far as we're concerned, this is just like receiving a
10025            // death notification...  just a bit prematurely.
10026            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10027                    + ") early provider death");
10028            final long ident = Binder.clearCallingIdentity();
10029            try {
10030                appDiedLocked(proc);
10031            } finally {
10032                Binder.restoreCallingIdentity(ident);
10033            }
10034        }
10035    }
10036
10037    @Override
10038    public void appNotRespondingViaProvider(IBinder connection) {
10039        enforceCallingPermission(
10040                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10041
10042        final ContentProviderConnection conn = (ContentProviderConnection) connection;
10043        if (conn == null) {
10044            Slog.w(TAG, "ContentProviderConnection is null");
10045            return;
10046        }
10047
10048        final ProcessRecord host = conn.provider.proc;
10049        if (host == null) {
10050            Slog.w(TAG, "Failed to find hosting ProcessRecord");
10051            return;
10052        }
10053
10054        final long token = Binder.clearCallingIdentity();
10055        try {
10056            appNotResponding(host, null, null, false, "ContentProvider not responding");
10057        } finally {
10058            Binder.restoreCallingIdentity(token);
10059        }
10060    }
10061
10062    public final void installSystemProviders() {
10063        List<ProviderInfo> providers;
10064        synchronized (this) {
10065            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10066            providers = generateApplicationProvidersLocked(app);
10067            if (providers != null) {
10068                for (int i=providers.size()-1; i>=0; i--) {
10069                    ProviderInfo pi = (ProviderInfo)providers.get(i);
10070                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10071                        Slog.w(TAG, "Not installing system proc provider " + pi.name
10072                                + ": not system .apk");
10073                        providers.remove(i);
10074                    }
10075                }
10076            }
10077        }
10078        if (providers != null) {
10079            mSystemThread.installSystemProviders(providers);
10080        }
10081
10082        mCoreSettingsObserver = new CoreSettingsObserver(this);
10083
10084        //mUsageStatsService.monitorPackages();
10085    }
10086
10087    /**
10088     * Allows apps to retrieve the MIME type of a URI.
10089     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
10090     * users, then it does not need permission to access the ContentProvider.
10091     * Either, it needs cross-user uri grants.
10092     *
10093     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
10094     *
10095     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
10096     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
10097     */
10098    public String getProviderMimeType(Uri uri, int userId) {
10099        enforceNotIsolatedCaller("getProviderMimeType");
10100        final String name = uri.getAuthority();
10101        int callingUid = Binder.getCallingUid();
10102        int callingPid = Binder.getCallingPid();
10103        long ident = 0;
10104        boolean clearedIdentity = false;
10105        userId = unsafeConvertIncomingUser(userId);
10106        if (canClearIdentity(callingPid, callingUid, userId)) {
10107            clearedIdentity = true;
10108            ident = Binder.clearCallingIdentity();
10109        }
10110        ContentProviderHolder holder = null;
10111        try {
10112            holder = getContentProviderExternalUnchecked(name, null, userId);
10113            if (holder != null) {
10114                return holder.provider.getType(uri);
10115            }
10116        } catch (RemoteException e) {
10117            Log.w(TAG, "Content provider dead retrieving " + uri, e);
10118            return null;
10119        } finally {
10120            // We need to clear the identity to call removeContentProviderExternalUnchecked
10121            if (!clearedIdentity) {
10122                ident = Binder.clearCallingIdentity();
10123            }
10124            try {
10125                if (holder != null) {
10126                    removeContentProviderExternalUnchecked(name, null, userId);
10127                }
10128            } finally {
10129                Binder.restoreCallingIdentity(ident);
10130            }
10131        }
10132
10133        return null;
10134    }
10135
10136    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
10137        if (UserHandle.getUserId(callingUid) == userId) {
10138            return true;
10139        }
10140        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
10141                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
10142                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
10143                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
10144                return true;
10145        }
10146        return false;
10147    }
10148
10149    // =========================================================
10150    // GLOBAL MANAGEMENT
10151    // =========================================================
10152
10153    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
10154            boolean isolated, int isolatedUid) {
10155        String proc = customProcess != null ? customProcess : info.processName;
10156        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10157        final int userId = UserHandle.getUserId(info.uid);
10158        int uid = info.uid;
10159        if (isolated) {
10160            if (isolatedUid == 0) {
10161                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
10162                while (true) {
10163                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
10164                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
10165                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
10166                    }
10167                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
10168                    mNextIsolatedProcessUid++;
10169                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
10170                        // No process for this uid, use it.
10171                        break;
10172                    }
10173                    stepsLeft--;
10174                    if (stepsLeft <= 0) {
10175                        return null;
10176                    }
10177                }
10178            } else {
10179                // Special case for startIsolatedProcess (internal only), where
10180                // the uid of the isolated process is specified by the caller.
10181                uid = isolatedUid;
10182            }
10183        }
10184        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
10185        if (!mBooted && !mBooting
10186                && userId == UserHandle.USER_OWNER
10187                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10188            r.persistent = true;
10189        }
10190        addProcessNameLocked(r);
10191        return r;
10192    }
10193
10194    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
10195            String abiOverride) {
10196        ProcessRecord app;
10197        if (!isolated) {
10198            app = getProcessRecordLocked(info.processName, info.uid, true);
10199        } else {
10200            app = null;
10201        }
10202
10203        if (app == null) {
10204            app = newProcessRecordLocked(info, null, isolated, 0);
10205            updateLruProcessLocked(app, false, null);
10206            updateOomAdjLocked();
10207        }
10208
10209        // This package really, really can not be stopped.
10210        try {
10211            AppGlobals.getPackageManager().setPackageStoppedState(
10212                    info.packageName, false, UserHandle.getUserId(app.uid));
10213        } catch (RemoteException e) {
10214        } catch (IllegalArgumentException e) {
10215            Slog.w(TAG, "Failed trying to unstop package "
10216                    + info.packageName + ": " + e);
10217        }
10218
10219        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10220            app.persistent = true;
10221            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10222        }
10223        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10224            mPersistentStartingProcesses.add(app);
10225            startProcessLocked(app, "added application", app.processName, abiOverride,
10226                    null /* entryPoint */, null /* entryPointArgs */);
10227        }
10228
10229        return app;
10230    }
10231
10232    public void unhandledBack() {
10233        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10234                "unhandledBack()");
10235
10236        synchronized(this) {
10237            final long origId = Binder.clearCallingIdentity();
10238            try {
10239                getFocusedStack().unhandledBackLocked();
10240            } finally {
10241                Binder.restoreCallingIdentity(origId);
10242            }
10243        }
10244    }
10245
10246    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10247        enforceNotIsolatedCaller("openContentUri");
10248        final int userId = UserHandle.getCallingUserId();
10249        String name = uri.getAuthority();
10250        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10251        ParcelFileDescriptor pfd = null;
10252        if (cph != null) {
10253            // We record the binder invoker's uid in thread-local storage before
10254            // going to the content provider to open the file.  Later, in the code
10255            // that handles all permissions checks, we look for this uid and use
10256            // that rather than the Activity Manager's own uid.  The effect is that
10257            // we do the check against the caller's permissions even though it looks
10258            // to the content provider like the Activity Manager itself is making
10259            // the request.
10260            Binder token = new Binder();
10261            sCallerIdentity.set(new Identity(
10262                    token, Binder.getCallingPid(), Binder.getCallingUid()));
10263            try {
10264                pfd = cph.provider.openFile(null, uri, "r", null, token);
10265            } catch (FileNotFoundException e) {
10266                // do nothing; pfd will be returned null
10267            } finally {
10268                // Ensure that whatever happens, we clean up the identity state
10269                sCallerIdentity.remove();
10270                // Ensure we're done with the provider.
10271                removeContentProviderExternalUnchecked(name, null, userId);
10272            }
10273        } else {
10274            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10275        }
10276        return pfd;
10277    }
10278
10279    // Actually is sleeping or shutting down or whatever else in the future
10280    // is an inactive state.
10281    public boolean isSleepingOrShuttingDown() {
10282        return isSleeping() || mShuttingDown;
10283    }
10284
10285    public boolean isSleeping() {
10286        return mSleeping;
10287    }
10288
10289    void onWakefulnessChanged(int wakefulness) {
10290        synchronized(this) {
10291            mWakefulness = wakefulness;
10292            updateSleepIfNeededLocked();
10293        }
10294    }
10295
10296    void finishRunningVoiceLocked() {
10297        if (mRunningVoice != null) {
10298            mRunningVoice = null;
10299            mVoiceWakeLock.release();
10300            updateSleepIfNeededLocked();
10301        }
10302    }
10303
10304    void startTimeTrackingFocusedActivityLocked() {
10305        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
10306            mCurAppTimeTracker.start(mFocusedActivity.packageName);
10307        }
10308    }
10309
10310    void updateSleepIfNeededLocked() {
10311        if (mSleeping && !shouldSleepLocked()) {
10312            mSleeping = false;
10313            startTimeTrackingFocusedActivityLocked();
10314            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
10315            mStackSupervisor.comeOutOfSleepIfNeededLocked();
10316            updateOomAdjLocked();
10317        } else if (!mSleeping && shouldSleepLocked()) {
10318            mSleeping = true;
10319            if (mCurAppTimeTracker != null) {
10320                mCurAppTimeTracker.stop();
10321            }
10322            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
10323            mStackSupervisor.goingToSleepLocked();
10324            updateOomAdjLocked();
10325
10326            // Initialize the wake times of all processes.
10327            checkExcessivePowerUsageLocked(false);
10328            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10329            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10330            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10331        }
10332    }
10333
10334    private boolean shouldSleepLocked() {
10335        // Resume applications while running a voice interactor.
10336        if (mRunningVoice != null) {
10337            return false;
10338        }
10339
10340        // TODO: Transform the lock screen state into a sleep token instead.
10341        switch (mWakefulness) {
10342            case PowerManagerInternal.WAKEFULNESS_AWAKE:
10343            case PowerManagerInternal.WAKEFULNESS_DREAMING:
10344            case PowerManagerInternal.WAKEFULNESS_DOZING:
10345                // Pause applications whenever the lock screen is shown or any sleep
10346                // tokens have been acquired.
10347                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
10348            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10349            default:
10350                // If we're asleep then pause applications unconditionally.
10351                return true;
10352        }
10353    }
10354
10355    /** Pokes the task persister. */
10356    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10357        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10358            // Never persist the home stack.
10359            return;
10360        }
10361        mTaskPersister.wakeup(task, flush);
10362    }
10363
10364    /** Notifies all listeners when the task stack has changed. */
10365    void notifyTaskStackChangedLocked() {
10366        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10367        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10368        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10369    }
10370
10371    @Override
10372    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
10373        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
10374    }
10375
10376    @Override
10377    public boolean shutdown(int timeout) {
10378        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10379                != PackageManager.PERMISSION_GRANTED) {
10380            throw new SecurityException("Requires permission "
10381                    + android.Manifest.permission.SHUTDOWN);
10382        }
10383
10384        boolean timedout = false;
10385
10386        synchronized(this) {
10387            mShuttingDown = true;
10388            updateEventDispatchingLocked();
10389            timedout = mStackSupervisor.shutdownLocked(timeout);
10390        }
10391
10392        mAppOpsService.shutdown();
10393        if (mUsageStatsService != null) {
10394            mUsageStatsService.prepareShutdown();
10395        }
10396        mBatteryStatsService.shutdown();
10397        synchronized (this) {
10398            mProcessStats.shutdownLocked();
10399            notifyTaskPersisterLocked(null, true);
10400        }
10401
10402        return timedout;
10403    }
10404
10405    public final void activitySlept(IBinder token) {
10406        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
10407
10408        final long origId = Binder.clearCallingIdentity();
10409
10410        synchronized (this) {
10411            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10412            if (r != null) {
10413                mStackSupervisor.activitySleptLocked(r);
10414            }
10415        }
10416
10417        Binder.restoreCallingIdentity(origId);
10418    }
10419
10420    private String lockScreenShownToString() {
10421        switch (mLockScreenShown) {
10422            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10423            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10424            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10425            default: return "Unknown=" + mLockScreenShown;
10426        }
10427    }
10428
10429    void logLockScreen(String msg) {
10430        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
10431                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10432                + PowerManagerInternal.wakefulnessToString(mWakefulness)
10433                + " mSleeping=" + mSleeping);
10434    }
10435
10436    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
10437        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
10438        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
10439            boolean wasRunningVoice = mRunningVoice != null;
10440            mRunningVoice = session;
10441            if (!wasRunningVoice) {
10442                mVoiceWakeLock.acquire();
10443                updateSleepIfNeededLocked();
10444            }
10445        }
10446    }
10447
10448    private void updateEventDispatchingLocked() {
10449        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10450    }
10451
10452    public void setLockScreenShown(boolean shown) {
10453        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10454                != PackageManager.PERMISSION_GRANTED) {
10455            throw new SecurityException("Requires permission "
10456                    + android.Manifest.permission.DEVICE_POWER);
10457        }
10458
10459        synchronized(this) {
10460            long ident = Binder.clearCallingIdentity();
10461            try {
10462                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10463                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10464                updateSleepIfNeededLocked();
10465            } finally {
10466                Binder.restoreCallingIdentity(ident);
10467            }
10468        }
10469    }
10470
10471    @Override
10472    public void stopAppSwitches() {
10473        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10474                != PackageManager.PERMISSION_GRANTED) {
10475            throw new SecurityException("Requires permission "
10476                    + android.Manifest.permission.STOP_APP_SWITCHES);
10477        }
10478
10479        synchronized(this) {
10480            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10481                    + APP_SWITCH_DELAY_TIME;
10482            mDidAppSwitch = false;
10483            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10484            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10485            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10486        }
10487    }
10488
10489    public void resumeAppSwitches() {
10490        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10491                != PackageManager.PERMISSION_GRANTED) {
10492            throw new SecurityException("Requires permission "
10493                    + android.Manifest.permission.STOP_APP_SWITCHES);
10494        }
10495
10496        synchronized(this) {
10497            // Note that we don't execute any pending app switches... we will
10498            // let those wait until either the timeout, or the next start
10499            // activity request.
10500            mAppSwitchesAllowedTime = 0;
10501        }
10502    }
10503
10504    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10505            int callingPid, int callingUid, String name) {
10506        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10507            return true;
10508        }
10509
10510        int perm = checkComponentPermission(
10511                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10512                sourceUid, -1, true);
10513        if (perm == PackageManager.PERMISSION_GRANTED) {
10514            return true;
10515        }
10516
10517        // If the actual IPC caller is different from the logical source, then
10518        // also see if they are allowed to control app switches.
10519        if (callingUid != -1 && callingUid != sourceUid) {
10520            perm = checkComponentPermission(
10521                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10522                    callingUid, -1, true);
10523            if (perm == PackageManager.PERMISSION_GRANTED) {
10524                return true;
10525            }
10526        }
10527
10528        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10529        return false;
10530    }
10531
10532    public void setDebugApp(String packageName, boolean waitForDebugger,
10533            boolean persistent) {
10534        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10535                "setDebugApp()");
10536
10537        long ident = Binder.clearCallingIdentity();
10538        try {
10539            // Note that this is not really thread safe if there are multiple
10540            // callers into it at the same time, but that's not a situation we
10541            // care about.
10542            if (persistent) {
10543                final ContentResolver resolver = mContext.getContentResolver();
10544                Settings.Global.putString(
10545                    resolver, Settings.Global.DEBUG_APP,
10546                    packageName);
10547                Settings.Global.putInt(
10548                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10549                    waitForDebugger ? 1 : 0);
10550            }
10551
10552            synchronized (this) {
10553                if (!persistent) {
10554                    mOrigDebugApp = mDebugApp;
10555                    mOrigWaitForDebugger = mWaitForDebugger;
10556                }
10557                mDebugApp = packageName;
10558                mWaitForDebugger = waitForDebugger;
10559                mDebugTransient = !persistent;
10560                if (packageName != null) {
10561                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10562                            false, UserHandle.USER_ALL, "set debug app");
10563                }
10564            }
10565        } finally {
10566            Binder.restoreCallingIdentity(ident);
10567        }
10568    }
10569
10570    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10571        synchronized (this) {
10572            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10573            if (!isDebuggable) {
10574                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10575                    throw new SecurityException("Process not debuggable: " + app.packageName);
10576                }
10577            }
10578
10579            mOpenGlTraceApp = processName;
10580        }
10581    }
10582
10583    void setTrackAllocationApp(ApplicationInfo app, String processName) {
10584        synchronized (this) {
10585            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10586            if (!isDebuggable) {
10587                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10588                    throw new SecurityException("Process not debuggable: " + app.packageName);
10589                }
10590            }
10591
10592            mTrackAllocationApp = processName;
10593        }
10594    }
10595
10596    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10597        synchronized (this) {
10598            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10599            if (!isDebuggable) {
10600                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10601                    throw new SecurityException("Process not debuggable: " + app.packageName);
10602                }
10603            }
10604            mProfileApp = processName;
10605            mProfileFile = profilerInfo.profileFile;
10606            if (mProfileFd != null) {
10607                try {
10608                    mProfileFd.close();
10609                } catch (IOException e) {
10610                }
10611                mProfileFd = null;
10612            }
10613            mProfileFd = profilerInfo.profileFd;
10614            mSamplingInterval = profilerInfo.samplingInterval;
10615            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10616            mProfileType = 0;
10617        }
10618    }
10619
10620    @Override
10621    public void setAlwaysFinish(boolean enabled) {
10622        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10623                "setAlwaysFinish()");
10624
10625        Settings.Global.putInt(
10626                mContext.getContentResolver(),
10627                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10628
10629        synchronized (this) {
10630            mAlwaysFinishActivities = enabled;
10631        }
10632    }
10633
10634    @Override
10635    public void setActivityController(IActivityController controller) {
10636        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10637                "setActivityController()");
10638        synchronized (this) {
10639            mController = controller;
10640            Watchdog.getInstance().setActivityController(controller);
10641        }
10642    }
10643
10644    @Override
10645    public void setUserIsMonkey(boolean userIsMonkey) {
10646        synchronized (this) {
10647            synchronized (mPidsSelfLocked) {
10648                final int callingPid = Binder.getCallingPid();
10649                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10650                if (precessRecord == null) {
10651                    throw new SecurityException("Unknown process: " + callingPid);
10652                }
10653                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10654                    throw new SecurityException("Only an instrumentation process "
10655                            + "with a UiAutomation can call setUserIsMonkey");
10656                }
10657            }
10658            mUserIsMonkey = userIsMonkey;
10659        }
10660    }
10661
10662    @Override
10663    public boolean isUserAMonkey() {
10664        synchronized (this) {
10665            // If there is a controller also implies the user is a monkey.
10666            return (mUserIsMonkey || mController != null);
10667        }
10668    }
10669
10670    public void requestBugReport() {
10671        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10672        SystemProperties.set("ctl.start", "bugreport");
10673    }
10674
10675    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10676        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10677    }
10678
10679    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10680        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10681            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10682        }
10683        return KEY_DISPATCHING_TIMEOUT;
10684    }
10685
10686    @Override
10687    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10688        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10689                != PackageManager.PERMISSION_GRANTED) {
10690            throw new SecurityException("Requires permission "
10691                    + android.Manifest.permission.FILTER_EVENTS);
10692        }
10693        ProcessRecord proc;
10694        long timeout;
10695        synchronized (this) {
10696            synchronized (mPidsSelfLocked) {
10697                proc = mPidsSelfLocked.get(pid);
10698            }
10699            timeout = getInputDispatchingTimeoutLocked(proc);
10700        }
10701
10702        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10703            return -1;
10704        }
10705
10706        return timeout;
10707    }
10708
10709    /**
10710     * Handle input dispatching timeouts.
10711     * Returns whether input dispatching should be aborted or not.
10712     */
10713    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10714            final ActivityRecord activity, final ActivityRecord parent,
10715            final boolean aboveSystem, String reason) {
10716        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10717                != PackageManager.PERMISSION_GRANTED) {
10718            throw new SecurityException("Requires permission "
10719                    + android.Manifest.permission.FILTER_EVENTS);
10720        }
10721
10722        final String annotation;
10723        if (reason == null) {
10724            annotation = "Input dispatching timed out";
10725        } else {
10726            annotation = "Input dispatching timed out (" + reason + ")";
10727        }
10728
10729        if (proc != null) {
10730            synchronized (this) {
10731                if (proc.debugging) {
10732                    return false;
10733                }
10734
10735                if (mDidDexOpt) {
10736                    // Give more time since we were dexopting.
10737                    mDidDexOpt = false;
10738                    return false;
10739                }
10740
10741                if (proc.instrumentationClass != null) {
10742                    Bundle info = new Bundle();
10743                    info.putString("shortMsg", "keyDispatchingTimedOut");
10744                    info.putString("longMsg", annotation);
10745                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10746                    return true;
10747                }
10748            }
10749            mHandler.post(new Runnable() {
10750                @Override
10751                public void run() {
10752                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10753                }
10754            });
10755        }
10756
10757        return true;
10758    }
10759
10760    @Override
10761    public Bundle getAssistContextExtras(int requestType) {
10762        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
10763                null, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
10764        if (pae == null) {
10765            return null;
10766        }
10767        synchronized (pae) {
10768            while (!pae.haveResult) {
10769                try {
10770                    pae.wait();
10771                } catch (InterruptedException e) {
10772                }
10773            }
10774        }
10775        synchronized (this) {
10776            buildAssistBundleLocked(pae, pae.result);
10777            mPendingAssistExtras.remove(pae);
10778            mUiHandler.removeCallbacks(pae);
10779        }
10780        return pae.extras;
10781    }
10782
10783    @Override
10784    public boolean isAssistDataAllowedOnCurrentActivity() {
10785        int userId = mCurrentUserId;
10786        synchronized (this) {
10787            ActivityRecord activity = getFocusedStack().topActivity();
10788            if (activity == null) {
10789                return false;
10790            }
10791            userId = activity.userId;
10792        }
10793        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
10794                Context.DEVICE_POLICY_SERVICE);
10795        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
10796    }
10797
10798    @Override
10799    public boolean showAssistFromActivity(IBinder token, Bundle args) {
10800        long ident = Binder.clearCallingIdentity();
10801        try {
10802            synchronized (this) {
10803                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
10804                ActivityRecord top = getFocusedStack().topActivity();
10805                if (top != caller) {
10806                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
10807                            + " is not current top " + top);
10808                    return false;
10809                }
10810                if (!top.nowVisible) {
10811                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
10812                            + " is not visible");
10813                    return false;
10814                }
10815            }
10816            AssistUtils utils = new AssistUtils(mContext);
10817            return utils.showSessionForActiveService(args,
10818                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
10819        } finally {
10820            Binder.restoreCallingIdentity(ident);
10821        }
10822    }
10823
10824    @Override
10825    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
10826            IBinder activityToken) {
10827        return enqueueAssistContext(requestType, null, null, receiver, activityToken,
10828                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
10829    }
10830
10831    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10832            IResultReceiver receiver, IBinder activityToken, int userHandle, Bundle args,
10833            long timeout) {
10834        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10835                "enqueueAssistContext()");
10836        synchronized (this) {
10837            ActivityRecord activity = getFocusedStack().topActivity();
10838            if (activity == null) {
10839                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
10840                return null;
10841            }
10842            if (activity.app == null || activity.app.thread == null) {
10843                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10844                return null;
10845            }
10846            if (activityToken != null) {
10847                ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
10848                if (activity != caller) {
10849                    Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
10850                            + " is not current top " + activity);
10851                    return null;
10852                }
10853            }
10854            PendingAssistExtras pae;
10855            Bundle extras = new Bundle();
10856            if (args != null) {
10857                extras.putAll(args);
10858            }
10859            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10860            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
10861            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
10862            try {
10863                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10864                        requestType);
10865                mPendingAssistExtras.add(pae);
10866                mUiHandler.postDelayed(pae, timeout);
10867            } catch (RemoteException e) {
10868                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10869                return null;
10870            }
10871            return pae;
10872        }
10873    }
10874
10875    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
10876        IResultReceiver receiver;
10877        synchronized (this) {
10878            mPendingAssistExtras.remove(pae);
10879            receiver = pae.receiver;
10880        }
10881        if (receiver != null) {
10882            // Caller wants result sent back to them.
10883            try {
10884                pae.receiver.send(0, null);
10885            } catch (RemoteException e) {
10886            }
10887        }
10888    }
10889
10890    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
10891        if (result != null) {
10892            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
10893        }
10894        if (pae.hint != null) {
10895            pae.extras.putBoolean(pae.hint, true);
10896        }
10897    }
10898
10899    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
10900            AssistContent content, Uri referrer) {
10901        PendingAssistExtras pae = (PendingAssistExtras)token;
10902        synchronized (pae) {
10903            pae.result = extras;
10904            pae.structure = structure;
10905            pae.content = content;
10906            if (referrer != null) {
10907                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
10908            }
10909            pae.haveResult = true;
10910            pae.notifyAll();
10911            if (pae.intent == null && pae.receiver == null) {
10912                // Caller is just waiting for the result.
10913                return;
10914            }
10915        }
10916
10917        // We are now ready to launch the assist activity.
10918        IResultReceiver sendReceiver = null;
10919        Bundle sendBundle = null;
10920        synchronized (this) {
10921            buildAssistBundleLocked(pae, extras);
10922            boolean exists = mPendingAssistExtras.remove(pae);
10923            mUiHandler.removeCallbacks(pae);
10924            if (!exists) {
10925                // Timed out.
10926                return;
10927            }
10928            if ((sendReceiver=pae.receiver) != null) {
10929                // Caller wants result sent back to them.
10930                sendBundle = new Bundle();
10931                sendBundle.putBundle("data", pae.extras);
10932                sendBundle.putParcelable("structure", pae.structure);
10933                sendBundle.putParcelable("content", pae.content);
10934            }
10935        }
10936        if (sendReceiver != null) {
10937            try {
10938                sendReceiver.send(0, sendBundle);
10939            } catch (RemoteException e) {
10940            }
10941            return;
10942        }
10943
10944        long ident = Binder.clearCallingIdentity();
10945        try {
10946            pae.intent.replaceExtras(pae.extras);
10947            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10948                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
10949                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10950            closeSystemDialogs("assist");
10951            try {
10952                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10953            } catch (ActivityNotFoundException e) {
10954                Slog.w(TAG, "No activity to handle assist action.", e);
10955            }
10956        } finally {
10957            Binder.restoreCallingIdentity(ident);
10958        }
10959    }
10960
10961    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
10962            Bundle args) {
10963        return enqueueAssistContext(requestType, intent, hint, null, null, userHandle, args,
10964                PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
10965    }
10966
10967    public void registerProcessObserver(IProcessObserver observer) {
10968        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10969                "registerProcessObserver()");
10970        synchronized (this) {
10971            mProcessObservers.register(observer);
10972        }
10973    }
10974
10975    @Override
10976    public void unregisterProcessObserver(IProcessObserver observer) {
10977        synchronized (this) {
10978            mProcessObservers.unregister(observer);
10979        }
10980    }
10981
10982    public void registerUidObserver(IUidObserver observer) {
10983        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10984                "registerUidObserver()");
10985        synchronized (this) {
10986            mUidObservers.register(observer);
10987        }
10988    }
10989
10990    @Override
10991    public void unregisterUidObserver(IUidObserver observer) {
10992        synchronized (this) {
10993            mUidObservers.unregister(observer);
10994        }
10995    }
10996
10997    @Override
10998    public boolean convertFromTranslucent(IBinder token) {
10999        final long origId = Binder.clearCallingIdentity();
11000        try {
11001            synchronized (this) {
11002                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11003                if (r == null) {
11004                    return false;
11005                }
11006                final boolean translucentChanged = r.changeWindowTranslucency(true);
11007                if (translucentChanged) {
11008                    r.task.stack.releaseBackgroundResources(r);
11009                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
11010                }
11011                mWindowManager.setAppFullscreen(token, true);
11012                return translucentChanged;
11013            }
11014        } finally {
11015            Binder.restoreCallingIdentity(origId);
11016        }
11017    }
11018
11019    @Override
11020    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
11021        final long origId = Binder.clearCallingIdentity();
11022        try {
11023            synchronized (this) {
11024                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11025                if (r == null) {
11026                    return false;
11027                }
11028                int index = r.task.mActivities.lastIndexOf(r);
11029                if (index > 0) {
11030                    ActivityRecord under = r.task.mActivities.get(index - 1);
11031                    under.returningOptions = options;
11032                }
11033                final boolean translucentChanged = r.changeWindowTranslucency(false);
11034                if (translucentChanged) {
11035                    r.task.stack.convertActivityToTranslucent(r);
11036                }
11037                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
11038                mWindowManager.setAppFullscreen(token, false);
11039                return translucentChanged;
11040            }
11041        } finally {
11042            Binder.restoreCallingIdentity(origId);
11043        }
11044    }
11045
11046    @Override
11047    public boolean requestVisibleBehind(IBinder token, boolean visible) {
11048        final long origId = Binder.clearCallingIdentity();
11049        try {
11050            synchronized (this) {
11051                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11052                if (r != null) {
11053                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
11054                }
11055            }
11056            return false;
11057        } finally {
11058            Binder.restoreCallingIdentity(origId);
11059        }
11060    }
11061
11062    @Override
11063    public boolean isBackgroundVisibleBehind(IBinder token) {
11064        final long origId = Binder.clearCallingIdentity();
11065        try {
11066            synchronized (this) {
11067                final ActivityStack stack = ActivityRecord.getStackLocked(token);
11068                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
11069                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
11070                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
11071                return visible;
11072            }
11073        } finally {
11074            Binder.restoreCallingIdentity(origId);
11075        }
11076    }
11077
11078    @Override
11079    public ActivityOptions getActivityOptions(IBinder token) {
11080        final long origId = Binder.clearCallingIdentity();
11081        try {
11082            synchronized (this) {
11083                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11084                if (r != null) {
11085                    final ActivityOptions activityOptions = r.pendingOptions;
11086                    r.pendingOptions = null;
11087                    return activityOptions;
11088                }
11089                return null;
11090            }
11091        } finally {
11092            Binder.restoreCallingIdentity(origId);
11093        }
11094    }
11095
11096    @Override
11097    public void setImmersive(IBinder token, boolean immersive) {
11098        synchronized(this) {
11099            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11100            if (r == null) {
11101                throw new IllegalArgumentException();
11102            }
11103            r.immersive = immersive;
11104
11105            // update associated state if we're frontmost
11106            if (r == mFocusedActivity) {
11107                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
11108                applyUpdateLockStateLocked(r);
11109            }
11110        }
11111    }
11112
11113    @Override
11114    public boolean isImmersive(IBinder token) {
11115        synchronized (this) {
11116            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11117            if (r == null) {
11118                throw new IllegalArgumentException();
11119            }
11120            return r.immersive;
11121        }
11122    }
11123
11124    public boolean isTopActivityImmersive() {
11125        enforceNotIsolatedCaller("startActivity");
11126        synchronized (this) {
11127            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
11128            return (r != null) ? r.immersive : false;
11129        }
11130    }
11131
11132    @Override
11133    public boolean isTopOfTask(IBinder token) {
11134        synchronized (this) {
11135            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11136            if (r == null) {
11137                throw new IllegalArgumentException();
11138            }
11139            return r.task.getTopActivity() == r;
11140        }
11141    }
11142
11143    public final void enterSafeMode() {
11144        synchronized(this) {
11145            // It only makes sense to do this before the system is ready
11146            // and started launching other packages.
11147            if (!mSystemReady) {
11148                try {
11149                    AppGlobals.getPackageManager().enterSafeMode();
11150                } catch (RemoteException e) {
11151                }
11152            }
11153
11154            mSafeMode = true;
11155        }
11156    }
11157
11158    public final void showSafeModeOverlay() {
11159        View v = LayoutInflater.from(mContext).inflate(
11160                com.android.internal.R.layout.safe_mode, null);
11161        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
11162        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
11163        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
11164        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
11165        lp.gravity = Gravity.BOTTOM | Gravity.START;
11166        lp.format = v.getBackground().getOpacity();
11167        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
11168                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
11169        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
11170        ((WindowManager)mContext.getSystemService(
11171                Context.WINDOW_SERVICE)).addView(v, lp);
11172    }
11173
11174    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
11175        if (!(sender instanceof PendingIntentRecord)) {
11176            return;
11177        }
11178        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11179        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11180        synchronized (stats) {
11181            if (mBatteryStatsService.isOnBattery()) {
11182                mBatteryStatsService.enforceCallingPermission();
11183                int MY_UID = Binder.getCallingUid();
11184                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11185                BatteryStatsImpl.Uid.Pkg pkg =
11186                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
11187                            sourcePkg != null ? sourcePkg : rec.key.packageName);
11188                pkg.noteWakeupAlarmLocked(tag);
11189            }
11190        }
11191    }
11192
11193    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
11194        if (!(sender instanceof PendingIntentRecord)) {
11195            return;
11196        }
11197        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11198        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11199        synchronized (stats) {
11200            mBatteryStatsService.enforceCallingPermission();
11201            int MY_UID = Binder.getCallingUid();
11202            int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11203            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
11204        }
11205    }
11206
11207    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
11208        if (!(sender instanceof PendingIntentRecord)) {
11209            return;
11210        }
11211        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11212        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11213        synchronized (stats) {
11214            mBatteryStatsService.enforceCallingPermission();
11215            int MY_UID = Binder.getCallingUid();
11216            int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11217            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
11218        }
11219    }
11220
11221    public boolean killPids(int[] pids, String pReason, boolean secure) {
11222        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11223            throw new SecurityException("killPids only available to the system");
11224        }
11225        String reason = (pReason == null) ? "Unknown" : pReason;
11226        // XXX Note: don't acquire main activity lock here, because the window
11227        // manager calls in with its locks held.
11228
11229        boolean killed = false;
11230        synchronized (mPidsSelfLocked) {
11231            int[] types = new int[pids.length];
11232            int worstType = 0;
11233            for (int i=0; i<pids.length; i++) {
11234                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11235                if (proc != null) {
11236                    int type = proc.setAdj;
11237                    types[i] = type;
11238                    if (type > worstType) {
11239                        worstType = type;
11240                    }
11241                }
11242            }
11243
11244            // If the worst oom_adj is somewhere in the cached proc LRU range,
11245            // then constrain it so we will kill all cached procs.
11246            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
11247                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
11248                worstType = ProcessList.CACHED_APP_MIN_ADJ;
11249            }
11250
11251            // If this is not a secure call, don't let it kill processes that
11252            // are important.
11253            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
11254                worstType = ProcessList.SERVICE_ADJ;
11255            }
11256
11257            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
11258            for (int i=0; i<pids.length; i++) {
11259                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11260                if (proc == null) {
11261                    continue;
11262                }
11263                int adj = proc.setAdj;
11264                if (adj >= worstType && !proc.killedByAm) {
11265                    proc.kill(reason, true);
11266                    killed = true;
11267                }
11268            }
11269        }
11270        return killed;
11271    }
11272
11273    @Override
11274    public void killUid(int appId, int userId, String reason) {
11275        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
11276        synchronized (this) {
11277            final long identity = Binder.clearCallingIdentity();
11278            try {
11279                killPackageProcessesLocked(null, appId, userId,
11280                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
11281                        reason != null ? reason : "kill uid");
11282            } finally {
11283                Binder.restoreCallingIdentity(identity);
11284            }
11285        }
11286    }
11287
11288    @Override
11289    public boolean killProcessesBelowForeground(String reason) {
11290        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11291            throw new SecurityException("killProcessesBelowForeground() only available to system");
11292        }
11293
11294        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
11295    }
11296
11297    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
11298        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11299            throw new SecurityException("killProcessesBelowAdj() only available to system");
11300        }
11301
11302        boolean killed = false;
11303        synchronized (mPidsSelfLocked) {
11304            final int size = mPidsSelfLocked.size();
11305            for (int i = 0; i < size; i++) {
11306                final int pid = mPidsSelfLocked.keyAt(i);
11307                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11308                if (proc == null) continue;
11309
11310                final int adj = proc.setAdj;
11311                if (adj > belowAdj && !proc.killedByAm) {
11312                    proc.kill(reason, true);
11313                    killed = true;
11314                }
11315            }
11316        }
11317        return killed;
11318    }
11319
11320    @Override
11321    public void hang(final IBinder who, boolean allowRestart) {
11322        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11323                != PackageManager.PERMISSION_GRANTED) {
11324            throw new SecurityException("Requires permission "
11325                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11326        }
11327
11328        final IBinder.DeathRecipient death = new DeathRecipient() {
11329            @Override
11330            public void binderDied() {
11331                synchronized (this) {
11332                    notifyAll();
11333                }
11334            }
11335        };
11336
11337        try {
11338            who.linkToDeath(death, 0);
11339        } catch (RemoteException e) {
11340            Slog.w(TAG, "hang: given caller IBinder is already dead.");
11341            return;
11342        }
11343
11344        synchronized (this) {
11345            Watchdog.getInstance().setAllowRestart(allowRestart);
11346            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
11347            synchronized (death) {
11348                while (who.isBinderAlive()) {
11349                    try {
11350                        death.wait();
11351                    } catch (InterruptedException e) {
11352                    }
11353                }
11354            }
11355            Watchdog.getInstance().setAllowRestart(true);
11356        }
11357    }
11358
11359    @Override
11360    public void restart() {
11361        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11362                != PackageManager.PERMISSION_GRANTED) {
11363            throw new SecurityException("Requires permission "
11364                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11365        }
11366
11367        Log.i(TAG, "Sending shutdown broadcast...");
11368
11369        BroadcastReceiver br = new BroadcastReceiver() {
11370            @Override public void onReceive(Context context, Intent intent) {
11371                // Now the broadcast is done, finish up the low-level shutdown.
11372                Log.i(TAG, "Shutting down activity manager...");
11373                shutdown(10000);
11374                Log.i(TAG, "Shutdown complete, restarting!");
11375                Process.killProcess(Process.myPid());
11376                System.exit(10);
11377            }
11378        };
11379
11380        // First send the high-level shut down broadcast.
11381        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
11382        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
11383        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
11384        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
11385        mContext.sendOrderedBroadcastAsUser(intent,
11386                UserHandle.ALL, null, br, mHandler, 0, null, null);
11387        */
11388        br.onReceive(mContext, intent);
11389    }
11390
11391    private long getLowRamTimeSinceIdle(long now) {
11392        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
11393    }
11394
11395    @Override
11396    public void performIdleMaintenance() {
11397        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11398                != PackageManager.PERMISSION_GRANTED) {
11399            throw new SecurityException("Requires permission "
11400                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11401        }
11402
11403        synchronized (this) {
11404            final long now = SystemClock.uptimeMillis();
11405            final long timeSinceLastIdle = now - mLastIdleTime;
11406            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
11407            mLastIdleTime = now;
11408            mLowRamTimeSinceLastIdle = 0;
11409            if (mLowRamStartTime != 0) {
11410                mLowRamStartTime = now;
11411            }
11412
11413            StringBuilder sb = new StringBuilder(128);
11414            sb.append("Idle maintenance over ");
11415            TimeUtils.formatDuration(timeSinceLastIdle, sb);
11416            sb.append(" low RAM for ");
11417            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11418            Slog.i(TAG, sb.toString());
11419
11420            // If at least 1/3 of our time since the last idle period has been spent
11421            // with RAM low, then we want to kill processes.
11422            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
11423
11424            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11425                ProcessRecord proc = mLruProcesses.get(i);
11426                if (proc.notCachedSinceIdle) {
11427                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
11428                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
11429                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
11430                        if (doKilling && proc.initialIdlePss != 0
11431                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
11432                            sb = new StringBuilder(128);
11433                            sb.append("Kill");
11434                            sb.append(proc.processName);
11435                            sb.append(" in idle maint: pss=");
11436                            sb.append(proc.lastPss);
11437                            sb.append(", initialPss=");
11438                            sb.append(proc.initialIdlePss);
11439                            sb.append(", period=");
11440                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
11441                            sb.append(", lowRamPeriod=");
11442                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11443                            Slog.wtfQuiet(TAG, sb.toString());
11444                            proc.kill("idle maint (pss " + proc.lastPss
11445                                    + " from " + proc.initialIdlePss + ")", true);
11446                        }
11447                    }
11448                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
11449                    proc.notCachedSinceIdle = true;
11450                    proc.initialIdlePss = 0;
11451                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
11452                            mTestPssMode, isSleeping(), now);
11453                }
11454            }
11455
11456            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
11457            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
11458        }
11459    }
11460
11461    private void retrieveSettings() {
11462        final ContentResolver resolver = mContext.getContentResolver();
11463        String debugApp = Settings.Global.getString(
11464            resolver, Settings.Global.DEBUG_APP);
11465        boolean waitForDebugger = Settings.Global.getInt(
11466            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11467        boolean alwaysFinishActivities = Settings.Global.getInt(
11468            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11469        boolean forceRtl = Settings.Global.getInt(
11470                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11471        // Transfer any global setting for forcing RTL layout, into a System Property
11472        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11473
11474        Configuration configuration = new Configuration();
11475        Settings.System.getConfiguration(resolver, configuration);
11476        if (forceRtl) {
11477            // This will take care of setting the correct layout direction flags
11478            configuration.setLayoutDirection(configuration.locale);
11479        }
11480
11481        synchronized (this) {
11482            mDebugApp = mOrigDebugApp = debugApp;
11483            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11484            mAlwaysFinishActivities = alwaysFinishActivities;
11485            // This happens before any activities are started, so we can
11486            // change mConfiguration in-place.
11487            updateConfigurationLocked(configuration, null, false, true);
11488            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
11489                    "Initial config: " + mConfiguration);
11490        }
11491    }
11492
11493    /** Loads resources after the current configuration has been set. */
11494    private void loadResourcesOnSystemReady() {
11495        final Resources res = mContext.getResources();
11496        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11497        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11498        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11499    }
11500
11501    public boolean testIsSystemReady() {
11502        // no need to synchronize(this) just to read & return the value
11503        return mSystemReady;
11504    }
11505
11506    private static File getCalledPreBootReceiversFile() {
11507        File dataDir = Environment.getDataDirectory();
11508        File systemDir = new File(dataDir, "system");
11509        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11510        return fname;
11511    }
11512
11513    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11514        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11515        File file = getCalledPreBootReceiversFile();
11516        FileInputStream fis = null;
11517        try {
11518            fis = new FileInputStream(file);
11519            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11520            int fvers = dis.readInt();
11521            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11522                String vers = dis.readUTF();
11523                String codename = dis.readUTF();
11524                String build = dis.readUTF();
11525                if (android.os.Build.VERSION.RELEASE.equals(vers)
11526                        && android.os.Build.VERSION.CODENAME.equals(codename)
11527                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11528                    int num = dis.readInt();
11529                    while (num > 0) {
11530                        num--;
11531                        String pkg = dis.readUTF();
11532                        String cls = dis.readUTF();
11533                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11534                    }
11535                }
11536            }
11537        } catch (FileNotFoundException e) {
11538        } catch (IOException e) {
11539            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11540        } finally {
11541            if (fis != null) {
11542                try {
11543                    fis.close();
11544                } catch (IOException e) {
11545                }
11546            }
11547        }
11548        return lastDoneReceivers;
11549    }
11550
11551    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11552        File file = getCalledPreBootReceiversFile();
11553        FileOutputStream fos = null;
11554        DataOutputStream dos = null;
11555        try {
11556            fos = new FileOutputStream(file);
11557            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11558            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11559            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11560            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11561            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11562            dos.writeInt(list.size());
11563            for (int i=0; i<list.size(); i++) {
11564                dos.writeUTF(list.get(i).getPackageName());
11565                dos.writeUTF(list.get(i).getClassName());
11566            }
11567        } catch (IOException e) {
11568            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11569            file.delete();
11570        } finally {
11571            FileUtils.sync(fos);
11572            if (dos != null) {
11573                try {
11574                    dos.close();
11575                } catch (IOException e) {
11576                    // TODO Auto-generated catch block
11577                    e.printStackTrace();
11578                }
11579            }
11580        }
11581    }
11582
11583    final class PreBootContinuation extends IIntentReceiver.Stub {
11584        final Intent intent;
11585        final Runnable onFinishCallback;
11586        final ArrayList<ComponentName> doneReceivers;
11587        final List<ResolveInfo> ris;
11588        final int[] users;
11589        int lastRi = -1;
11590        int curRi = 0;
11591        int curUser = 0;
11592
11593        PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
11594                ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
11595            intent = _intent;
11596            onFinishCallback = _onFinishCallback;
11597            doneReceivers = _doneReceivers;
11598            ris = _ris;
11599            users = _users;
11600        }
11601
11602        void go() {
11603            if (lastRi != curRi) {
11604                ActivityInfo ai = ris.get(curRi).activityInfo;
11605                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11606                intent.setComponent(comp);
11607                doneReceivers.add(comp);
11608                lastRi = curRi;
11609                CharSequence label = ai.loadLabel(mContext.getPackageManager());
11610                showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
11611            }
11612            Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
11613                    + " for user " + users[curUser]);
11614            EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
11615            broadcastIntentLocked(null, null, intent, null, this,
11616                    0, null, null, null, AppOpsManager.OP_NONE,
11617                    null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
11618        }
11619
11620        public void performReceive(Intent intent, int resultCode,
11621                String data, Bundle extras, boolean ordered,
11622                boolean sticky, int sendingUser) {
11623            curUser++;
11624            if (curUser >= users.length) {
11625                curUser = 0;
11626                curRi++;
11627                if (curRi >= ris.size()) {
11628                    // All done sending broadcasts!
11629                    if (onFinishCallback != null) {
11630                        // The raw IIntentReceiver interface is called
11631                        // with the AM lock held, so redispatch to
11632                        // execute our code without the lock.
11633                        mHandler.post(onFinishCallback);
11634                    }
11635                    return;
11636                }
11637            }
11638            go();
11639        }
11640    }
11641
11642    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11643            ArrayList<ComponentName> doneReceivers, int userId) {
11644        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11645        List<ResolveInfo> ris = null;
11646        try {
11647            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11648                    intent, null, 0, userId);
11649        } catch (RemoteException e) {
11650        }
11651        if (ris == null) {
11652            return false;
11653        }
11654        for (int i=ris.size()-1; i>=0; i--) {
11655            if ((ris.get(i).activityInfo.applicationInfo.flags
11656                    &ApplicationInfo.FLAG_SYSTEM) == 0) {
11657                ris.remove(i);
11658            }
11659        }
11660        intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11661
11662        // For User 0, load the version number. When delivering to a new user, deliver
11663        // to all receivers.
11664        if (userId == UserHandle.USER_OWNER) {
11665            ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11666            for (int i=0; i<ris.size(); i++) {
11667                ActivityInfo ai = ris.get(i).activityInfo;
11668                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11669                if (lastDoneReceivers.contains(comp)) {
11670                    // We already did the pre boot receiver for this app with the current
11671                    // platform version, so don't do it again...
11672                    ris.remove(i);
11673                    i--;
11674                    // ...however, do keep it as one that has been done, so we don't
11675                    // forget about it when rewriting the file of last done receivers.
11676                    doneReceivers.add(comp);
11677                }
11678            }
11679        }
11680
11681        if (ris.size() <= 0) {
11682            return false;
11683        }
11684
11685        // If primary user, send broadcast to all available users, else just to userId
11686        final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11687                : new int[] { userId };
11688        if (users.length <= 0) {
11689            return false;
11690        }
11691
11692        PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
11693                ris, users);
11694        cont.go();
11695        return true;
11696    }
11697
11698    public void systemReady(final Runnable goingCallback) {
11699        synchronized(this) {
11700            if (mSystemReady) {
11701                // If we're done calling all the receivers, run the next "boot phase" passed in
11702                // by the SystemServer
11703                if (goingCallback != null) {
11704                    goingCallback.run();
11705                }
11706                return;
11707            }
11708
11709            mLocalDeviceIdleController
11710                    = LocalServices.getService(DeviceIdleController.LocalService.class);
11711
11712            // Make sure we have the current profile info, since it is needed for
11713            // security checks.
11714            updateCurrentProfileIdsLocked();
11715
11716            mRecentTasks.clear();
11717            mRecentTasks.addAll(mTaskPersister.restoreTasksLocked());
11718            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
11719            mTaskPersister.startPersisting();
11720
11721            // Check to see if there are any update receivers to run.
11722            if (!mDidUpdate) {
11723                if (mWaitingUpdate) {
11724                    return;
11725                }
11726                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11727                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11728                    public void run() {
11729                        synchronized (ActivityManagerService.this) {
11730                            mDidUpdate = true;
11731                        }
11732                        showBootMessage(mContext.getText(
11733                                R.string.android_upgrading_complete),
11734                                false);
11735                        writeLastDonePreBootReceivers(doneReceivers);
11736                        systemReady(goingCallback);
11737                    }
11738                }, doneReceivers, UserHandle.USER_OWNER);
11739
11740                if (mWaitingUpdate) {
11741                    return;
11742                }
11743                mDidUpdate = true;
11744            }
11745
11746            mAppOpsService.systemReady();
11747            mSystemReady = true;
11748        }
11749
11750        ArrayList<ProcessRecord> procsToKill = null;
11751        synchronized(mPidsSelfLocked) {
11752            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11753                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11754                if (!isAllowedWhileBooting(proc.info)){
11755                    if (procsToKill == null) {
11756                        procsToKill = new ArrayList<ProcessRecord>();
11757                    }
11758                    procsToKill.add(proc);
11759                }
11760            }
11761        }
11762
11763        synchronized(this) {
11764            if (procsToKill != null) {
11765                for (int i=procsToKill.size()-1; i>=0; i--) {
11766                    ProcessRecord proc = procsToKill.get(i);
11767                    Slog.i(TAG, "Removing system update proc: " + proc);
11768                    removeProcessLocked(proc, true, false, "system update done");
11769                }
11770            }
11771
11772            // Now that we have cleaned up any update processes, we
11773            // are ready to start launching real processes and know that
11774            // we won't trample on them any more.
11775            mProcessesReady = true;
11776        }
11777
11778        Slog.i(TAG, "System now ready");
11779        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11780            SystemClock.uptimeMillis());
11781
11782        synchronized(this) {
11783            // Make sure we have no pre-ready processes sitting around.
11784
11785            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11786                ResolveInfo ri = mContext.getPackageManager()
11787                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11788                                STOCK_PM_FLAGS);
11789                CharSequence errorMsg = null;
11790                if (ri != null) {
11791                    ActivityInfo ai = ri.activityInfo;
11792                    ApplicationInfo app = ai.applicationInfo;
11793                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11794                        mTopAction = Intent.ACTION_FACTORY_TEST;
11795                        mTopData = null;
11796                        mTopComponent = new ComponentName(app.packageName,
11797                                ai.name);
11798                    } else {
11799                        errorMsg = mContext.getResources().getText(
11800                                com.android.internal.R.string.factorytest_not_system);
11801                    }
11802                } else {
11803                    errorMsg = mContext.getResources().getText(
11804                            com.android.internal.R.string.factorytest_no_action);
11805                }
11806                if (errorMsg != null) {
11807                    mTopAction = null;
11808                    mTopData = null;
11809                    mTopComponent = null;
11810                    Message msg = Message.obtain();
11811                    msg.what = SHOW_FACTORY_ERROR_MSG;
11812                    msg.getData().putCharSequence("msg", errorMsg);
11813                    mUiHandler.sendMessage(msg);
11814                }
11815            }
11816        }
11817
11818        retrieveSettings();
11819        loadResourcesOnSystemReady();
11820
11821        synchronized (this) {
11822            readGrantedUriPermissionsLocked();
11823        }
11824
11825        if (goingCallback != null) goingCallback.run();
11826
11827        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11828                Integer.toString(mCurrentUserId), mCurrentUserId);
11829        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11830                Integer.toString(mCurrentUserId), mCurrentUserId);
11831        mSystemServiceManager.startUser(mCurrentUserId);
11832
11833        synchronized (this) {
11834            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11835                try {
11836                    List apps = AppGlobals.getPackageManager().
11837                        getPersistentApplications(STOCK_PM_FLAGS);
11838                    if (apps != null) {
11839                        int N = apps.size();
11840                        int i;
11841                        for (i=0; i<N; i++) {
11842                            ApplicationInfo info
11843                                = (ApplicationInfo)apps.get(i);
11844                            if (info != null &&
11845                                    !info.packageName.equals("android")) {
11846                                addAppLocked(info, false, null /* ABI override */);
11847                            }
11848                        }
11849                    }
11850                } catch (RemoteException ex) {
11851                    // pm is in same process, this will never happen.
11852                }
11853            }
11854
11855            // Start up initial activity.
11856            mBooting = true;
11857            startHomeActivityLocked(mCurrentUserId, "systemReady");
11858
11859            try {
11860                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11861                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11862                            + " data partition or your device will be unstable.");
11863                    mUiHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11864                }
11865            } catch (RemoteException e) {
11866            }
11867
11868            if (!Build.isBuildConsistent()) {
11869                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11870                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11871            }
11872
11873            long ident = Binder.clearCallingIdentity();
11874            try {
11875                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11876                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11877                        | Intent.FLAG_RECEIVER_FOREGROUND);
11878                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11879                broadcastIntentLocked(null, null, intent,
11880                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11881                        null, false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11882                intent = new Intent(Intent.ACTION_USER_STARTING);
11883                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11884                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11885                broadcastIntentLocked(null, null, intent,
11886                        null, new IIntentReceiver.Stub() {
11887                            @Override
11888                            public void performReceive(Intent intent, int resultCode, String data,
11889                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11890                                    throws RemoteException {
11891                            }
11892                        }, 0, null, null,
11893                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
11894                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11895            } catch (Throwable t) {
11896                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11897            } finally {
11898                Binder.restoreCallingIdentity(ident);
11899            }
11900            mStackSupervisor.resumeTopActivitiesLocked();
11901            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11902        }
11903    }
11904
11905    private boolean makeAppCrashingLocked(ProcessRecord app,
11906            String shortMsg, String longMsg, String stackTrace) {
11907        app.crashing = true;
11908        app.crashingReport = generateProcessError(app,
11909                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11910        startAppProblemLocked(app);
11911        app.stopFreezingAllLocked();
11912        return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
11913    }
11914
11915    private void makeAppNotRespondingLocked(ProcessRecord app,
11916            String activity, String shortMsg, String longMsg) {
11917        app.notResponding = true;
11918        app.notRespondingReport = generateProcessError(app,
11919                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11920                activity, shortMsg, longMsg, null);
11921        startAppProblemLocked(app);
11922        app.stopFreezingAllLocked();
11923    }
11924
11925    /**
11926     * Generate a process error record, suitable for attachment to a ProcessRecord.
11927     *
11928     * @param app The ProcessRecord in which the error occurred.
11929     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11930     *                      ActivityManager.AppErrorStateInfo
11931     * @param activity The activity associated with the crash, if known.
11932     * @param shortMsg Short message describing the crash.
11933     * @param longMsg Long message describing the crash.
11934     * @param stackTrace Full crash stack trace, may be null.
11935     *
11936     * @return Returns a fully-formed AppErrorStateInfo record.
11937     */
11938    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11939            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11940        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11941
11942        report.condition = condition;
11943        report.processName = app.processName;
11944        report.pid = app.pid;
11945        report.uid = app.info.uid;
11946        report.tag = activity;
11947        report.shortMsg = shortMsg;
11948        report.longMsg = longMsg;
11949        report.stackTrace = stackTrace;
11950
11951        return report;
11952    }
11953
11954    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11955        synchronized (this) {
11956            app.crashing = false;
11957            app.crashingReport = null;
11958            app.notResponding = false;
11959            app.notRespondingReport = null;
11960            if (app.anrDialog == fromDialog) {
11961                app.anrDialog = null;
11962            }
11963            if (app.waitDialog == fromDialog) {
11964                app.waitDialog = null;
11965            }
11966            if (app.pid > 0 && app.pid != MY_PID) {
11967                handleAppCrashLocked(app, "user-terminated" /*reason*/,
11968                        null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
11969                app.kill("user request after error", true);
11970            }
11971        }
11972    }
11973
11974    private boolean handleAppCrashLocked(ProcessRecord app, String reason,
11975            String shortMsg, String longMsg, String stackTrace) {
11976        long now = SystemClock.uptimeMillis();
11977
11978        Long crashTime;
11979        if (!app.isolated) {
11980            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11981        } else {
11982            crashTime = null;
11983        }
11984        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11985            // This process loses!
11986            Slog.w(TAG, "Process " + app.info.processName
11987                    + " has crashed too many times: killing!");
11988            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11989                    app.userId, app.info.processName, app.uid);
11990            mStackSupervisor.handleAppCrashLocked(app);
11991            if (!app.persistent) {
11992                // We don't want to start this process again until the user
11993                // explicitly does so...  but for persistent process, we really
11994                // need to keep it running.  If a persistent process is actually
11995                // repeatedly crashing, then badness for everyone.
11996                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11997                        app.info.processName);
11998                if (!app.isolated) {
11999                    // XXX We don't have a way to mark isolated processes
12000                    // as bad, since they don't have a peristent identity.
12001                    mBadProcesses.put(app.info.processName, app.uid,
12002                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
12003                    mProcessCrashTimes.remove(app.info.processName, app.uid);
12004                }
12005                app.bad = true;
12006                app.removed = true;
12007                // Don't let services in this process be restarted and potentially
12008                // annoy the user repeatedly.  Unless it is persistent, since those
12009                // processes run critical code.
12010                removeProcessLocked(app, false, false, "crash");
12011                mStackSupervisor.resumeTopActivitiesLocked();
12012                return false;
12013            }
12014            mStackSupervisor.resumeTopActivitiesLocked();
12015        } else {
12016            mStackSupervisor.finishTopRunningActivityLocked(app, reason);
12017        }
12018
12019        // Bump up the crash count of any services currently running in the proc.
12020        for (int i=app.services.size()-1; i>=0; i--) {
12021            // Any services running in the application need to be placed
12022            // back in the pending list.
12023            ServiceRecord sr = app.services.valueAt(i);
12024            sr.crashCount++;
12025        }
12026
12027        // If the crashing process is what we consider to be the "home process" and it has been
12028        // replaced by a third-party app, clear the package preferred activities from packages
12029        // with a home activity running in the process to prevent a repeatedly crashing app
12030        // from blocking the user to manually clear the list.
12031        final ArrayList<ActivityRecord> activities = app.activities;
12032        if (app == mHomeProcess && activities.size() > 0
12033                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
12034            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
12035                final ActivityRecord r = activities.get(activityNdx);
12036                if (r.isHomeActivity()) {
12037                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
12038                    try {
12039                        ActivityThread.getPackageManager()
12040                                .clearPackagePreferredActivities(r.packageName);
12041                    } catch (RemoteException c) {
12042                        // pm is in same process, this will never happen.
12043                    }
12044                }
12045            }
12046        }
12047
12048        if (!app.isolated) {
12049            // XXX Can't keep track of crash times for isolated processes,
12050            // because they don't have a perisistent identity.
12051            mProcessCrashTimes.put(app.info.processName, app.uid, now);
12052        }
12053
12054        if (app.crashHandler != null) mHandler.post(app.crashHandler);
12055        return true;
12056    }
12057
12058    void startAppProblemLocked(ProcessRecord app) {
12059        // If this app is not running under the current user, then we
12060        // can't give it a report button because that would require
12061        // launching the report UI under a different user.
12062        app.errorReportReceiver = null;
12063
12064        for (int userId : mCurrentProfileIds) {
12065            if (app.userId == userId) {
12066                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
12067                        mContext, app.info.packageName, app.info.flags);
12068            }
12069        }
12070        skipCurrentReceiverLocked(app);
12071    }
12072
12073    void skipCurrentReceiverLocked(ProcessRecord app) {
12074        for (BroadcastQueue queue : mBroadcastQueues) {
12075            queue.skipCurrentReceiverLocked(app);
12076        }
12077    }
12078
12079    /**
12080     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12081     * The application process will exit immediately after this call returns.
12082     * @param app object of the crashing app, null for the system server
12083     * @param crashInfo describing the exception
12084     */
12085    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12086        ProcessRecord r = findAppProcess(app, "Crash");
12087        final String processName = app == null ? "system_server"
12088                : (r == null ? "unknown" : r.processName);
12089
12090        handleApplicationCrashInner("crash", r, processName, crashInfo);
12091    }
12092
12093    /* Native crash reporting uses this inner version because it needs to be somewhat
12094     * decoupled from the AM-managed cleanup lifecycle
12095     */
12096    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12097            ApplicationErrorReport.CrashInfo crashInfo) {
12098        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12099                UserHandle.getUserId(Binder.getCallingUid()), processName,
12100                r == null ? -1 : r.info.flags,
12101                crashInfo.exceptionClassName,
12102                crashInfo.exceptionMessage,
12103                crashInfo.throwFileName,
12104                crashInfo.throwLineNumber);
12105
12106        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12107
12108        crashApplication(r, crashInfo);
12109    }
12110
12111    public void handleApplicationStrictModeViolation(
12112            IBinder app,
12113            int violationMask,
12114            StrictMode.ViolationInfo info) {
12115        ProcessRecord r = findAppProcess(app, "StrictMode");
12116        if (r == null) {
12117            return;
12118        }
12119
12120        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12121            Integer stackFingerprint = info.hashCode();
12122            boolean logIt = true;
12123            synchronized (mAlreadyLoggedViolatedStacks) {
12124                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12125                    logIt = false;
12126                    // TODO: sub-sample into EventLog for these, with
12127                    // the info.durationMillis?  Then we'd get
12128                    // the relative pain numbers, without logging all
12129                    // the stack traces repeatedly.  We'd want to do
12130                    // likewise in the client code, which also does
12131                    // dup suppression, before the Binder call.
12132                } else {
12133                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12134                        mAlreadyLoggedViolatedStacks.clear();
12135                    }
12136                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12137                }
12138            }
12139            if (logIt) {
12140                logStrictModeViolationToDropBox(r, info);
12141            }
12142        }
12143
12144        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12145            AppErrorResult result = new AppErrorResult();
12146            synchronized (this) {
12147                final long origId = Binder.clearCallingIdentity();
12148
12149                Message msg = Message.obtain();
12150                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
12151                HashMap<String, Object> data = new HashMap<String, Object>();
12152                data.put("result", result);
12153                data.put("app", r);
12154                data.put("violationMask", violationMask);
12155                data.put("info", info);
12156                msg.obj = data;
12157                mUiHandler.sendMessage(msg);
12158
12159                Binder.restoreCallingIdentity(origId);
12160            }
12161            int res = result.get();
12162            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12163        }
12164    }
12165
12166    // Depending on the policy in effect, there could be a bunch of
12167    // these in quick succession so we try to batch these together to
12168    // minimize disk writes, number of dropbox entries, and maximize
12169    // compression, by having more fewer, larger records.
12170    private void logStrictModeViolationToDropBox(
12171            ProcessRecord process,
12172            StrictMode.ViolationInfo info) {
12173        if (info == null) {
12174            return;
12175        }
12176        final boolean isSystemApp = process == null ||
12177                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12178                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12179        final String processName = process == null ? "unknown" : process.processName;
12180        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12181        final DropBoxManager dbox = (DropBoxManager)
12182                mContext.getSystemService(Context.DROPBOX_SERVICE);
12183
12184        // Exit early if the dropbox isn't configured to accept this report type.
12185        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12186
12187        boolean bufferWasEmpty;
12188        boolean needsFlush;
12189        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12190        synchronized (sb) {
12191            bufferWasEmpty = sb.length() == 0;
12192            appendDropBoxProcessHeaders(process, processName, sb);
12193            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12194            sb.append("System-App: ").append(isSystemApp).append("\n");
12195            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12196            if (info.violationNumThisLoop != 0) {
12197                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12198            }
12199            if (info.numAnimationsRunning != 0) {
12200                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12201            }
12202            if (info.broadcastIntentAction != null) {
12203                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12204            }
12205            if (info.durationMillis != -1) {
12206                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12207            }
12208            if (info.numInstances != -1) {
12209                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12210            }
12211            if (info.tags != null) {
12212                for (String tag : info.tags) {
12213                    sb.append("Span-Tag: ").append(tag).append("\n");
12214                }
12215            }
12216            sb.append("\n");
12217            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
12218                sb.append(info.crashInfo.stackTrace);
12219                sb.append("\n");
12220            }
12221            if (info.message != null) {
12222                sb.append(info.message);
12223                sb.append("\n");
12224            }
12225
12226            // Only buffer up to ~64k.  Various logging bits truncate
12227            // things at 128k.
12228            needsFlush = (sb.length() > 64 * 1024);
12229        }
12230
12231        // Flush immediately if the buffer's grown too large, or this
12232        // is a non-system app.  Non-system apps are isolated with a
12233        // different tag & policy and not batched.
12234        //
12235        // Batching is useful during internal testing with
12236        // StrictMode settings turned up high.  Without batching,
12237        // thousands of separate files could be created on boot.
12238        if (!isSystemApp || needsFlush) {
12239            new Thread("Error dump: " + dropboxTag) {
12240                @Override
12241                public void run() {
12242                    String report;
12243                    synchronized (sb) {
12244                        report = sb.toString();
12245                        sb.delete(0, sb.length());
12246                        sb.trimToSize();
12247                    }
12248                    if (report.length() != 0) {
12249                        dbox.addText(dropboxTag, report);
12250                    }
12251                }
12252            }.start();
12253            return;
12254        }
12255
12256        // System app batching:
12257        if (!bufferWasEmpty) {
12258            // An existing dropbox-writing thread is outstanding, so
12259            // we don't need to start it up.  The existing thread will
12260            // catch the buffer appends we just did.
12261            return;
12262        }
12263
12264        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
12265        // (After this point, we shouldn't access AMS internal data structures.)
12266        new Thread("Error dump: " + dropboxTag) {
12267            @Override
12268            public void run() {
12269                // 5 second sleep to let stacks arrive and be batched together
12270                try {
12271                    Thread.sleep(5000);  // 5 seconds
12272                } catch (InterruptedException e) {}
12273
12274                String errorReport;
12275                synchronized (mStrictModeBuffer) {
12276                    errorReport = mStrictModeBuffer.toString();
12277                    if (errorReport.length() == 0) {
12278                        return;
12279                    }
12280                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
12281                    mStrictModeBuffer.trimToSize();
12282                }
12283                dbox.addText(dropboxTag, errorReport);
12284            }
12285        }.start();
12286    }
12287
12288    /**
12289     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
12290     * @param app object of the crashing app, null for the system server
12291     * @param tag reported by the caller
12292     * @param system whether this wtf is coming from the system
12293     * @param crashInfo describing the context of the error
12294     * @return true if the process should exit immediately (WTF is fatal)
12295     */
12296    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
12297            final ApplicationErrorReport.CrashInfo crashInfo) {
12298        final int callingUid = Binder.getCallingUid();
12299        final int callingPid = Binder.getCallingPid();
12300
12301        if (system) {
12302            // If this is coming from the system, we could very well have low-level
12303            // system locks held, so we want to do this all asynchronously.  And we
12304            // never want this to become fatal, so there is that too.
12305            mHandler.post(new Runnable() {
12306                @Override public void run() {
12307                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
12308                }
12309            });
12310            return false;
12311        }
12312
12313        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
12314                crashInfo);
12315
12316        if (r != null && r.pid != Process.myPid() &&
12317                Settings.Global.getInt(mContext.getContentResolver(),
12318                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
12319            crashApplication(r, crashInfo);
12320            return true;
12321        } else {
12322            return false;
12323        }
12324    }
12325
12326    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
12327            final ApplicationErrorReport.CrashInfo crashInfo) {
12328        final ProcessRecord r = findAppProcess(app, "WTF");
12329        final String processName = app == null ? "system_server"
12330                : (r == null ? "unknown" : r.processName);
12331
12332        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
12333                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
12334
12335        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
12336
12337        return r;
12338    }
12339
12340    /**
12341     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
12342     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
12343     */
12344    private ProcessRecord findAppProcess(IBinder app, String reason) {
12345        if (app == null) {
12346            return null;
12347        }
12348
12349        synchronized (this) {
12350            final int NP = mProcessNames.getMap().size();
12351            for (int ip=0; ip<NP; ip++) {
12352                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12353                final int NA = apps.size();
12354                for (int ia=0; ia<NA; ia++) {
12355                    ProcessRecord p = apps.valueAt(ia);
12356                    if (p.thread != null && p.thread.asBinder() == app) {
12357                        return p;
12358                    }
12359                }
12360            }
12361
12362            Slog.w(TAG, "Can't find mystery application for " + reason
12363                    + " from pid=" + Binder.getCallingPid()
12364                    + " uid=" + Binder.getCallingUid() + ": " + app);
12365            return null;
12366        }
12367    }
12368
12369    /**
12370     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
12371     * to append various headers to the dropbox log text.
12372     */
12373    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
12374            StringBuilder sb) {
12375        // Watchdog thread ends up invoking this function (with
12376        // a null ProcessRecord) to add the stack file to dropbox.
12377        // Do not acquire a lock on this (am) in such cases, as it
12378        // could cause a potential deadlock, if and when watchdog
12379        // is invoked due to unavailability of lock on am and it
12380        // would prevent watchdog from killing system_server.
12381        if (process == null) {
12382            sb.append("Process: ").append(processName).append("\n");
12383            return;
12384        }
12385        // Note: ProcessRecord 'process' is guarded by the service
12386        // instance.  (notably process.pkgList, which could otherwise change
12387        // concurrently during execution of this method)
12388        synchronized (this) {
12389            sb.append("Process: ").append(processName).append("\n");
12390            int flags = process.info.flags;
12391            IPackageManager pm = AppGlobals.getPackageManager();
12392            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
12393            for (int ip=0; ip<process.pkgList.size(); ip++) {
12394                String pkg = process.pkgList.keyAt(ip);
12395                sb.append("Package: ").append(pkg);
12396                try {
12397                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
12398                    if (pi != null) {
12399                        sb.append(" v").append(pi.versionCode);
12400                        if (pi.versionName != null) {
12401                            sb.append(" (").append(pi.versionName).append(")");
12402                        }
12403                    }
12404                } catch (RemoteException e) {
12405                    Slog.e(TAG, "Error getting package info: " + pkg, e);
12406                }
12407                sb.append("\n");
12408            }
12409        }
12410    }
12411
12412    private static String processClass(ProcessRecord process) {
12413        if (process == null || process.pid == MY_PID) {
12414            return "system_server";
12415        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
12416            return "system_app";
12417        } else {
12418            return "data_app";
12419        }
12420    }
12421
12422    /**
12423     * Write a description of an error (crash, WTF, ANR) to the drop box.
12424     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
12425     * @param process which caused the error, null means the system server
12426     * @param activity which triggered the error, null if unknown
12427     * @param parent activity related to the error, null if unknown
12428     * @param subject line related to the error, null if absent
12429     * @param report in long form describing the error, null if absent
12430     * @param logFile to include in the report, null if none
12431     * @param crashInfo giving an application stack trace, null if absent
12432     */
12433    public void addErrorToDropBox(String eventType,
12434            ProcessRecord process, String processName, ActivityRecord activity,
12435            ActivityRecord parent, String subject,
12436            final String report, final File logFile,
12437            final ApplicationErrorReport.CrashInfo crashInfo) {
12438        // NOTE -- this must never acquire the ActivityManagerService lock,
12439        // otherwise the watchdog may be prevented from resetting the system.
12440
12441        final String dropboxTag = processClass(process) + "_" + eventType;
12442        final DropBoxManager dbox = (DropBoxManager)
12443                mContext.getSystemService(Context.DROPBOX_SERVICE);
12444
12445        // Exit early if the dropbox isn't configured to accept this report type.
12446        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12447
12448        final StringBuilder sb = new StringBuilder(1024);
12449        appendDropBoxProcessHeaders(process, processName, sb);
12450        if (activity != null) {
12451            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
12452        }
12453        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
12454            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
12455        }
12456        if (parent != null && parent != activity) {
12457            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
12458        }
12459        if (subject != null) {
12460            sb.append("Subject: ").append(subject).append("\n");
12461        }
12462        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12463        if (Debug.isDebuggerConnected()) {
12464            sb.append("Debugger: Connected\n");
12465        }
12466        sb.append("\n");
12467
12468        // Do the rest in a worker thread to avoid blocking the caller on I/O
12469        // (After this point, we shouldn't access AMS internal data structures.)
12470        Thread worker = new Thread("Error dump: " + dropboxTag) {
12471            @Override
12472            public void run() {
12473                if (report != null) {
12474                    sb.append(report);
12475                }
12476                if (logFile != null) {
12477                    try {
12478                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
12479                                    "\n\n[[TRUNCATED]]"));
12480                    } catch (IOException e) {
12481                        Slog.e(TAG, "Error reading " + logFile, e);
12482                    }
12483                }
12484                if (crashInfo != null && crashInfo.stackTrace != null) {
12485                    sb.append(crashInfo.stackTrace);
12486                }
12487
12488                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
12489                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
12490                if (lines > 0) {
12491                    sb.append("\n");
12492
12493                    // Merge several logcat streams, and take the last N lines
12494                    InputStreamReader input = null;
12495                    try {
12496                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
12497                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
12498                                "-b", "crash",
12499                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
12500
12501                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
12502                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
12503                        input = new InputStreamReader(logcat.getInputStream());
12504
12505                        int num;
12506                        char[] buf = new char[8192];
12507                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
12508                    } catch (IOException e) {
12509                        Slog.e(TAG, "Error running logcat", e);
12510                    } finally {
12511                        if (input != null) try { input.close(); } catch (IOException e) {}
12512                    }
12513                }
12514
12515                dbox.addText(dropboxTag, sb.toString());
12516            }
12517        };
12518
12519        if (process == null) {
12520            // If process is null, we are being called from some internal code
12521            // and may be about to die -- run this synchronously.
12522            worker.run();
12523        } else {
12524            worker.start();
12525        }
12526    }
12527
12528    /**
12529     * Bring up the "unexpected error" dialog box for a crashing app.
12530     * Deal with edge cases (intercepts from instrumented applications,
12531     * ActivityController, error intent receivers, that sort of thing).
12532     * @param r the application crashing
12533     * @param crashInfo describing the failure
12534     */
12535    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12536        long timeMillis = System.currentTimeMillis();
12537        String shortMsg = crashInfo.exceptionClassName;
12538        String longMsg = crashInfo.exceptionMessage;
12539        String stackTrace = crashInfo.stackTrace;
12540        if (shortMsg != null && longMsg != null) {
12541            longMsg = shortMsg + ": " + longMsg;
12542        } else if (shortMsg != null) {
12543            longMsg = shortMsg;
12544        }
12545
12546        AppErrorResult result = new AppErrorResult();
12547        synchronized (this) {
12548            if (mController != null) {
12549                try {
12550                    String name = r != null ? r.processName : null;
12551                    int pid = r != null ? r.pid : Binder.getCallingPid();
12552                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
12553                    if (!mController.appCrashed(name, pid,
12554                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12555                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12556                                && "Native crash".equals(crashInfo.exceptionClassName)) {
12557                            Slog.w(TAG, "Skip killing native crashed app " + name
12558                                    + "(" + pid + ") during testing");
12559                        } else {
12560                            Slog.w(TAG, "Force-killing crashed app " + name
12561                                    + " at watcher's request");
12562                            if (r != null) {
12563                                r.kill("crash", true);
12564                            } else {
12565                                // Huh.
12566                                Process.killProcess(pid);
12567                                killProcessGroup(uid, pid);
12568                            }
12569                        }
12570                        return;
12571                    }
12572                } catch (RemoteException e) {
12573                    mController = null;
12574                    Watchdog.getInstance().setActivityController(null);
12575                }
12576            }
12577
12578            final long origId = Binder.clearCallingIdentity();
12579
12580            // If this process is running instrumentation, finish it.
12581            if (r != null && r.instrumentationClass != null) {
12582                Slog.w(TAG, "Error in app " + r.processName
12583                      + " running instrumentation " + r.instrumentationClass + ":");
12584                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12585                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12586                Bundle info = new Bundle();
12587                info.putString("shortMsg", shortMsg);
12588                info.putString("longMsg", longMsg);
12589                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12590                Binder.restoreCallingIdentity(origId);
12591                return;
12592            }
12593
12594            // Log crash in battery stats.
12595            if (r != null) {
12596                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12597            }
12598
12599            // If we can't identify the process or it's already exceeded its crash quota,
12600            // quit right away without showing a crash dialog.
12601            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12602                Binder.restoreCallingIdentity(origId);
12603                return;
12604            }
12605
12606            Message msg = Message.obtain();
12607            msg.what = SHOW_ERROR_MSG;
12608            HashMap data = new HashMap();
12609            data.put("result", result);
12610            data.put("app", r);
12611            msg.obj = data;
12612            mUiHandler.sendMessage(msg);
12613
12614            Binder.restoreCallingIdentity(origId);
12615        }
12616
12617        int res = result.get();
12618
12619        Intent appErrorIntent = null;
12620        synchronized (this) {
12621            if (r != null && !r.isolated) {
12622                // XXX Can't keep track of crash time for isolated processes,
12623                // since they don't have a persistent identity.
12624                mProcessCrashTimes.put(r.info.processName, r.uid,
12625                        SystemClock.uptimeMillis());
12626            }
12627            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12628                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12629            }
12630        }
12631
12632        if (appErrorIntent != null) {
12633            try {
12634                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12635            } catch (ActivityNotFoundException e) {
12636                Slog.w(TAG, "bug report receiver dissappeared", e);
12637            }
12638        }
12639    }
12640
12641    Intent createAppErrorIntentLocked(ProcessRecord r,
12642            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12643        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12644        if (report == null) {
12645            return null;
12646        }
12647        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12648        result.setComponent(r.errorReportReceiver);
12649        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12650        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12651        return result;
12652    }
12653
12654    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12655            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12656        if (r.errorReportReceiver == null) {
12657            return null;
12658        }
12659
12660        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12661            return null;
12662        }
12663
12664        ApplicationErrorReport report = new ApplicationErrorReport();
12665        report.packageName = r.info.packageName;
12666        report.installerPackageName = r.errorReportReceiver.getPackageName();
12667        report.processName = r.processName;
12668        report.time = timeMillis;
12669        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12670
12671        if (r.crashing || r.forceCrashReport) {
12672            report.type = ApplicationErrorReport.TYPE_CRASH;
12673            report.crashInfo = crashInfo;
12674        } else if (r.notResponding) {
12675            report.type = ApplicationErrorReport.TYPE_ANR;
12676            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12677
12678            report.anrInfo.activity = r.notRespondingReport.tag;
12679            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12680            report.anrInfo.info = r.notRespondingReport.longMsg;
12681        }
12682
12683        return report;
12684    }
12685
12686    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12687        enforceNotIsolatedCaller("getProcessesInErrorState");
12688        // assume our apps are happy - lazy create the list
12689        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12690
12691        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12692                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12693        int userId = UserHandle.getUserId(Binder.getCallingUid());
12694
12695        synchronized (this) {
12696
12697            // iterate across all processes
12698            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12699                ProcessRecord app = mLruProcesses.get(i);
12700                if (!allUsers && app.userId != userId) {
12701                    continue;
12702                }
12703                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12704                    // This one's in trouble, so we'll generate a report for it
12705                    // crashes are higher priority (in case there's a crash *and* an anr)
12706                    ActivityManager.ProcessErrorStateInfo report = null;
12707                    if (app.crashing) {
12708                        report = app.crashingReport;
12709                    } else if (app.notResponding) {
12710                        report = app.notRespondingReport;
12711                    }
12712
12713                    if (report != null) {
12714                        if (errList == null) {
12715                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12716                        }
12717                        errList.add(report);
12718                    } else {
12719                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12720                                " crashing = " + app.crashing +
12721                                " notResponding = " + app.notResponding);
12722                    }
12723                }
12724            }
12725        }
12726
12727        return errList;
12728    }
12729
12730    static int procStateToImportance(int procState, int memAdj,
12731            ActivityManager.RunningAppProcessInfo currApp) {
12732        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12733        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12734            currApp.lru = memAdj;
12735        } else {
12736            currApp.lru = 0;
12737        }
12738        return imp;
12739    }
12740
12741    private void fillInProcMemInfo(ProcessRecord app,
12742            ActivityManager.RunningAppProcessInfo outInfo) {
12743        outInfo.pid = app.pid;
12744        outInfo.uid = app.info.uid;
12745        if (mHeavyWeightProcess == app) {
12746            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12747        }
12748        if (app.persistent) {
12749            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12750        }
12751        if (app.activities.size() > 0) {
12752            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12753        }
12754        outInfo.lastTrimLevel = app.trimMemoryLevel;
12755        int adj = app.curAdj;
12756        int procState = app.curProcState;
12757        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12758        outInfo.importanceReasonCode = app.adjTypeCode;
12759        outInfo.processState = app.curProcState;
12760    }
12761
12762    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12763        enforceNotIsolatedCaller("getRunningAppProcesses");
12764
12765        final int callingUid = Binder.getCallingUid();
12766
12767        // Lazy instantiation of list
12768        List<ActivityManager.RunningAppProcessInfo> runList = null;
12769        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12770                callingUid) == PackageManager.PERMISSION_GRANTED;
12771        final int userId = UserHandle.getUserId(callingUid);
12772        final boolean allUids = isGetTasksAllowed(
12773                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
12774
12775        synchronized (this) {
12776            // Iterate across all processes
12777            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
12778                ProcessRecord app = mLruProcesses.get(i);
12779                if ((!allUsers && app.userId != userId)
12780                        || (!allUids && app.uid != callingUid)) {
12781                    continue;
12782                }
12783                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12784                    // Generate process state info for running application
12785                    ActivityManager.RunningAppProcessInfo currApp =
12786                        new ActivityManager.RunningAppProcessInfo(app.processName,
12787                                app.pid, app.getPackageList());
12788                    fillInProcMemInfo(app, currApp);
12789                    if (app.adjSource instanceof ProcessRecord) {
12790                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12791                        currApp.importanceReasonImportance =
12792                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12793                                        app.adjSourceProcState);
12794                    } else if (app.adjSource instanceof ActivityRecord) {
12795                        ActivityRecord r = (ActivityRecord)app.adjSource;
12796                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12797                    }
12798                    if (app.adjTarget instanceof ComponentName) {
12799                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12800                    }
12801                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12802                    //        + " lru=" + currApp.lru);
12803                    if (runList == null) {
12804                        runList = new ArrayList<>();
12805                    }
12806                    runList.add(currApp);
12807                }
12808            }
12809        }
12810        return runList;
12811    }
12812
12813    public List<ApplicationInfo> getRunningExternalApplications() {
12814        enforceNotIsolatedCaller("getRunningExternalApplications");
12815        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12816        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12817        if (runningApps != null && runningApps.size() > 0) {
12818            Set<String> extList = new HashSet<String>();
12819            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12820                if (app.pkgList != null) {
12821                    for (String pkg : app.pkgList) {
12822                        extList.add(pkg);
12823                    }
12824                }
12825            }
12826            IPackageManager pm = AppGlobals.getPackageManager();
12827            for (String pkg : extList) {
12828                try {
12829                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12830                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12831                        retList.add(info);
12832                    }
12833                } catch (RemoteException e) {
12834                }
12835            }
12836        }
12837        return retList;
12838    }
12839
12840    @Override
12841    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12842        enforceNotIsolatedCaller("getMyMemoryState");
12843        synchronized (this) {
12844            ProcessRecord proc;
12845            synchronized (mPidsSelfLocked) {
12846                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12847            }
12848            fillInProcMemInfo(proc, outInfo);
12849        }
12850    }
12851
12852    @Override
12853    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12854        if (checkCallingPermission(android.Manifest.permission.DUMP)
12855                != PackageManager.PERMISSION_GRANTED) {
12856            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12857                    + Binder.getCallingPid()
12858                    + ", uid=" + Binder.getCallingUid()
12859                    + " without permission "
12860                    + android.Manifest.permission.DUMP);
12861            return;
12862        }
12863
12864        boolean dumpAll = false;
12865        boolean dumpClient = false;
12866        String dumpPackage = null;
12867
12868        int opti = 0;
12869        while (opti < args.length) {
12870            String opt = args[opti];
12871            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12872                break;
12873            }
12874            opti++;
12875            if ("-a".equals(opt)) {
12876                dumpAll = true;
12877            } else if ("-c".equals(opt)) {
12878                dumpClient = true;
12879            } else if ("-p".equals(opt)) {
12880                if (opti < args.length) {
12881                    dumpPackage = args[opti];
12882                    opti++;
12883                } else {
12884                    pw.println("Error: -p option requires package argument");
12885                    return;
12886                }
12887                dumpClient = true;
12888            } else if ("-h".equals(opt)) {
12889                pw.println("Activity manager dump options:");
12890                pw.println("  [-a] [-c] [-p package] [-h] [cmd] ...");
12891                pw.println("  cmd may be one of:");
12892                pw.println("    a[ctivities]: activity stack state");
12893                pw.println("    r[recents]: recent activities state");
12894                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12895                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12896                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12897                pw.println("    o[om]: out of memory management");
12898                pw.println("    perm[issions]: URI permission grant state");
12899                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12900                pw.println("    provider [COMP_SPEC]: provider client-side state");
12901                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12902                pw.println("    as[sociations]: tracked app associations");
12903                pw.println("    service [COMP_SPEC]: service client-side state");
12904                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12905                pw.println("    all: dump all activities");
12906                pw.println("    top: dump the top activity");
12907                pw.println("    write: write all pending state to storage");
12908                pw.println("    track-associations: enable association tracking");
12909                pw.println("    untrack-associations: disable and clear association tracking");
12910                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12911                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12912                pw.println("    a partial substring in a component name, a");
12913                pw.println("    hex object identifier.");
12914                pw.println("  -a: include all available server state.");
12915                pw.println("  -c: include client state.");
12916                pw.println("  -p: limit output to given package.");
12917                return;
12918            } else {
12919                pw.println("Unknown argument: " + opt + "; use -h for help");
12920            }
12921        }
12922
12923        long origId = Binder.clearCallingIdentity();
12924        boolean more = false;
12925        // Is the caller requesting to dump a particular piece of data?
12926        if (opti < args.length) {
12927            String cmd = args[opti];
12928            opti++;
12929            if ("activities".equals(cmd) || "a".equals(cmd)) {
12930                synchronized (this) {
12931                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12932                }
12933            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12934                synchronized (this) {
12935                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
12936                }
12937            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12938                String[] newArgs;
12939                String name;
12940                if (opti >= args.length) {
12941                    name = null;
12942                    newArgs = EMPTY_STRING_ARRAY;
12943                } else {
12944                    dumpPackage = args[opti];
12945                    opti++;
12946                    newArgs = new String[args.length - opti];
12947                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12948                            args.length - opti);
12949                }
12950                synchronized (this) {
12951                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
12952                }
12953            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12954                String[] newArgs;
12955                String name;
12956                if (opti >= args.length) {
12957                    name = null;
12958                    newArgs = EMPTY_STRING_ARRAY;
12959                } else {
12960                    dumpPackage = args[opti];
12961                    opti++;
12962                    newArgs = new String[args.length - opti];
12963                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12964                            args.length - opti);
12965                }
12966                synchronized (this) {
12967                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
12968                }
12969            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12970                String[] newArgs;
12971                String name;
12972                if (opti >= args.length) {
12973                    name = null;
12974                    newArgs = EMPTY_STRING_ARRAY;
12975                } else {
12976                    dumpPackage = args[opti];
12977                    opti++;
12978                    newArgs = new String[args.length - opti];
12979                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12980                            args.length - opti);
12981                }
12982                synchronized (this) {
12983                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
12984                }
12985            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12986                synchronized (this) {
12987                    dumpOomLocked(fd, pw, args, opti, true);
12988                }
12989            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
12990                synchronized (this) {
12991                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
12992                }
12993            } else if ("provider".equals(cmd)) {
12994                String[] newArgs;
12995                String name;
12996                if (opti >= args.length) {
12997                    name = null;
12998                    newArgs = EMPTY_STRING_ARRAY;
12999                } else {
13000                    name = args[opti];
13001                    opti++;
13002                    newArgs = new String[args.length - opti];
13003                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13004                }
13005                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13006                    pw.println("No providers match: " + name);
13007                    pw.println("Use -h for help.");
13008                }
13009            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13010                synchronized (this) {
13011                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13012                }
13013            } else if ("service".equals(cmd)) {
13014                String[] newArgs;
13015                String name;
13016                if (opti >= args.length) {
13017                    name = null;
13018                    newArgs = EMPTY_STRING_ARRAY;
13019                } else {
13020                    name = args[opti];
13021                    opti++;
13022                    newArgs = new String[args.length - opti];
13023                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13024                            args.length - opti);
13025                }
13026                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13027                    pw.println("No services match: " + name);
13028                    pw.println("Use -h for help.");
13029                }
13030            } else if ("package".equals(cmd)) {
13031                String[] newArgs;
13032                if (opti >= args.length) {
13033                    pw.println("package: no package name specified");
13034                    pw.println("Use -h for help.");
13035                } else {
13036                    dumpPackage = args[opti];
13037                    opti++;
13038                    newArgs = new String[args.length - opti];
13039                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13040                            args.length - opti);
13041                    args = newArgs;
13042                    opti = 0;
13043                    more = true;
13044                }
13045            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13046                synchronized (this) {
13047                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13048                }
13049            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13050                synchronized (this) {
13051                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13052                }
13053            } else if ("write".equals(cmd)) {
13054                mTaskPersister.flush();
13055                pw.println("All tasks persisted.");
13056                return;
13057            } else if ("track-associations".equals(cmd)) {
13058                synchronized (this) {
13059                    if (!mTrackingAssociations) {
13060                        mTrackingAssociations = true;
13061                        pw.println("Association tracking started.");
13062                    } else {
13063                        pw.println("Association tracking already enabled.");
13064                    }
13065                }
13066                return;
13067            } else if ("untrack-associations".equals(cmd)) {
13068                synchronized (this) {
13069                    if (mTrackingAssociations) {
13070                        mTrackingAssociations = false;
13071                        mAssociations.clear();
13072                        pw.println("Association tracking stopped.");
13073                    } else {
13074                        pw.println("Association tracking not running.");
13075                    }
13076                }
13077                return;
13078            } else {
13079                // Dumping a single activity?
13080                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13081                    pw.println("Bad activity command, or no activities match: " + cmd);
13082                    pw.println("Use -h for help.");
13083                }
13084            }
13085            if (!more) {
13086                Binder.restoreCallingIdentity(origId);
13087                return;
13088            }
13089        }
13090
13091        // No piece of data specified, dump everything.
13092        synchronized (this) {
13093            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13094            pw.println();
13095            if (dumpAll) {
13096                pw.println("-------------------------------------------------------------------------------");
13097            }
13098            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13099            pw.println();
13100            if (dumpAll) {
13101                pw.println("-------------------------------------------------------------------------------");
13102            }
13103            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13104            pw.println();
13105            if (dumpAll) {
13106                pw.println("-------------------------------------------------------------------------------");
13107            }
13108            dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13109            pw.println();
13110            if (dumpAll) {
13111                pw.println("-------------------------------------------------------------------------------");
13112            }
13113            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13114            pw.println();
13115            if (dumpAll) {
13116                pw.println("-------------------------------------------------------------------------------");
13117            }
13118            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13119            pw.println();
13120            if (dumpAll) {
13121                pw.println("-------------------------------------------------------------------------------");
13122            }
13123            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13124            if (mAssociations.size() > 0) {
13125                pw.println();
13126                if (dumpAll) {
13127                    pw.println("-------------------------------------------------------------------------------");
13128                }
13129                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13130            }
13131            pw.println();
13132            if (dumpAll) {
13133                pw.println("-------------------------------------------------------------------------------");
13134            }
13135            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13136        }
13137        Binder.restoreCallingIdentity(origId);
13138    }
13139
13140    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13141            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13142        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13143
13144        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13145                dumpPackage);
13146        boolean needSep = printedAnything;
13147
13148        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13149                dumpPackage, needSep, "  mFocusedActivity: ");
13150        if (printed) {
13151            printedAnything = true;
13152            needSep = false;
13153        }
13154
13155        if (dumpPackage == null) {
13156            if (needSep) {
13157                pw.println();
13158            }
13159            needSep = true;
13160            printedAnything = true;
13161            mStackSupervisor.dump(pw, "  ");
13162        }
13163
13164        if (!printedAnything) {
13165            pw.println("  (nothing)");
13166        }
13167    }
13168
13169    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13170            int opti, boolean dumpAll, String dumpPackage) {
13171        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13172
13173        boolean printedAnything = false;
13174
13175        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13176            boolean printedHeader = false;
13177
13178            final int N = mRecentTasks.size();
13179            for (int i=0; i<N; i++) {
13180                TaskRecord tr = mRecentTasks.get(i);
13181                if (dumpPackage != null) {
13182                    if (tr.realActivity == null ||
13183                            !dumpPackage.equals(tr.realActivity)) {
13184                        continue;
13185                    }
13186                }
13187                if (!printedHeader) {
13188                    pw.println("  Recent tasks:");
13189                    printedHeader = true;
13190                    printedAnything = true;
13191                }
13192                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13193                        pw.println(tr);
13194                if (dumpAll) {
13195                    mRecentTasks.get(i).dump(pw, "    ");
13196                }
13197            }
13198        }
13199
13200        if (!printedAnything) {
13201            pw.println("  (nothing)");
13202        }
13203    }
13204
13205    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13206            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13207        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13208
13209        int dumpUid = 0;
13210        if (dumpPackage != null) {
13211            IPackageManager pm = AppGlobals.getPackageManager();
13212            try {
13213                dumpUid = pm.getPackageUid(dumpPackage, 0);
13214            } catch (RemoteException e) {
13215            }
13216        }
13217
13218        boolean printedAnything = false;
13219
13220        final long now = SystemClock.uptimeMillis();
13221
13222        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13223            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13224                    = mAssociations.valueAt(i1);
13225            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13226                SparseArray<ArrayMap<String, Association>> sourceUids
13227                        = targetComponents.valueAt(i2);
13228                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13229                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13230                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13231                        Association ass = sourceProcesses.valueAt(i4);
13232                        if (dumpPackage != null) {
13233                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13234                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13235                                continue;
13236                            }
13237                        }
13238                        printedAnything = true;
13239                        pw.print("  ");
13240                        pw.print(ass.mTargetProcess);
13241                        pw.print("/");
13242                        UserHandle.formatUid(pw, ass.mTargetUid);
13243                        pw.print(" <- ");
13244                        pw.print(ass.mSourceProcess);
13245                        pw.print("/");
13246                        UserHandle.formatUid(pw, ass.mSourceUid);
13247                        pw.println();
13248                        pw.print("    via ");
13249                        pw.print(ass.mTargetComponent.flattenToShortString());
13250                        pw.println();
13251                        pw.print("    ");
13252                        long dur = ass.mTime;
13253                        if (ass.mNesting > 0) {
13254                            dur += now - ass.mStartTime;
13255                        }
13256                        TimeUtils.formatDuration(dur, pw);
13257                        pw.print(" (");
13258                        pw.print(ass.mCount);
13259                        pw.println(" times)");
13260                        if (ass.mNesting > 0) {
13261                            pw.print("    ");
13262                            pw.print(" Currently active: ");
13263                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13264                            pw.println();
13265                        }
13266                    }
13267                }
13268            }
13269
13270        }
13271
13272        if (!printedAnything) {
13273            pw.println("  (nothing)");
13274        }
13275    }
13276
13277    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13278            int opti, boolean dumpAll, String dumpPackage) {
13279        boolean needSep = false;
13280        boolean printedAnything = false;
13281        int numPers = 0;
13282
13283        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13284
13285        if (dumpAll) {
13286            final int NP = mProcessNames.getMap().size();
13287            for (int ip=0; ip<NP; ip++) {
13288                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13289                final int NA = procs.size();
13290                for (int ia=0; ia<NA; ia++) {
13291                    ProcessRecord r = procs.valueAt(ia);
13292                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13293                        continue;
13294                    }
13295                    if (!needSep) {
13296                        pw.println("  All known processes:");
13297                        needSep = true;
13298                        printedAnything = true;
13299                    }
13300                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13301                        pw.print(" UID "); pw.print(procs.keyAt(ia));
13302                        pw.print(" "); pw.println(r);
13303                    r.dump(pw, "    ");
13304                    if (r.persistent) {
13305                        numPers++;
13306                    }
13307                }
13308            }
13309        }
13310
13311        if (mIsolatedProcesses.size() > 0) {
13312            boolean printed = false;
13313            for (int i=0; i<mIsolatedProcesses.size(); i++) {
13314                ProcessRecord r = mIsolatedProcesses.valueAt(i);
13315                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13316                    continue;
13317                }
13318                if (!printed) {
13319                    if (needSep) {
13320                        pw.println();
13321                    }
13322                    pw.println("  Isolated process list (sorted by uid):");
13323                    printedAnything = true;
13324                    printed = true;
13325                    needSep = true;
13326                }
13327                pw.println(String.format("%sIsolated #%2d: %s",
13328                        "    ", i, r.toString()));
13329            }
13330        }
13331
13332        if (mActiveUids.size() > 0) {
13333            if (needSep) {
13334                pw.println();
13335            }
13336            pw.println("  UID states:");
13337            for (int i=0; i<mActiveUids.size(); i++) {
13338                UidRecord uidRec = mActiveUids.valueAt(i);
13339                pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13340                pw.print(": "); pw.println(uidRec);
13341            }
13342            needSep = true;
13343            printedAnything = true;
13344        }
13345
13346        if (mLruProcesses.size() > 0) {
13347            if (needSep) {
13348                pw.println();
13349            }
13350            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
13351                    pw.print(" total, non-act at ");
13352                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13353                    pw.print(", non-svc at ");
13354                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13355                    pw.println("):");
13356            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
13357            needSep = true;
13358            printedAnything = true;
13359        }
13360
13361        if (dumpAll || dumpPackage != null) {
13362            synchronized (mPidsSelfLocked) {
13363                boolean printed = false;
13364                for (int i=0; i<mPidsSelfLocked.size(); i++) {
13365                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
13366                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13367                        continue;
13368                    }
13369                    if (!printed) {
13370                        if (needSep) pw.println();
13371                        needSep = true;
13372                        pw.println("  PID mappings:");
13373                        printed = true;
13374                        printedAnything = true;
13375                    }
13376                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
13377                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
13378                }
13379            }
13380        }
13381
13382        if (mForegroundProcesses.size() > 0) {
13383            synchronized (mPidsSelfLocked) {
13384                boolean printed = false;
13385                for (int i=0; i<mForegroundProcesses.size(); i++) {
13386                    ProcessRecord r = mPidsSelfLocked.get(
13387                            mForegroundProcesses.valueAt(i).pid);
13388                    if (dumpPackage != null && (r == null
13389                            || !r.pkgList.containsKey(dumpPackage))) {
13390                        continue;
13391                    }
13392                    if (!printed) {
13393                        if (needSep) pw.println();
13394                        needSep = true;
13395                        pw.println("  Foreground Processes:");
13396                        printed = true;
13397                        printedAnything = true;
13398                    }
13399                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
13400                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
13401                }
13402            }
13403        }
13404
13405        if (mPersistentStartingProcesses.size() > 0) {
13406            if (needSep) pw.println();
13407            needSep = true;
13408            printedAnything = true;
13409            pw.println("  Persisent processes that are starting:");
13410            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
13411                    "Starting Norm", "Restarting PERS", dumpPackage);
13412        }
13413
13414        if (mRemovedProcesses.size() > 0) {
13415            if (needSep) pw.println();
13416            needSep = true;
13417            printedAnything = true;
13418            pw.println("  Processes that are being removed:");
13419            dumpProcessList(pw, this, mRemovedProcesses, "    ",
13420                    "Removed Norm", "Removed PERS", dumpPackage);
13421        }
13422
13423        if (mProcessesOnHold.size() > 0) {
13424            if (needSep) pw.println();
13425            needSep = true;
13426            printedAnything = true;
13427            pw.println("  Processes that are on old until the system is ready:");
13428            dumpProcessList(pw, this, mProcessesOnHold, "    ",
13429                    "OnHold Norm", "OnHold PERS", dumpPackage);
13430        }
13431
13432        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
13433
13434        if (mProcessCrashTimes.getMap().size() > 0) {
13435            boolean printed = false;
13436            long now = SystemClock.uptimeMillis();
13437            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
13438            final int NP = pmap.size();
13439            for (int ip=0; ip<NP; ip++) {
13440                String pname = pmap.keyAt(ip);
13441                SparseArray<Long> uids = pmap.valueAt(ip);
13442                final int N = uids.size();
13443                for (int i=0; i<N; i++) {
13444                    int puid = uids.keyAt(i);
13445                    ProcessRecord r = mProcessNames.get(pname, puid);
13446                    if (dumpPackage != null && (r == null
13447                            || !r.pkgList.containsKey(dumpPackage))) {
13448                        continue;
13449                    }
13450                    if (!printed) {
13451                        if (needSep) pw.println();
13452                        needSep = true;
13453                        pw.println("  Time since processes crashed:");
13454                        printed = true;
13455                        printedAnything = true;
13456                    }
13457                    pw.print("    Process "); pw.print(pname);
13458                            pw.print(" uid "); pw.print(puid);
13459                            pw.print(": last crashed ");
13460                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
13461                            pw.println(" ago");
13462                }
13463            }
13464        }
13465
13466        if (mBadProcesses.getMap().size() > 0) {
13467            boolean printed = false;
13468            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
13469            final int NP = pmap.size();
13470            for (int ip=0; ip<NP; ip++) {
13471                String pname = pmap.keyAt(ip);
13472                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
13473                final int N = uids.size();
13474                for (int i=0; i<N; i++) {
13475                    int puid = uids.keyAt(i);
13476                    ProcessRecord r = mProcessNames.get(pname, puid);
13477                    if (dumpPackage != null && (r == null
13478                            || !r.pkgList.containsKey(dumpPackage))) {
13479                        continue;
13480                    }
13481                    if (!printed) {
13482                        if (needSep) pw.println();
13483                        needSep = true;
13484                        pw.println("  Bad processes:");
13485                        printedAnything = true;
13486                    }
13487                    BadProcessInfo info = uids.valueAt(i);
13488                    pw.print("    Bad process "); pw.print(pname);
13489                            pw.print(" uid "); pw.print(puid);
13490                            pw.print(": crashed at time "); pw.println(info.time);
13491                    if (info.shortMsg != null) {
13492                        pw.print("      Short msg: "); pw.println(info.shortMsg);
13493                    }
13494                    if (info.longMsg != null) {
13495                        pw.print("      Long msg: "); pw.println(info.longMsg);
13496                    }
13497                    if (info.stack != null) {
13498                        pw.println("      Stack:");
13499                        int lastPos = 0;
13500                        for (int pos=0; pos<info.stack.length(); pos++) {
13501                            if (info.stack.charAt(pos) == '\n') {
13502                                pw.print("        ");
13503                                pw.write(info.stack, lastPos, pos-lastPos);
13504                                pw.println();
13505                                lastPos = pos+1;
13506                            }
13507                        }
13508                        if (lastPos < info.stack.length()) {
13509                            pw.print("        ");
13510                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
13511                            pw.println();
13512                        }
13513                    }
13514                }
13515            }
13516        }
13517
13518        if (dumpPackage == null) {
13519            pw.println();
13520            needSep = false;
13521            pw.println("  mStartedUsers:");
13522            for (int i=0; i<mStartedUsers.size(); i++) {
13523                UserState uss = mStartedUsers.valueAt(i);
13524                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
13525                        pw.print(": "); uss.dump("", pw);
13526            }
13527            pw.print("  mStartedUserArray: [");
13528            for (int i=0; i<mStartedUserArray.length; i++) {
13529                if (i > 0) pw.print(", ");
13530                pw.print(mStartedUserArray[i]);
13531            }
13532            pw.println("]");
13533            pw.print("  mUserLru: [");
13534            for (int i=0; i<mUserLru.size(); i++) {
13535                if (i > 0) pw.print(", ");
13536                pw.print(mUserLru.get(i));
13537            }
13538            pw.println("]");
13539            if (dumpAll) {
13540                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
13541            }
13542            synchronized (mUserProfileGroupIdsSelfLocked) {
13543                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
13544                    pw.println("  mUserProfileGroupIds:");
13545                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
13546                        pw.print("    User #");
13547                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
13548                        pw.print(" -> profile #");
13549                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
13550                    }
13551                }
13552            }
13553        }
13554        if (mHomeProcess != null && (dumpPackage == null
13555                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13556            if (needSep) {
13557                pw.println();
13558                needSep = false;
13559            }
13560            pw.println("  mHomeProcess: " + mHomeProcess);
13561        }
13562        if (mPreviousProcess != null && (dumpPackage == null
13563                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13564            if (needSep) {
13565                pw.println();
13566                needSep = false;
13567            }
13568            pw.println("  mPreviousProcess: " + mPreviousProcess);
13569        }
13570        if (dumpAll) {
13571            StringBuilder sb = new StringBuilder(128);
13572            sb.append("  mPreviousProcessVisibleTime: ");
13573            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13574            pw.println(sb);
13575        }
13576        if (mHeavyWeightProcess != null && (dumpPackage == null
13577                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13578            if (needSep) {
13579                pw.println();
13580                needSep = false;
13581            }
13582            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13583        }
13584        if (dumpPackage == null) {
13585            pw.println("  mConfiguration: " + mConfiguration);
13586        }
13587        if (dumpAll) {
13588            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13589            if (mCompatModePackages.getPackages().size() > 0) {
13590                boolean printed = false;
13591                for (Map.Entry<String, Integer> entry
13592                        : mCompatModePackages.getPackages().entrySet()) {
13593                    String pkg = entry.getKey();
13594                    int mode = entry.getValue();
13595                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
13596                        continue;
13597                    }
13598                    if (!printed) {
13599                        pw.println("  mScreenCompatPackages:");
13600                        printed = true;
13601                    }
13602                    pw.print("    "); pw.print(pkg); pw.print(": ");
13603                            pw.print(mode); pw.println();
13604                }
13605            }
13606        }
13607        if (dumpPackage == null) {
13608            pw.println("  mWakefulness="
13609                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
13610            pw.println("  mSleepTokens=" + mSleepTokens);
13611            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
13612                    + lockScreenShownToString());
13613            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
13614            if (mRunningVoice != null) {
13615                pw.println("  mRunningVoice=" + mRunningVoice);
13616                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
13617            }
13618        }
13619        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
13620                || mOrigWaitForDebugger) {
13621            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
13622                    || dumpPackage.equals(mOrigDebugApp)) {
13623                if (needSep) {
13624                    pw.println();
13625                    needSep = false;
13626                }
13627                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
13628                        + " mDebugTransient=" + mDebugTransient
13629                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
13630            }
13631        }
13632        if (mCurAppTimeTracker != null) {
13633            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
13634        }
13635        if (mMemWatchProcesses.getMap().size() > 0) {
13636            pw.println("  Mem watch processes:");
13637            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
13638                    = mMemWatchProcesses.getMap();
13639            for (int i=0; i<procs.size(); i++) {
13640                final String proc = procs.keyAt(i);
13641                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
13642                for (int j=0; j<uids.size(); j++) {
13643                    if (needSep) {
13644                        pw.println();
13645                        needSep = false;
13646                    }
13647                    StringBuilder sb = new StringBuilder();
13648                    sb.append("    ").append(proc).append('/');
13649                    UserHandle.formatUid(sb, uids.keyAt(j));
13650                    Pair<Long, String> val = uids.valueAt(j);
13651                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
13652                    if (val.second != null) {
13653                        sb.append(", report to ").append(val.second);
13654                    }
13655                    pw.println(sb.toString());
13656                }
13657            }
13658            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
13659            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
13660            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
13661                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
13662        }
13663        if (mOpenGlTraceApp != null) {
13664            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
13665                if (needSep) {
13666                    pw.println();
13667                    needSep = false;
13668                }
13669                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
13670            }
13671        }
13672        if (mTrackAllocationApp != null) {
13673            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
13674                if (needSep) {
13675                    pw.println();
13676                    needSep = false;
13677                }
13678                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
13679            }
13680        }
13681        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
13682                || mProfileFd != null) {
13683            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13684                if (needSep) {
13685                    pw.println();
13686                    needSep = false;
13687                }
13688                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13689                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13690                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13691                        + mAutoStopProfiler);
13692                pw.println("  mProfileType=" + mProfileType);
13693            }
13694        }
13695        if (dumpPackage == null) {
13696            if (mAlwaysFinishActivities || mController != null) {
13697                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
13698                        + " mController=" + mController);
13699            }
13700            if (dumpAll) {
13701                pw.println("  Total persistent processes: " + numPers);
13702                pw.println("  mProcessesReady=" + mProcessesReady
13703                        + " mSystemReady=" + mSystemReady
13704                        + " mBooted=" + mBooted
13705                        + " mFactoryTest=" + mFactoryTest);
13706                pw.println("  mBooting=" + mBooting
13707                        + " mCallFinishBooting=" + mCallFinishBooting
13708                        + " mBootAnimationComplete=" + mBootAnimationComplete);
13709                pw.print("  mLastPowerCheckRealtime=");
13710                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13711                        pw.println("");
13712                pw.print("  mLastPowerCheckUptime=");
13713                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13714                        pw.println("");
13715                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13716                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13717                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13718                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
13719                        + " (" + mLruProcesses.size() + " total)"
13720                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13721                        + " mNumServiceProcs=" + mNumServiceProcs
13722                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13723                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
13724                        + " mLastMemoryLevel" + mLastMemoryLevel
13725                        + " mLastNumProcesses" + mLastNumProcesses);
13726                long now = SystemClock.uptimeMillis();
13727                pw.print("  mLastIdleTime=");
13728                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
13729                        pw.print(" mLowRamSinceLastIdle=");
13730                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13731                        pw.println();
13732            }
13733        }
13734
13735        if (!printedAnything) {
13736            pw.println("  (nothing)");
13737        }
13738    }
13739
13740    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13741            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13742        if (mProcessesToGc.size() > 0) {
13743            boolean printed = false;
13744            long now = SystemClock.uptimeMillis();
13745            for (int i=0; i<mProcessesToGc.size(); i++) {
13746                ProcessRecord proc = mProcessesToGc.get(i);
13747                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13748                    continue;
13749                }
13750                if (!printed) {
13751                    if (needSep) pw.println();
13752                    needSep = true;
13753                    pw.println("  Processes that are waiting to GC:");
13754                    printed = true;
13755                }
13756                pw.print("    Process "); pw.println(proc);
13757                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13758                        pw.print(", last gced=");
13759                        pw.print(now-proc.lastRequestedGc);
13760                        pw.print(" ms ago, last lowMem=");
13761                        pw.print(now-proc.lastLowMemory);
13762                        pw.println(" ms ago");
13763
13764            }
13765        }
13766        return needSep;
13767    }
13768
13769    void printOomLevel(PrintWriter pw, String name, int adj) {
13770        pw.print("    ");
13771        if (adj >= 0) {
13772            pw.print(' ');
13773            if (adj < 10) pw.print(' ');
13774        } else {
13775            if (adj > -10) pw.print(' ');
13776        }
13777        pw.print(adj);
13778        pw.print(": ");
13779        pw.print(name);
13780        pw.print(" (");
13781        pw.print(mProcessList.getMemLevel(adj)/1024);
13782        pw.println(" kB)");
13783    }
13784
13785    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13786            int opti, boolean dumpAll) {
13787        boolean needSep = false;
13788
13789        if (mLruProcesses.size() > 0) {
13790            if (needSep) pw.println();
13791            needSep = true;
13792            pw.println("  OOM levels:");
13793            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13794            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13795            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13796            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13797            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13798            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13799            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13800            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13801            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13802            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13803            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13804            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13805            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13806            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13807
13808            if (needSep) pw.println();
13809            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13810                    pw.print(" total, non-act at ");
13811                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13812                    pw.print(", non-svc at ");
13813                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13814                    pw.println("):");
13815            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13816            needSep = true;
13817        }
13818
13819        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13820
13821        pw.println();
13822        pw.println("  mHomeProcess: " + mHomeProcess);
13823        pw.println("  mPreviousProcess: " + mPreviousProcess);
13824        if (mHeavyWeightProcess != null) {
13825            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13826        }
13827
13828        return true;
13829    }
13830
13831    /**
13832     * There are three ways to call this:
13833     *  - no provider specified: dump all the providers
13834     *  - a flattened component name that matched an existing provider was specified as the
13835     *    first arg: dump that one provider
13836     *  - the first arg isn't the flattened component name of an existing provider:
13837     *    dump all providers whose component contains the first arg as a substring
13838     */
13839    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13840            int opti, boolean dumpAll) {
13841        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13842    }
13843
13844    static class ItemMatcher {
13845        ArrayList<ComponentName> components;
13846        ArrayList<String> strings;
13847        ArrayList<Integer> objects;
13848        boolean all;
13849
13850        ItemMatcher() {
13851            all = true;
13852        }
13853
13854        void build(String name) {
13855            ComponentName componentName = ComponentName.unflattenFromString(name);
13856            if (componentName != null) {
13857                if (components == null) {
13858                    components = new ArrayList<ComponentName>();
13859                }
13860                components.add(componentName);
13861                all = false;
13862            } else {
13863                int objectId = 0;
13864                // Not a '/' separated full component name; maybe an object ID?
13865                try {
13866                    objectId = Integer.parseInt(name, 16);
13867                    if (objects == null) {
13868                        objects = new ArrayList<Integer>();
13869                    }
13870                    objects.add(objectId);
13871                    all = false;
13872                } catch (RuntimeException e) {
13873                    // Not an integer; just do string match.
13874                    if (strings == null) {
13875                        strings = new ArrayList<String>();
13876                    }
13877                    strings.add(name);
13878                    all = false;
13879                }
13880            }
13881        }
13882
13883        int build(String[] args, int opti) {
13884            for (; opti<args.length; opti++) {
13885                String name = args[opti];
13886                if ("--".equals(name)) {
13887                    return opti+1;
13888                }
13889                build(name);
13890            }
13891            return opti;
13892        }
13893
13894        boolean match(Object object, ComponentName comp) {
13895            if (all) {
13896                return true;
13897            }
13898            if (components != null) {
13899                for (int i=0; i<components.size(); i++) {
13900                    if (components.get(i).equals(comp)) {
13901                        return true;
13902                    }
13903                }
13904            }
13905            if (objects != null) {
13906                for (int i=0; i<objects.size(); i++) {
13907                    if (System.identityHashCode(object) == objects.get(i)) {
13908                        return true;
13909                    }
13910                }
13911            }
13912            if (strings != null) {
13913                String flat = comp.flattenToString();
13914                for (int i=0; i<strings.size(); i++) {
13915                    if (flat.contains(strings.get(i))) {
13916                        return true;
13917                    }
13918                }
13919            }
13920            return false;
13921        }
13922    }
13923
13924    /**
13925     * There are three things that cmd can be:
13926     *  - a flattened component name that matches an existing activity
13927     *  - the cmd arg isn't the flattened component name of an existing activity:
13928     *    dump all activity whose component contains the cmd as a substring
13929     *  - A hex number of the ActivityRecord object instance.
13930     */
13931    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13932            int opti, boolean dumpAll) {
13933        ArrayList<ActivityRecord> activities;
13934
13935        synchronized (this) {
13936            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13937        }
13938
13939        if (activities.size() <= 0) {
13940            return false;
13941        }
13942
13943        String[] newArgs = new String[args.length - opti];
13944        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13945
13946        TaskRecord lastTask = null;
13947        boolean needSep = false;
13948        for (int i=activities.size()-1; i>=0; i--) {
13949            ActivityRecord r = activities.get(i);
13950            if (needSep) {
13951                pw.println();
13952            }
13953            needSep = true;
13954            synchronized (this) {
13955                if (lastTask != r.task) {
13956                    lastTask = r.task;
13957                    pw.print("TASK "); pw.print(lastTask.affinity);
13958                            pw.print(" id="); pw.println(lastTask.taskId);
13959                    if (dumpAll) {
13960                        lastTask.dump(pw, "  ");
13961                    }
13962                }
13963            }
13964            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13965        }
13966        return true;
13967    }
13968
13969    /**
13970     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13971     * there is a thread associated with the activity.
13972     */
13973    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13974            final ActivityRecord r, String[] args, boolean dumpAll) {
13975        String innerPrefix = prefix + "  ";
13976        synchronized (this) {
13977            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13978                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13979                    pw.print(" pid=");
13980                    if (r.app != null) pw.println(r.app.pid);
13981                    else pw.println("(not running)");
13982            if (dumpAll) {
13983                r.dump(pw, innerPrefix);
13984            }
13985        }
13986        if (r.app != null && r.app.thread != null) {
13987            // flush anything that is already in the PrintWriter since the thread is going
13988            // to write to the file descriptor directly
13989            pw.flush();
13990            try {
13991                TransferPipe tp = new TransferPipe();
13992                try {
13993                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13994                            r.appToken, innerPrefix, args);
13995                    tp.go(fd);
13996                } finally {
13997                    tp.kill();
13998                }
13999            } catch (IOException e) {
14000                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14001            } catch (RemoteException e) {
14002                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14003            }
14004        }
14005    }
14006
14007    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14008            int opti, boolean dumpAll, String dumpPackage) {
14009        boolean needSep = false;
14010        boolean onlyHistory = false;
14011        boolean printedAnything = false;
14012
14013        if ("history".equals(dumpPackage)) {
14014            if (opti < args.length && "-s".equals(args[opti])) {
14015                dumpAll = false;
14016            }
14017            onlyHistory = true;
14018            dumpPackage = null;
14019        }
14020
14021        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14022        if (!onlyHistory && dumpAll) {
14023            if (mRegisteredReceivers.size() > 0) {
14024                boolean printed = false;
14025                Iterator it = mRegisteredReceivers.values().iterator();
14026                while (it.hasNext()) {
14027                    ReceiverList r = (ReceiverList)it.next();
14028                    if (dumpPackage != null && (r.app == null ||
14029                            !dumpPackage.equals(r.app.info.packageName))) {
14030                        continue;
14031                    }
14032                    if (!printed) {
14033                        pw.println("  Registered Receivers:");
14034                        needSep = true;
14035                        printed = true;
14036                        printedAnything = true;
14037                    }
14038                    pw.print("  * "); pw.println(r);
14039                    r.dump(pw, "    ");
14040                }
14041            }
14042
14043            if (mReceiverResolver.dump(pw, needSep ?
14044                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14045                    "    ", dumpPackage, false, false)) {
14046                needSep = true;
14047                printedAnything = true;
14048            }
14049        }
14050
14051        for (BroadcastQueue q : mBroadcastQueues) {
14052            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14053            printedAnything |= needSep;
14054        }
14055
14056        needSep = true;
14057
14058        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14059            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14060                if (needSep) {
14061                    pw.println();
14062                }
14063                needSep = true;
14064                printedAnything = true;
14065                pw.print("  Sticky broadcasts for user ");
14066                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14067                StringBuilder sb = new StringBuilder(128);
14068                for (Map.Entry<String, ArrayList<Intent>> ent
14069                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14070                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14071                    if (dumpAll) {
14072                        pw.println(":");
14073                        ArrayList<Intent> intents = ent.getValue();
14074                        final int N = intents.size();
14075                        for (int i=0; i<N; i++) {
14076                            sb.setLength(0);
14077                            sb.append("    Intent: ");
14078                            intents.get(i).toShortString(sb, false, true, false, false);
14079                            pw.println(sb.toString());
14080                            Bundle bundle = intents.get(i).getExtras();
14081                            if (bundle != null) {
14082                                pw.print("      ");
14083                                pw.println(bundle.toString());
14084                            }
14085                        }
14086                    } else {
14087                        pw.println("");
14088                    }
14089                }
14090            }
14091        }
14092
14093        if (!onlyHistory && dumpAll) {
14094            pw.println();
14095            for (BroadcastQueue queue : mBroadcastQueues) {
14096                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14097                        + queue.mBroadcastsScheduled);
14098            }
14099            pw.println("  mHandler:");
14100            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14101            needSep = true;
14102            printedAnything = true;
14103        }
14104
14105        if (!printedAnything) {
14106            pw.println("  (nothing)");
14107        }
14108    }
14109
14110    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14111            int opti, boolean dumpAll, String dumpPackage) {
14112        boolean needSep;
14113        boolean printedAnything = false;
14114
14115        ItemMatcher matcher = new ItemMatcher();
14116        matcher.build(args, opti);
14117
14118        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14119
14120        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14121        printedAnything |= needSep;
14122
14123        if (mLaunchingProviders.size() > 0) {
14124            boolean printed = false;
14125            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14126                ContentProviderRecord r = mLaunchingProviders.get(i);
14127                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14128                    continue;
14129                }
14130                if (!printed) {
14131                    if (needSep) pw.println();
14132                    needSep = true;
14133                    pw.println("  Launching content providers:");
14134                    printed = true;
14135                    printedAnything = true;
14136                }
14137                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14138                        pw.println(r);
14139            }
14140        }
14141
14142        if (!printedAnything) {
14143            pw.println("  (nothing)");
14144        }
14145    }
14146
14147    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14148            int opti, boolean dumpAll, String dumpPackage) {
14149        boolean needSep = false;
14150        boolean printedAnything = false;
14151
14152        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14153
14154        if (mGrantedUriPermissions.size() > 0) {
14155            boolean printed = false;
14156            int dumpUid = -2;
14157            if (dumpPackage != null) {
14158                try {
14159                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
14160                } catch (NameNotFoundException e) {
14161                    dumpUid = -1;
14162                }
14163            }
14164            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14165                int uid = mGrantedUriPermissions.keyAt(i);
14166                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14167                    continue;
14168                }
14169                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14170                if (!printed) {
14171                    if (needSep) pw.println();
14172                    needSep = true;
14173                    pw.println("  Granted Uri Permissions:");
14174                    printed = true;
14175                    printedAnything = true;
14176                }
14177                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14178                for (UriPermission perm : perms.values()) {
14179                    pw.print("    "); pw.println(perm);
14180                    if (dumpAll) {
14181                        perm.dump(pw, "      ");
14182                    }
14183                }
14184            }
14185        }
14186
14187        if (!printedAnything) {
14188            pw.println("  (nothing)");
14189        }
14190    }
14191
14192    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14193            int opti, boolean dumpAll, String dumpPackage) {
14194        boolean printed = false;
14195
14196        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14197
14198        if (mIntentSenderRecords.size() > 0) {
14199            Iterator<WeakReference<PendingIntentRecord>> it
14200                    = mIntentSenderRecords.values().iterator();
14201            while (it.hasNext()) {
14202                WeakReference<PendingIntentRecord> ref = it.next();
14203                PendingIntentRecord rec = ref != null ? ref.get(): null;
14204                if (dumpPackage != null && (rec == null
14205                        || !dumpPackage.equals(rec.key.packageName))) {
14206                    continue;
14207                }
14208                printed = true;
14209                if (rec != null) {
14210                    pw.print("  * "); pw.println(rec);
14211                    if (dumpAll) {
14212                        rec.dump(pw, "    ");
14213                    }
14214                } else {
14215                    pw.print("  * "); pw.println(ref);
14216                }
14217            }
14218        }
14219
14220        if (!printed) {
14221            pw.println("  (nothing)");
14222        }
14223    }
14224
14225    private static final int dumpProcessList(PrintWriter pw,
14226            ActivityManagerService service, List list,
14227            String prefix, String normalLabel, String persistentLabel,
14228            String dumpPackage) {
14229        int numPers = 0;
14230        final int N = list.size()-1;
14231        for (int i=N; i>=0; i--) {
14232            ProcessRecord r = (ProcessRecord)list.get(i);
14233            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14234                continue;
14235            }
14236            pw.println(String.format("%s%s #%2d: %s",
14237                    prefix, (r.persistent ? persistentLabel : normalLabel),
14238                    i, r.toString()));
14239            if (r.persistent) {
14240                numPers++;
14241            }
14242        }
14243        return numPers;
14244    }
14245
14246    private static final boolean dumpProcessOomList(PrintWriter pw,
14247            ActivityManagerService service, List<ProcessRecord> origList,
14248            String prefix, String normalLabel, String persistentLabel,
14249            boolean inclDetails, String dumpPackage) {
14250
14251        ArrayList<Pair<ProcessRecord, Integer>> list
14252                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14253        for (int i=0; i<origList.size(); i++) {
14254            ProcessRecord r = origList.get(i);
14255            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14256                continue;
14257            }
14258            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14259        }
14260
14261        if (list.size() <= 0) {
14262            return false;
14263        }
14264
14265        Comparator<Pair<ProcessRecord, Integer>> comparator
14266                = new Comparator<Pair<ProcessRecord, Integer>>() {
14267            @Override
14268            public int compare(Pair<ProcessRecord, Integer> object1,
14269                    Pair<ProcessRecord, Integer> object2) {
14270                if (object1.first.setAdj != object2.first.setAdj) {
14271                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14272                }
14273                if (object1.second.intValue() != object2.second.intValue()) {
14274                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14275                }
14276                return 0;
14277            }
14278        };
14279
14280        Collections.sort(list, comparator);
14281
14282        final long curRealtime = SystemClock.elapsedRealtime();
14283        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14284        final long curUptime = SystemClock.uptimeMillis();
14285        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14286
14287        for (int i=list.size()-1; i>=0; i--) {
14288            ProcessRecord r = list.get(i).first;
14289            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14290            char schedGroup;
14291            switch (r.setSchedGroup) {
14292                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
14293                    schedGroup = 'B';
14294                    break;
14295                case Process.THREAD_GROUP_DEFAULT:
14296                    schedGroup = 'F';
14297                    break;
14298                default:
14299                    schedGroup = '?';
14300                    break;
14301            }
14302            char foreground;
14303            if (r.foregroundActivities) {
14304                foreground = 'A';
14305            } else if (r.foregroundServices) {
14306                foreground = 'S';
14307            } else {
14308                foreground = ' ';
14309            }
14310            String procState = ProcessList.makeProcStateString(r.curProcState);
14311            pw.print(prefix);
14312            pw.print(r.persistent ? persistentLabel : normalLabel);
14313            pw.print(" #");
14314            int num = (origList.size()-1)-list.get(i).second;
14315            if (num < 10) pw.print(' ');
14316            pw.print(num);
14317            pw.print(": ");
14318            pw.print(oomAdj);
14319            pw.print(' ');
14320            pw.print(schedGroup);
14321            pw.print('/');
14322            pw.print(foreground);
14323            pw.print('/');
14324            pw.print(procState);
14325            pw.print(" trm:");
14326            if (r.trimMemoryLevel < 10) pw.print(' ');
14327            pw.print(r.trimMemoryLevel);
14328            pw.print(' ');
14329            pw.print(r.toShortString());
14330            pw.print(" (");
14331            pw.print(r.adjType);
14332            pw.println(')');
14333            if (r.adjSource != null || r.adjTarget != null) {
14334                pw.print(prefix);
14335                pw.print("    ");
14336                if (r.adjTarget instanceof ComponentName) {
14337                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14338                } else if (r.adjTarget != null) {
14339                    pw.print(r.adjTarget.toString());
14340                } else {
14341                    pw.print("{null}");
14342                }
14343                pw.print("<=");
14344                if (r.adjSource instanceof ProcessRecord) {
14345                    pw.print("Proc{");
14346                    pw.print(((ProcessRecord)r.adjSource).toShortString());
14347                    pw.println("}");
14348                } else if (r.adjSource != null) {
14349                    pw.println(r.adjSource.toString());
14350                } else {
14351                    pw.println("{null}");
14352                }
14353            }
14354            if (inclDetails) {
14355                pw.print(prefix);
14356                pw.print("    ");
14357                pw.print("oom: max="); pw.print(r.maxAdj);
14358                pw.print(" curRaw="); pw.print(r.curRawAdj);
14359                pw.print(" setRaw="); pw.print(r.setRawAdj);
14360                pw.print(" cur="); pw.print(r.curAdj);
14361                pw.print(" set="); pw.println(r.setAdj);
14362                pw.print(prefix);
14363                pw.print("    ");
14364                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14365                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14366                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14367                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14368                pw.println();
14369                pw.print(prefix);
14370                pw.print("    ");
14371                pw.print("cached="); pw.print(r.cached);
14372                pw.print(" empty="); pw.print(r.empty);
14373                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14374
14375                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14376                    if (r.lastWakeTime != 0) {
14377                        long wtime;
14378                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14379                        synchronized (stats) {
14380                            wtime = stats.getProcessWakeTime(r.info.uid,
14381                                    r.pid, curRealtime);
14382                        }
14383                        long timeUsed = wtime - r.lastWakeTime;
14384                        pw.print(prefix);
14385                        pw.print("    ");
14386                        pw.print("keep awake over ");
14387                        TimeUtils.formatDuration(realtimeSince, pw);
14388                        pw.print(" used ");
14389                        TimeUtils.formatDuration(timeUsed, pw);
14390                        pw.print(" (");
14391                        pw.print((timeUsed*100)/realtimeSince);
14392                        pw.println("%)");
14393                    }
14394                    if (r.lastCpuTime != 0) {
14395                        long timeUsed = r.curCpuTime - r.lastCpuTime;
14396                        pw.print(prefix);
14397                        pw.print("    ");
14398                        pw.print("run cpu over ");
14399                        TimeUtils.formatDuration(uptimeSince, pw);
14400                        pw.print(" used ");
14401                        TimeUtils.formatDuration(timeUsed, pw);
14402                        pw.print(" (");
14403                        pw.print((timeUsed*100)/uptimeSince);
14404                        pw.println("%)");
14405                    }
14406                }
14407            }
14408        }
14409        return true;
14410    }
14411
14412    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14413            String[] args) {
14414        ArrayList<ProcessRecord> procs;
14415        synchronized (this) {
14416            if (args != null && args.length > start
14417                    && args[start].charAt(0) != '-') {
14418                procs = new ArrayList<ProcessRecord>();
14419                int pid = -1;
14420                try {
14421                    pid = Integer.parseInt(args[start]);
14422                } catch (NumberFormatException e) {
14423                }
14424                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14425                    ProcessRecord proc = mLruProcesses.get(i);
14426                    if (proc.pid == pid) {
14427                        procs.add(proc);
14428                    } else if (allPkgs && proc.pkgList != null
14429                            && proc.pkgList.containsKey(args[start])) {
14430                        procs.add(proc);
14431                    } else if (proc.processName.equals(args[start])) {
14432                        procs.add(proc);
14433                    }
14434                }
14435                if (procs.size() <= 0) {
14436                    return null;
14437                }
14438            } else {
14439                procs = new ArrayList<ProcessRecord>(mLruProcesses);
14440            }
14441        }
14442        return procs;
14443    }
14444
14445    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
14446            PrintWriter pw, String[] args) {
14447        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14448        if (procs == null) {
14449            pw.println("No process found for: " + args[0]);
14450            return;
14451        }
14452
14453        long uptime = SystemClock.uptimeMillis();
14454        long realtime = SystemClock.elapsedRealtime();
14455        pw.println("Applications Graphics Acceleration Info:");
14456        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14457
14458        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14459            ProcessRecord r = procs.get(i);
14460            if (r.thread != null) {
14461                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
14462                pw.flush();
14463                try {
14464                    TransferPipe tp = new TransferPipe();
14465                    try {
14466                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
14467                        tp.go(fd);
14468                    } finally {
14469                        tp.kill();
14470                    }
14471                } catch (IOException e) {
14472                    pw.println("Failure while dumping the app: " + r);
14473                    pw.flush();
14474                } catch (RemoteException e) {
14475                    pw.println("Got a RemoteException while dumping the app " + r);
14476                    pw.flush();
14477                }
14478            }
14479        }
14480    }
14481
14482    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
14483        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14484        if (procs == null) {
14485            pw.println("No process found for: " + args[0]);
14486            return;
14487        }
14488
14489        pw.println("Applications Database Info:");
14490
14491        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14492            ProcessRecord r = procs.get(i);
14493            if (r.thread != null) {
14494                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
14495                pw.flush();
14496                try {
14497                    TransferPipe tp = new TransferPipe();
14498                    try {
14499                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
14500                        tp.go(fd);
14501                    } finally {
14502                        tp.kill();
14503                    }
14504                } catch (IOException e) {
14505                    pw.println("Failure while dumping the app: " + r);
14506                    pw.flush();
14507                } catch (RemoteException e) {
14508                    pw.println("Got a RemoteException while dumping the app " + r);
14509                    pw.flush();
14510                }
14511            }
14512        }
14513    }
14514
14515    final static class MemItem {
14516        final boolean isProc;
14517        final String label;
14518        final String shortLabel;
14519        final long pss;
14520        final int id;
14521        final boolean hasActivities;
14522        ArrayList<MemItem> subitems;
14523
14524        public MemItem(String _label, String _shortLabel, long _pss, int _id,
14525                boolean _hasActivities) {
14526            isProc = true;
14527            label = _label;
14528            shortLabel = _shortLabel;
14529            pss = _pss;
14530            id = _id;
14531            hasActivities = _hasActivities;
14532        }
14533
14534        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
14535            isProc = false;
14536            label = _label;
14537            shortLabel = _shortLabel;
14538            pss = _pss;
14539            id = _id;
14540            hasActivities = false;
14541        }
14542    }
14543
14544    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
14545            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
14546        if (sort && !isCompact) {
14547            Collections.sort(items, new Comparator<MemItem>() {
14548                @Override
14549                public int compare(MemItem lhs, MemItem rhs) {
14550                    if (lhs.pss < rhs.pss) {
14551                        return 1;
14552                    } else if (lhs.pss > rhs.pss) {
14553                        return -1;
14554                    }
14555                    return 0;
14556                }
14557            });
14558        }
14559
14560        for (int i=0; i<items.size(); i++) {
14561            MemItem mi = items.get(i);
14562            if (!isCompact) {
14563                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
14564            } else if (mi.isProc) {
14565                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
14566                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
14567                pw.println(mi.hasActivities ? ",a" : ",e");
14568            } else {
14569                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
14570                pw.println(mi.pss);
14571            }
14572            if (mi.subitems != null) {
14573                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
14574                        true, isCompact);
14575            }
14576        }
14577    }
14578
14579    // These are in KB.
14580    static final long[] DUMP_MEM_BUCKETS = new long[] {
14581        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
14582        120*1024, 160*1024, 200*1024,
14583        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
14584        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
14585    };
14586
14587    static final void appendMemBucket(StringBuilder out, long memKB, String label,
14588            boolean stackLike) {
14589        int start = label.lastIndexOf('.');
14590        if (start >= 0) start++;
14591        else start = 0;
14592        int end = label.length();
14593        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
14594            if (DUMP_MEM_BUCKETS[i] >= memKB) {
14595                long bucket = DUMP_MEM_BUCKETS[i]/1024;
14596                out.append(bucket);
14597                out.append(stackLike ? "MB." : "MB ");
14598                out.append(label, start, end);
14599                return;
14600            }
14601        }
14602        out.append(memKB/1024);
14603        out.append(stackLike ? "MB." : "MB ");
14604        out.append(label, start, end);
14605    }
14606
14607    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
14608            ProcessList.NATIVE_ADJ,
14609            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
14610            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
14611            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
14612            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
14613            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
14614            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
14615    };
14616    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
14617            "Native",
14618            "System", "Persistent", "Persistent Service", "Foreground",
14619            "Visible", "Perceptible",
14620            "Heavy Weight", "Backup",
14621            "A Services", "Home",
14622            "Previous", "B Services", "Cached"
14623    };
14624    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
14625            "native",
14626            "sys", "pers", "persvc", "fore",
14627            "vis", "percept",
14628            "heavy", "backup",
14629            "servicea", "home",
14630            "prev", "serviceb", "cached"
14631    };
14632
14633    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
14634            long realtime, boolean isCheckinRequest, boolean isCompact) {
14635        if (isCheckinRequest || isCompact) {
14636            // short checkin version
14637            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
14638        } else {
14639            pw.println("Applications Memory Usage (kB):");
14640            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14641        }
14642    }
14643
14644    private static final int KSM_SHARED = 0;
14645    private static final int KSM_SHARING = 1;
14646    private static final int KSM_UNSHARED = 2;
14647    private static final int KSM_VOLATILE = 3;
14648
14649    private final long[] getKsmInfo() {
14650        long[] longOut = new long[4];
14651        final int[] SINGLE_LONG_FORMAT = new int[] {
14652            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14653        };
14654        long[] longTmp = new long[1];
14655        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14656                SINGLE_LONG_FORMAT, null, longTmp, null);
14657        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14658        longTmp[0] = 0;
14659        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14660                SINGLE_LONG_FORMAT, null, longTmp, null);
14661        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14662        longTmp[0] = 0;
14663        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14664                SINGLE_LONG_FORMAT, null, longTmp, null);
14665        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14666        longTmp[0] = 0;
14667        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14668                SINGLE_LONG_FORMAT, null, longTmp, null);
14669        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14670        return longOut;
14671    }
14672
14673    final void dumpApplicationMemoryUsage(FileDescriptor fd,
14674            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
14675        boolean dumpDetails = false;
14676        boolean dumpFullDetails = false;
14677        boolean dumpDalvik = false;
14678        boolean dumpSummaryOnly = false;
14679        boolean oomOnly = false;
14680        boolean isCompact = false;
14681        boolean localOnly = false;
14682        boolean packages = false;
14683
14684        int opti = 0;
14685        while (opti < args.length) {
14686            String opt = args[opti];
14687            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14688                break;
14689            }
14690            opti++;
14691            if ("-a".equals(opt)) {
14692                dumpDetails = true;
14693                dumpFullDetails = true;
14694                dumpDalvik = true;
14695            } else if ("-d".equals(opt)) {
14696                dumpDalvik = true;
14697            } else if ("-c".equals(opt)) {
14698                isCompact = true;
14699            } else if ("-s".equals(opt)) {
14700                dumpDetails = true;
14701                dumpSummaryOnly = true;
14702            } else if ("--oom".equals(opt)) {
14703                oomOnly = true;
14704            } else if ("--local".equals(opt)) {
14705                localOnly = true;
14706            } else if ("--package".equals(opt)) {
14707                packages = true;
14708            } else if ("-h".equals(opt)) {
14709                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
14710                pw.println("  -a: include all available information for each process.");
14711                pw.println("  -d: include dalvik details.");
14712                pw.println("  -c: dump in a compact machine-parseable representation.");
14713                pw.println("  -s: dump only summary of application memory usage.");
14714                pw.println("  --oom: only show processes organized by oom adj.");
14715                pw.println("  --local: only collect details locally, don't call process.");
14716                pw.println("  --package: interpret process arg as package, dumping all");
14717                pw.println("             processes that have loaded that package.");
14718                pw.println("If [process] is specified it can be the name or ");
14719                pw.println("pid of a specific process to dump.");
14720                return;
14721            } else {
14722                pw.println("Unknown argument: " + opt + "; use -h for help");
14723            }
14724        }
14725
14726        final boolean isCheckinRequest = scanArgs(args, "--checkin");
14727        long uptime = SystemClock.uptimeMillis();
14728        long realtime = SystemClock.elapsedRealtime();
14729        final long[] tmpLong = new long[1];
14730
14731        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
14732        if (procs == null) {
14733            // No Java processes.  Maybe they want to print a native process.
14734            if (args != null && args.length > opti
14735                    && args[opti].charAt(0) != '-') {
14736                ArrayList<ProcessCpuTracker.Stats> nativeProcs
14737                        = new ArrayList<ProcessCpuTracker.Stats>();
14738                updateCpuStatsNow();
14739                int findPid = -1;
14740                try {
14741                    findPid = Integer.parseInt(args[opti]);
14742                } catch (NumberFormatException e) {
14743                }
14744                synchronized (mProcessCpuTracker) {
14745                    final int N = mProcessCpuTracker.countStats();
14746                    for (int i=0; i<N; i++) {
14747                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14748                        if (st.pid == findPid || (st.baseName != null
14749                                && st.baseName.equals(args[opti]))) {
14750                            nativeProcs.add(st);
14751                        }
14752                    }
14753                }
14754                if (nativeProcs.size() > 0) {
14755                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14756                            isCompact);
14757                    Debug.MemoryInfo mi = null;
14758                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14759                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14760                        final int pid = r.pid;
14761                        if (!isCheckinRequest && dumpDetails) {
14762                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14763                        }
14764                        if (mi == null) {
14765                            mi = new Debug.MemoryInfo();
14766                        }
14767                        if (dumpDetails || (!brief && !oomOnly)) {
14768                            Debug.getMemoryInfo(pid, mi);
14769                        } else {
14770                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14771                            mi.dalvikPrivateDirty = (int)tmpLong[0];
14772                        }
14773                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14774                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14775                        if (isCheckinRequest) {
14776                            pw.println();
14777                        }
14778                    }
14779                    return;
14780                }
14781            }
14782            pw.println("No process found for: " + args[opti]);
14783            return;
14784        }
14785
14786        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14787            dumpDetails = true;
14788        }
14789
14790        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14791
14792        String[] innerArgs = new String[args.length-opti];
14793        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14794
14795        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14796        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14797        long nativePss = 0;
14798        long dalvikPss = 0;
14799        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
14800                EmptyArray.LONG;
14801        long otherPss = 0;
14802        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14803
14804        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14805        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14806                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14807
14808        long totalPss = 0;
14809        long cachedPss = 0;
14810
14811        Debug.MemoryInfo mi = null;
14812        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14813            final ProcessRecord r = procs.get(i);
14814            final IApplicationThread thread;
14815            final int pid;
14816            final int oomAdj;
14817            final boolean hasActivities;
14818            synchronized (this) {
14819                thread = r.thread;
14820                pid = r.pid;
14821                oomAdj = r.getSetAdjWithServices();
14822                hasActivities = r.activities.size() > 0;
14823            }
14824            if (thread != null) {
14825                if (!isCheckinRequest && dumpDetails) {
14826                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14827                }
14828                if (mi == null) {
14829                    mi = new Debug.MemoryInfo();
14830                }
14831                if (dumpDetails || (!brief && !oomOnly)) {
14832                    Debug.getMemoryInfo(pid, mi);
14833                } else {
14834                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14835                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14836                }
14837                if (dumpDetails) {
14838                    if (localOnly) {
14839                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14840                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
14841                        if (isCheckinRequest) {
14842                            pw.println();
14843                        }
14844                    } else {
14845                        try {
14846                            pw.flush();
14847                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14848                                    dumpDalvik, dumpSummaryOnly, innerArgs);
14849                        } catch (RemoteException e) {
14850                            if (!isCheckinRequest) {
14851                                pw.println("Got RemoteException!");
14852                                pw.flush();
14853                            }
14854                        }
14855                    }
14856                }
14857
14858                final long myTotalPss = mi.getTotalPss();
14859                final long myTotalUss = mi.getTotalUss();
14860
14861                synchronized (this) {
14862                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14863                        // Record this for posterity if the process has been stable.
14864                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14865                    }
14866                }
14867
14868                if (!isCheckinRequest && mi != null) {
14869                    totalPss += myTotalPss;
14870                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14871                            (hasActivities ? " / activities)" : ")"),
14872                            r.processName, myTotalPss, pid, hasActivities);
14873                    procMems.add(pssItem);
14874                    procMemsMap.put(pid, pssItem);
14875
14876                    nativePss += mi.nativePss;
14877                    dalvikPss += mi.dalvikPss;
14878                    for (int j=0; j<dalvikSubitemPss.length; j++) {
14879                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
14880                    }
14881                    otherPss += mi.otherPss;
14882                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14883                        long mem = mi.getOtherPss(j);
14884                        miscPss[j] += mem;
14885                        otherPss -= mem;
14886                    }
14887
14888                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14889                        cachedPss += myTotalPss;
14890                    }
14891
14892                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14893                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14894                                || oomIndex == (oomPss.length-1)) {
14895                            oomPss[oomIndex] += myTotalPss;
14896                            if (oomProcs[oomIndex] == null) {
14897                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14898                            }
14899                            oomProcs[oomIndex].add(pssItem);
14900                            break;
14901                        }
14902                    }
14903                }
14904            }
14905        }
14906
14907        long nativeProcTotalPss = 0;
14908
14909        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14910            // If we are showing aggregations, also look for native processes to
14911            // include so that our aggregations are more accurate.
14912            updateCpuStatsNow();
14913            mi = null;
14914            synchronized (mProcessCpuTracker) {
14915                final int N = mProcessCpuTracker.countStats();
14916                for (int i=0; i<N; i++) {
14917                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14918                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14919                        if (mi == null) {
14920                            mi = new Debug.MemoryInfo();
14921                        }
14922                        if (!brief && !oomOnly) {
14923                            Debug.getMemoryInfo(st.pid, mi);
14924                        } else {
14925                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14926                            mi.nativePrivateDirty = (int)tmpLong[0];
14927                        }
14928
14929                        final long myTotalPss = mi.getTotalPss();
14930                        totalPss += myTotalPss;
14931                        nativeProcTotalPss += myTotalPss;
14932
14933                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14934                                st.name, myTotalPss, st.pid, false);
14935                        procMems.add(pssItem);
14936
14937                        nativePss += mi.nativePss;
14938                        dalvikPss += mi.dalvikPss;
14939                        for (int j=0; j<dalvikSubitemPss.length; j++) {
14940                            dalvikSubitemPss[j] += mi.getOtherPss(
14941                                    Debug.MemoryInfo.NUM_OTHER_STATS + j);
14942                        }
14943                        otherPss += mi.otherPss;
14944                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14945                            long mem = mi.getOtherPss(j);
14946                            miscPss[j] += mem;
14947                            otherPss -= mem;
14948                        }
14949                        oomPss[0] += myTotalPss;
14950                        if (oomProcs[0] == null) {
14951                            oomProcs[0] = new ArrayList<MemItem>();
14952                        }
14953                        oomProcs[0].add(pssItem);
14954                    }
14955                }
14956            }
14957
14958            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14959
14960            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14961            final MemItem dalvikItem = new MemItem("Dalvik", "Dalvik", dalvikPss, -2);
14962            if (dalvikSubitemPss.length > 0) {
14963                dalvikItem.subitems = new ArrayList<MemItem>();
14964                for (int j=0; j<dalvikSubitemPss.length; j++) {
14965                    final String name = Debug.MemoryInfo.getOtherLabel(
14966                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
14967                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j], j));
14968                }
14969            }
14970            catMems.add(dalvikItem);
14971            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14972            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14973                String label = Debug.MemoryInfo.getOtherLabel(j);
14974                catMems.add(new MemItem(label, label, miscPss[j], j));
14975            }
14976
14977            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14978            for (int j=0; j<oomPss.length; j++) {
14979                if (oomPss[j] != 0) {
14980                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14981                            : DUMP_MEM_OOM_LABEL[j];
14982                    MemItem item = new MemItem(label, label, oomPss[j],
14983                            DUMP_MEM_OOM_ADJ[j]);
14984                    item.subitems = oomProcs[j];
14985                    oomMems.add(item);
14986                }
14987            }
14988
14989            if (!brief && !oomOnly && !isCompact) {
14990                pw.println();
14991                pw.println("Total PSS by process:");
14992                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14993                pw.println();
14994            }
14995            if (!isCompact) {
14996                pw.println("Total PSS by OOM adjustment:");
14997            }
14998            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14999            if (!brief && !oomOnly) {
15000                PrintWriter out = categoryPw != null ? categoryPw : pw;
15001                if (!isCompact) {
15002                    out.println();
15003                    out.println("Total PSS by category:");
15004                }
15005                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
15006            }
15007            if (!isCompact) {
15008                pw.println();
15009            }
15010            MemInfoReader memInfo = new MemInfoReader();
15011            memInfo.readMemInfo();
15012            if (nativeProcTotalPss > 0) {
15013                synchronized (this) {
15014                    final long cachedKb = memInfo.getCachedSizeKb();
15015                    final long freeKb = memInfo.getFreeSizeKb();
15016                    final long zramKb = memInfo.getZramTotalSizeKb();
15017                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15018                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15019                            kernelKb*1024, nativeProcTotalPss*1024);
15020                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15021                            nativeProcTotalPss);
15022                }
15023            }
15024            if (!brief) {
15025                if (!isCompact) {
15026                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
15027                    pw.print(" kB (status ");
15028                    switch (mLastMemoryLevel) {
15029                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15030                            pw.println("normal)");
15031                            break;
15032                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15033                            pw.println("moderate)");
15034                            break;
15035                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15036                            pw.println("low)");
15037                            break;
15038                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15039                            pw.println("critical)");
15040                            break;
15041                        default:
15042                            pw.print(mLastMemoryLevel);
15043                            pw.println(")");
15044                            break;
15045                    }
15046                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
15047                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
15048                            pw.print(cachedPss); pw.print(" cached pss + ");
15049                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
15050                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
15051                } else {
15052                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15053                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15054                            + memInfo.getFreeSizeKb()); pw.print(",");
15055                    pw.println(totalPss - cachedPss);
15056                }
15057            }
15058            if (!isCompact) {
15059                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
15060                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
15061                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
15062                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
15063                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
15064                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15065                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
15066            }
15067            if (!brief) {
15068                if (memInfo.getZramTotalSizeKb() != 0) {
15069                    if (!isCompact) {
15070                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
15071                                pw.print(" kB physical used for ");
15072                                pw.print(memInfo.getSwapTotalSizeKb()
15073                                        - memInfo.getSwapFreeSizeKb());
15074                                pw.print(" kB in swap (");
15075                                pw.print(memInfo.getSwapTotalSizeKb());
15076                                pw.println(" kB total swap)");
15077                    } else {
15078                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15079                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15080                                pw.println(memInfo.getSwapFreeSizeKb());
15081                    }
15082                }
15083                final long[] ksm = getKsmInfo();
15084                if (!isCompact) {
15085                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15086                            || ksm[KSM_VOLATILE] != 0) {
15087                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
15088                                pw.print(" kB saved from shared ");
15089                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
15090                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
15091                                pw.print(" kB unshared; ");
15092                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
15093                    }
15094                    pw.print("   Tuning: ");
15095                    pw.print(ActivityManager.staticGetMemoryClass());
15096                    pw.print(" (large ");
15097                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15098                    pw.print("), oom ");
15099                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15100                    pw.print(" kB");
15101                    pw.print(", restore limit ");
15102                    pw.print(mProcessList.getCachedRestoreThresholdKb());
15103                    pw.print(" kB");
15104                    if (ActivityManager.isLowRamDeviceStatic()) {
15105                        pw.print(" (low-ram)");
15106                    }
15107                    if (ActivityManager.isHighEndGfx()) {
15108                        pw.print(" (high-end-gfx)");
15109                    }
15110                    pw.println();
15111                } else {
15112                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15113                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15114                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15115                    pw.print("tuning,");
15116                    pw.print(ActivityManager.staticGetMemoryClass());
15117                    pw.print(',');
15118                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15119                    pw.print(',');
15120                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15121                    if (ActivityManager.isLowRamDeviceStatic()) {
15122                        pw.print(",low-ram");
15123                    }
15124                    if (ActivityManager.isHighEndGfx()) {
15125                        pw.print(",high-end-gfx");
15126                    }
15127                    pw.println();
15128                }
15129            }
15130        }
15131    }
15132
15133    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15134            long memtrack, String name) {
15135        sb.append("  ");
15136        sb.append(ProcessList.makeOomAdjString(oomAdj));
15137        sb.append(' ');
15138        sb.append(ProcessList.makeProcStateString(procState));
15139        sb.append(' ');
15140        ProcessList.appendRamKb(sb, pss);
15141        sb.append(" kB: ");
15142        sb.append(name);
15143        if (memtrack > 0) {
15144            sb.append(" (");
15145            sb.append(memtrack);
15146            sb.append(" kB memtrack)");
15147        }
15148    }
15149
15150    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15151        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15152        sb.append(" (pid ");
15153        sb.append(mi.pid);
15154        sb.append(") ");
15155        sb.append(mi.adjType);
15156        sb.append('\n');
15157        if (mi.adjReason != null) {
15158            sb.append("                      ");
15159            sb.append(mi.adjReason);
15160            sb.append('\n');
15161        }
15162    }
15163
15164    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15165        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15166        for (int i=0, N=memInfos.size(); i<N; i++) {
15167            ProcessMemInfo mi = memInfos.get(i);
15168            infoMap.put(mi.pid, mi);
15169        }
15170        updateCpuStatsNow();
15171        long[] memtrackTmp = new long[1];
15172        synchronized (mProcessCpuTracker) {
15173            final int N = mProcessCpuTracker.countStats();
15174            for (int i=0; i<N; i++) {
15175                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15176                if (st.vsize > 0) {
15177                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
15178                    if (pss > 0) {
15179                        if (infoMap.indexOfKey(st.pid) < 0) {
15180                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15181                                    ProcessList.NATIVE_ADJ, -1, "native", null);
15182                            mi.pss = pss;
15183                            mi.memtrack = memtrackTmp[0];
15184                            memInfos.add(mi);
15185                        }
15186                    }
15187                }
15188            }
15189        }
15190
15191        long totalPss = 0;
15192        long totalMemtrack = 0;
15193        for (int i=0, N=memInfos.size(); i<N; i++) {
15194            ProcessMemInfo mi = memInfos.get(i);
15195            if (mi.pss == 0) {
15196                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15197                mi.memtrack = memtrackTmp[0];
15198            }
15199            totalPss += mi.pss;
15200            totalMemtrack += mi.memtrack;
15201        }
15202        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15203            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15204                if (lhs.oomAdj != rhs.oomAdj) {
15205                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15206                }
15207                if (lhs.pss != rhs.pss) {
15208                    return lhs.pss < rhs.pss ? 1 : -1;
15209                }
15210                return 0;
15211            }
15212        });
15213
15214        StringBuilder tag = new StringBuilder(128);
15215        StringBuilder stack = new StringBuilder(128);
15216        tag.append("Low on memory -- ");
15217        appendMemBucket(tag, totalPss, "total", false);
15218        appendMemBucket(stack, totalPss, "total", true);
15219
15220        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15221        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15222        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15223
15224        boolean firstLine = true;
15225        int lastOomAdj = Integer.MIN_VALUE;
15226        long extraNativeRam = 0;
15227        long extraNativeMemtrack = 0;
15228        long cachedPss = 0;
15229        for (int i=0, N=memInfos.size(); i<N; i++) {
15230            ProcessMemInfo mi = memInfos.get(i);
15231
15232            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15233                cachedPss += mi.pss;
15234            }
15235
15236            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15237                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15238                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15239                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15240                if (lastOomAdj != mi.oomAdj) {
15241                    lastOomAdj = mi.oomAdj;
15242                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15243                        tag.append(" / ");
15244                    }
15245                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15246                        if (firstLine) {
15247                            stack.append(":");
15248                            firstLine = false;
15249                        }
15250                        stack.append("\n\t at ");
15251                    } else {
15252                        stack.append("$");
15253                    }
15254                } else {
15255                    tag.append(" ");
15256                    stack.append("$");
15257                }
15258                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15259                    appendMemBucket(tag, mi.pss, mi.name, false);
15260                }
15261                appendMemBucket(stack, mi.pss, mi.name, true);
15262                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15263                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15264                    stack.append("(");
15265                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15266                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15267                            stack.append(DUMP_MEM_OOM_LABEL[k]);
15268                            stack.append(":");
15269                            stack.append(DUMP_MEM_OOM_ADJ[k]);
15270                        }
15271                    }
15272                    stack.append(")");
15273                }
15274            }
15275
15276            appendMemInfo(fullNativeBuilder, mi);
15277            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15278                // The short form only has native processes that are >= 512K.
15279                if (mi.pss >= 512) {
15280                    appendMemInfo(shortNativeBuilder, mi);
15281                } else {
15282                    extraNativeRam += mi.pss;
15283                    extraNativeMemtrack += mi.memtrack;
15284                }
15285            } else {
15286                // Short form has all other details, but if we have collected RAM
15287                // from smaller native processes let's dump a summary of that.
15288                if (extraNativeRam > 0) {
15289                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15290                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15291                    shortNativeBuilder.append('\n');
15292                    extraNativeRam = 0;
15293                }
15294                appendMemInfo(fullJavaBuilder, mi);
15295            }
15296        }
15297
15298        fullJavaBuilder.append("           ");
15299        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15300        fullJavaBuilder.append(" kB: TOTAL");
15301        if (totalMemtrack > 0) {
15302            fullJavaBuilder.append(" (");
15303            fullJavaBuilder.append(totalMemtrack);
15304            fullJavaBuilder.append(" kB memtrack)");
15305        } else {
15306        }
15307        fullJavaBuilder.append("\n");
15308
15309        MemInfoReader memInfo = new MemInfoReader();
15310        memInfo.readMemInfo();
15311        final long[] infos = memInfo.getRawInfo();
15312
15313        StringBuilder memInfoBuilder = new StringBuilder(1024);
15314        Debug.getMemInfo(infos);
15315        memInfoBuilder.append("  MemInfo: ");
15316        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
15317        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
15318        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
15319        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
15320        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
15321        memInfoBuilder.append("           ");
15322        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
15323        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
15324        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
15325        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
15326        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15327            memInfoBuilder.append("  ZRAM: ");
15328            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
15329            memInfoBuilder.append(" kB RAM, ");
15330            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
15331            memInfoBuilder.append(" kB swap total, ");
15332            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
15333            memInfoBuilder.append(" kB swap free\n");
15334        }
15335        final long[] ksm = getKsmInfo();
15336        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15337                || ksm[KSM_VOLATILE] != 0) {
15338            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
15339            memInfoBuilder.append(" kB saved from shared ");
15340            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
15341            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
15342            memInfoBuilder.append(" kB unshared; ");
15343            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
15344        }
15345        memInfoBuilder.append("  Free RAM: ");
15346        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
15347                + memInfo.getFreeSizeKb());
15348        memInfoBuilder.append(" kB\n");
15349        memInfoBuilder.append("  Used RAM: ");
15350        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
15351        memInfoBuilder.append(" kB\n");
15352        memInfoBuilder.append("  Lost RAM: ");
15353        memInfoBuilder.append(memInfo.getTotalSizeKb()
15354                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15355                - memInfo.getKernelUsedSizeKb());
15356        memInfoBuilder.append(" kB\n");
15357        Slog.i(TAG, "Low on memory:");
15358        Slog.i(TAG, shortNativeBuilder.toString());
15359        Slog.i(TAG, fullJavaBuilder.toString());
15360        Slog.i(TAG, memInfoBuilder.toString());
15361
15362        StringBuilder dropBuilder = new StringBuilder(1024);
15363        /*
15364        StringWriter oomSw = new StringWriter();
15365        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
15366        StringWriter catSw = new StringWriter();
15367        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15368        String[] emptyArgs = new String[] { };
15369        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
15370        oomPw.flush();
15371        String oomString = oomSw.toString();
15372        */
15373        dropBuilder.append("Low on memory:");
15374        dropBuilder.append(stack);
15375        dropBuilder.append('\n');
15376        dropBuilder.append(fullNativeBuilder);
15377        dropBuilder.append(fullJavaBuilder);
15378        dropBuilder.append('\n');
15379        dropBuilder.append(memInfoBuilder);
15380        dropBuilder.append('\n');
15381        /*
15382        dropBuilder.append(oomString);
15383        dropBuilder.append('\n');
15384        */
15385        StringWriter catSw = new StringWriter();
15386        synchronized (ActivityManagerService.this) {
15387            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15388            String[] emptyArgs = new String[] { };
15389            catPw.println();
15390            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
15391            catPw.println();
15392            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
15393                    false, false, null);
15394            catPw.println();
15395            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
15396            catPw.flush();
15397        }
15398        dropBuilder.append(catSw.toString());
15399        addErrorToDropBox("lowmem", null, "system_server", null,
15400                null, tag.toString(), dropBuilder.toString(), null, null);
15401        //Slog.i(TAG, "Sent to dropbox:");
15402        //Slog.i(TAG, dropBuilder.toString());
15403        synchronized (ActivityManagerService.this) {
15404            long now = SystemClock.uptimeMillis();
15405            if (mLastMemUsageReportTime < now) {
15406                mLastMemUsageReportTime = now;
15407            }
15408        }
15409    }
15410
15411    /**
15412     * Searches array of arguments for the specified string
15413     * @param args array of argument strings
15414     * @param value value to search for
15415     * @return true if the value is contained in the array
15416     */
15417    private static boolean scanArgs(String[] args, String value) {
15418        if (args != null) {
15419            for (String arg : args) {
15420                if (value.equals(arg)) {
15421                    return true;
15422                }
15423            }
15424        }
15425        return false;
15426    }
15427
15428    private final boolean removeDyingProviderLocked(ProcessRecord proc,
15429            ContentProviderRecord cpr, boolean always) {
15430        final boolean inLaunching = mLaunchingProviders.contains(cpr);
15431
15432        if (!inLaunching || always) {
15433            synchronized (cpr) {
15434                cpr.launchingApp = null;
15435                cpr.notifyAll();
15436            }
15437            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
15438            String names[] = cpr.info.authority.split(";");
15439            for (int j = 0; j < names.length; j++) {
15440                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
15441            }
15442        }
15443
15444        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
15445            ContentProviderConnection conn = cpr.connections.get(i);
15446            if (conn.waiting) {
15447                // If this connection is waiting for the provider, then we don't
15448                // need to mess with its process unless we are always removing
15449                // or for some reason the provider is not currently launching.
15450                if (inLaunching && !always) {
15451                    continue;
15452                }
15453            }
15454            ProcessRecord capp = conn.client;
15455            conn.dead = true;
15456            if (conn.stableCount > 0) {
15457                if (!capp.persistent && capp.thread != null
15458                        && capp.pid != 0
15459                        && capp.pid != MY_PID) {
15460                    capp.kill("depends on provider "
15461                            + cpr.name.flattenToShortString()
15462                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
15463                }
15464            } else if (capp.thread != null && conn.provider.provider != null) {
15465                try {
15466                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
15467                } catch (RemoteException e) {
15468                }
15469                // In the protocol here, we don't expect the client to correctly
15470                // clean up this connection, we'll just remove it.
15471                cpr.connections.remove(i);
15472                if (conn.client.conProviders.remove(conn)) {
15473                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
15474                }
15475            }
15476        }
15477
15478        if (inLaunching && always) {
15479            mLaunchingProviders.remove(cpr);
15480        }
15481        return inLaunching;
15482    }
15483
15484    /**
15485     * Main code for cleaning up a process when it has gone away.  This is
15486     * called both as a result of the process dying, or directly when stopping
15487     * a process when running in single process mode.
15488     *
15489     * @return Returns true if the given process has been restarted, so the
15490     * app that was passed in must remain on the process lists.
15491     */
15492    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
15493            boolean restarting, boolean allowRestart, int index) {
15494        if (index >= 0) {
15495            removeLruProcessLocked(app);
15496            ProcessList.remove(app.pid);
15497        }
15498
15499        mProcessesToGc.remove(app);
15500        mPendingPssProcesses.remove(app);
15501
15502        // Dismiss any open dialogs.
15503        if (app.crashDialog != null && !app.forceCrashReport) {
15504            app.crashDialog.dismiss();
15505            app.crashDialog = null;
15506        }
15507        if (app.anrDialog != null) {
15508            app.anrDialog.dismiss();
15509            app.anrDialog = null;
15510        }
15511        if (app.waitDialog != null) {
15512            app.waitDialog.dismiss();
15513            app.waitDialog = null;
15514        }
15515
15516        app.crashing = false;
15517        app.notResponding = false;
15518
15519        app.resetPackageList(mProcessStats);
15520        app.unlinkDeathRecipient();
15521        app.makeInactive(mProcessStats);
15522        app.waitingToKill = null;
15523        app.forcingToForeground = null;
15524        updateProcessForegroundLocked(app, false, false);
15525        app.foregroundActivities = false;
15526        app.hasShownUi = false;
15527        app.treatLikeActivity = false;
15528        app.hasAboveClient = false;
15529        app.hasClientActivities = false;
15530
15531        mServices.killServicesLocked(app, allowRestart);
15532
15533        boolean restart = false;
15534
15535        // Remove published content providers.
15536        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
15537            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
15538            final boolean always = app.bad || !allowRestart;
15539            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
15540            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
15541                // We left the provider in the launching list, need to
15542                // restart it.
15543                restart = true;
15544            }
15545
15546            cpr.provider = null;
15547            cpr.proc = null;
15548        }
15549        app.pubProviders.clear();
15550
15551        // Take care of any launching providers waiting for this process.
15552        if (checkAppInLaunchingProvidersLocked(app, false)) {
15553            restart = true;
15554        }
15555
15556        // Unregister from connected content providers.
15557        if (!app.conProviders.isEmpty()) {
15558            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
15559                ContentProviderConnection conn = app.conProviders.get(i);
15560                conn.provider.connections.remove(conn);
15561                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
15562                        conn.provider.name);
15563            }
15564            app.conProviders.clear();
15565        }
15566
15567        // At this point there may be remaining entries in mLaunchingProviders
15568        // where we were the only one waiting, so they are no longer of use.
15569        // Look for these and clean up if found.
15570        // XXX Commented out for now.  Trying to figure out a way to reproduce
15571        // the actual situation to identify what is actually going on.
15572        if (false) {
15573            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15574                ContentProviderRecord cpr = mLaunchingProviders.get(i);
15575                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
15576                    synchronized (cpr) {
15577                        cpr.launchingApp = null;
15578                        cpr.notifyAll();
15579                    }
15580                }
15581            }
15582        }
15583
15584        skipCurrentReceiverLocked(app);
15585
15586        // Unregister any receivers.
15587        for (int i = app.receivers.size() - 1; i >= 0; i--) {
15588            removeReceiverLocked(app.receivers.valueAt(i));
15589        }
15590        app.receivers.clear();
15591
15592        // If the app is undergoing backup, tell the backup manager about it
15593        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
15594            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
15595                    + mBackupTarget.appInfo + " died during backup");
15596            try {
15597                IBackupManager bm = IBackupManager.Stub.asInterface(
15598                        ServiceManager.getService(Context.BACKUP_SERVICE));
15599                bm.agentDisconnected(app.info.packageName);
15600            } catch (RemoteException e) {
15601                // can't happen; backup manager is local
15602            }
15603        }
15604
15605        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
15606            ProcessChangeItem item = mPendingProcessChanges.get(i);
15607            if (item.pid == app.pid) {
15608                mPendingProcessChanges.remove(i);
15609                mAvailProcessChanges.add(item);
15610            }
15611        }
15612        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
15613
15614        // If the caller is restarting this app, then leave it in its
15615        // current lists and let the caller take care of it.
15616        if (restarting) {
15617            return false;
15618        }
15619
15620        if (!app.persistent || app.isolated) {
15621            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
15622                    "Removing non-persistent process during cleanup: " + app);
15623            removeProcessNameLocked(app.processName, app.uid);
15624            if (mHeavyWeightProcess == app) {
15625                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
15626                        mHeavyWeightProcess.userId, 0));
15627                mHeavyWeightProcess = null;
15628            }
15629        } else if (!app.removed) {
15630            // This app is persistent, so we need to keep its record around.
15631            // If it is not already on the pending app list, add it there
15632            // and start a new process for it.
15633            if (mPersistentStartingProcesses.indexOf(app) < 0) {
15634                mPersistentStartingProcesses.add(app);
15635                restart = true;
15636            }
15637        }
15638        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
15639                TAG_CLEANUP, "Clean-up removing on hold: " + app);
15640        mProcessesOnHold.remove(app);
15641
15642        if (app == mHomeProcess) {
15643            mHomeProcess = null;
15644        }
15645        if (app == mPreviousProcess) {
15646            mPreviousProcess = null;
15647        }
15648
15649        if (restart && !app.isolated) {
15650            // We have components that still need to be running in the
15651            // process, so re-launch it.
15652            if (index < 0) {
15653                ProcessList.remove(app.pid);
15654            }
15655            addProcessNameLocked(app);
15656            startProcessLocked(app, "restart", app.processName);
15657            return true;
15658        } else if (app.pid > 0 && app.pid != MY_PID) {
15659            // Goodbye!
15660            boolean removed;
15661            synchronized (mPidsSelfLocked) {
15662                mPidsSelfLocked.remove(app.pid);
15663                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
15664            }
15665            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
15666            if (app.isolated) {
15667                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
15668            }
15669            app.setPid(0);
15670        }
15671        return false;
15672    }
15673
15674    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
15675        // Look through the content providers we are waiting to have launched,
15676        // and if any run in this process then either schedule a restart of
15677        // the process or kill the client waiting for it if this process has
15678        // gone bad.
15679        boolean restart = false;
15680        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15681            ContentProviderRecord cpr = mLaunchingProviders.get(i);
15682            if (cpr.launchingApp == app) {
15683                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
15684                    restart = true;
15685                } else {
15686                    removeDyingProviderLocked(app, cpr, true);
15687                }
15688            }
15689        }
15690        return restart;
15691    }
15692
15693    // =========================================================
15694    // SERVICES
15695    // =========================================================
15696
15697    @Override
15698    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
15699            int flags) {
15700        enforceNotIsolatedCaller("getServices");
15701        synchronized (this) {
15702            return mServices.getRunningServiceInfoLocked(maxNum, flags);
15703        }
15704    }
15705
15706    @Override
15707    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
15708        enforceNotIsolatedCaller("getRunningServiceControlPanel");
15709        synchronized (this) {
15710            return mServices.getRunningServiceControlPanelLocked(name);
15711        }
15712    }
15713
15714    @Override
15715    public ComponentName startService(IApplicationThread caller, Intent service,
15716            String resolvedType, String callingPackage, int userId)
15717            throws TransactionTooLargeException {
15718        enforceNotIsolatedCaller("startService");
15719        // Refuse possible leaked file descriptors
15720        if (service != null && service.hasFileDescriptors() == true) {
15721            throw new IllegalArgumentException("File descriptors passed in Intent");
15722        }
15723
15724        if (callingPackage == null) {
15725            throw new IllegalArgumentException("callingPackage cannot be null");
15726        }
15727
15728        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15729                "startService: " + service + " type=" + resolvedType);
15730        synchronized(this) {
15731            final int callingPid = Binder.getCallingPid();
15732            final int callingUid = Binder.getCallingUid();
15733            final long origId = Binder.clearCallingIdentity();
15734            ComponentName res = mServices.startServiceLocked(caller, service,
15735                    resolvedType, callingPid, callingUid, callingPackage, userId);
15736            Binder.restoreCallingIdentity(origId);
15737            return res;
15738        }
15739    }
15740
15741    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
15742            String callingPackage, int userId)
15743            throws TransactionTooLargeException {
15744        synchronized(this) {
15745            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15746                    "startServiceInPackage: " + service + " type=" + resolvedType);
15747            final long origId = Binder.clearCallingIdentity();
15748            ComponentName res = mServices.startServiceLocked(null, service,
15749                    resolvedType, -1, uid, callingPackage, userId);
15750            Binder.restoreCallingIdentity(origId);
15751            return res;
15752        }
15753    }
15754
15755    @Override
15756    public int stopService(IApplicationThread caller, Intent service,
15757            String resolvedType, int userId) {
15758        enforceNotIsolatedCaller("stopService");
15759        // Refuse possible leaked file descriptors
15760        if (service != null && service.hasFileDescriptors() == true) {
15761            throw new IllegalArgumentException("File descriptors passed in Intent");
15762        }
15763
15764        synchronized(this) {
15765            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
15766        }
15767    }
15768
15769    @Override
15770    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
15771        enforceNotIsolatedCaller("peekService");
15772        // Refuse possible leaked file descriptors
15773        if (service != null && service.hasFileDescriptors() == true) {
15774            throw new IllegalArgumentException("File descriptors passed in Intent");
15775        }
15776
15777        if (callingPackage == null) {
15778            throw new IllegalArgumentException("callingPackage cannot be null");
15779        }
15780
15781        synchronized(this) {
15782            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
15783        }
15784    }
15785
15786    @Override
15787    public boolean stopServiceToken(ComponentName className, IBinder token,
15788            int startId) {
15789        synchronized(this) {
15790            return mServices.stopServiceTokenLocked(className, token, startId);
15791        }
15792    }
15793
15794    @Override
15795    public void setServiceForeground(ComponentName className, IBinder token,
15796            int id, Notification notification, boolean removeNotification) {
15797        synchronized(this) {
15798            mServices.setServiceForegroundLocked(className, token, id, notification,
15799                    removeNotification);
15800        }
15801    }
15802
15803    @Override
15804    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15805            boolean requireFull, String name, String callerPackage) {
15806        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15807                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15808    }
15809
15810    int unsafeConvertIncomingUser(int userId) {
15811        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15812                ? mCurrentUserId : userId;
15813    }
15814
15815    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15816            int allowMode, String name, String callerPackage) {
15817        final int callingUserId = UserHandle.getUserId(callingUid);
15818        if (callingUserId == userId) {
15819            return userId;
15820        }
15821
15822        // Note that we may be accessing mCurrentUserId outside of a lock...
15823        // shouldn't be a big deal, if this is being called outside
15824        // of a locked context there is intrinsically a race with
15825        // the value the caller will receive and someone else changing it.
15826        // We assume that USER_CURRENT_OR_SELF will use the current user; later
15827        // we will switch to the calling user if access to the current user fails.
15828        int targetUserId = unsafeConvertIncomingUser(userId);
15829
15830        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15831            final boolean allow;
15832            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15833                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15834                // If the caller has this permission, they always pass go.  And collect $200.
15835                allow = true;
15836            } else if (allowMode == ALLOW_FULL_ONLY) {
15837                // We require full access, sucks to be you.
15838                allow = false;
15839            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15840                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15841                // If the caller does not have either permission, they are always doomed.
15842                allow = false;
15843            } else if (allowMode == ALLOW_NON_FULL) {
15844                // We are blanket allowing non-full access, you lucky caller!
15845                allow = true;
15846            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15847                // We may or may not allow this depending on whether the two users are
15848                // in the same profile.
15849                synchronized (mUserProfileGroupIdsSelfLocked) {
15850                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15851                            UserInfo.NO_PROFILE_GROUP_ID);
15852                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15853                            UserInfo.NO_PROFILE_GROUP_ID);
15854                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15855                            && callingProfile == targetProfile;
15856                }
15857            } else {
15858                throw new IllegalArgumentException("Unknown mode: " + allowMode);
15859            }
15860            if (!allow) {
15861                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15862                    // In this case, they would like to just execute as their
15863                    // owner user instead of failing.
15864                    targetUserId = callingUserId;
15865                } else {
15866                    StringBuilder builder = new StringBuilder(128);
15867                    builder.append("Permission Denial: ");
15868                    builder.append(name);
15869                    if (callerPackage != null) {
15870                        builder.append(" from ");
15871                        builder.append(callerPackage);
15872                    }
15873                    builder.append(" asks to run as user ");
15874                    builder.append(userId);
15875                    builder.append(" but is calling from user ");
15876                    builder.append(UserHandle.getUserId(callingUid));
15877                    builder.append("; this requires ");
15878                    builder.append(INTERACT_ACROSS_USERS_FULL);
15879                    if (allowMode != ALLOW_FULL_ONLY) {
15880                        builder.append(" or ");
15881                        builder.append(INTERACT_ACROSS_USERS);
15882                    }
15883                    String msg = builder.toString();
15884                    Slog.w(TAG, msg);
15885                    throw new SecurityException(msg);
15886                }
15887            }
15888        }
15889        if (!allowAll && targetUserId < 0) {
15890            throw new IllegalArgumentException(
15891                    "Call does not support special user #" + targetUserId);
15892        }
15893        // Check shell permission
15894        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15895            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15896                    targetUserId)) {
15897                throw new SecurityException("Shell does not have permission to access user "
15898                        + targetUserId + "\n " + Debug.getCallers(3));
15899            }
15900        }
15901        return targetUserId;
15902    }
15903
15904    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15905            String className, int flags) {
15906        boolean result = false;
15907        // For apps that don't have pre-defined UIDs, check for permission
15908        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15909            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15910                if (ActivityManager.checkUidPermission(
15911                        INTERACT_ACROSS_USERS,
15912                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15913                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15914                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15915                            + " requests FLAG_SINGLE_USER, but app does not hold "
15916                            + INTERACT_ACROSS_USERS;
15917                    Slog.w(TAG, msg);
15918                    throw new SecurityException(msg);
15919                }
15920                // Permission passed
15921                result = true;
15922            }
15923        } else if ("system".equals(componentProcessName)) {
15924            result = true;
15925        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15926            // Phone app and persistent apps are allowed to export singleuser providers.
15927            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15928                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15929        }
15930        if (DEBUG_MU) Slog.v(TAG_MU,
15931                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
15932                + Integer.toHexString(flags) + ") = " + result);
15933        return result;
15934    }
15935
15936    /**
15937     * Checks to see if the caller is in the same app as the singleton
15938     * component, or the component is in a special app. It allows special apps
15939     * to export singleton components but prevents exporting singleton
15940     * components for regular apps.
15941     */
15942    boolean isValidSingletonCall(int callingUid, int componentUid) {
15943        int componentAppId = UserHandle.getAppId(componentUid);
15944        return UserHandle.isSameApp(callingUid, componentUid)
15945                || componentAppId == Process.SYSTEM_UID
15946                || componentAppId == Process.PHONE_UID
15947                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15948                        == PackageManager.PERMISSION_GRANTED;
15949    }
15950
15951    public int bindService(IApplicationThread caller, IBinder token, Intent service,
15952            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
15953            int userId) throws TransactionTooLargeException {
15954        enforceNotIsolatedCaller("bindService");
15955
15956        // Refuse possible leaked file descriptors
15957        if (service != null && service.hasFileDescriptors() == true) {
15958            throw new IllegalArgumentException("File descriptors passed in Intent");
15959        }
15960
15961        if (callingPackage == null) {
15962            throw new IllegalArgumentException("callingPackage cannot be null");
15963        }
15964
15965        synchronized(this) {
15966            return mServices.bindServiceLocked(caller, token, service,
15967                    resolvedType, connection, flags, callingPackage, userId);
15968        }
15969    }
15970
15971    public boolean unbindService(IServiceConnection connection) {
15972        synchronized (this) {
15973            return mServices.unbindServiceLocked(connection);
15974        }
15975    }
15976
15977    public void publishService(IBinder token, Intent intent, IBinder service) {
15978        // Refuse possible leaked file descriptors
15979        if (intent != null && intent.hasFileDescriptors() == true) {
15980            throw new IllegalArgumentException("File descriptors passed in Intent");
15981        }
15982
15983        synchronized(this) {
15984            if (!(token instanceof ServiceRecord)) {
15985                throw new IllegalArgumentException("Invalid service token");
15986            }
15987            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15988        }
15989    }
15990
15991    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15992        // Refuse possible leaked file descriptors
15993        if (intent != null && intent.hasFileDescriptors() == true) {
15994            throw new IllegalArgumentException("File descriptors passed in Intent");
15995        }
15996
15997        synchronized(this) {
15998            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15999        }
16000    }
16001
16002    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16003        synchronized(this) {
16004            if (!(token instanceof ServiceRecord)) {
16005                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16006                throw new IllegalArgumentException("Invalid service token");
16007            }
16008            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16009        }
16010    }
16011
16012    // =========================================================
16013    // BACKUP AND RESTORE
16014    // =========================================================
16015
16016    // Cause the target app to be launched if necessary and its backup agent
16017    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16018    // activity manager to announce its creation.
16019    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16020        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16021                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16022        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16023
16024        synchronized(this) {
16025            // !!! TODO: currently no check here that we're already bound
16026            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16027            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16028            synchronized (stats) {
16029                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16030            }
16031
16032            // Backup agent is now in use, its package can't be stopped.
16033            try {
16034                AppGlobals.getPackageManager().setPackageStoppedState(
16035                        app.packageName, false, UserHandle.getUserId(app.uid));
16036            } catch (RemoteException e) {
16037            } catch (IllegalArgumentException e) {
16038                Slog.w(TAG, "Failed trying to unstop package "
16039                        + app.packageName + ": " + e);
16040            }
16041
16042            BackupRecord r = new BackupRecord(ss, app, backupMode);
16043            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16044                    ? new ComponentName(app.packageName, app.backupAgentName)
16045                    : new ComponentName("android", "FullBackupAgent");
16046            // startProcessLocked() returns existing proc's record if it's already running
16047            ProcessRecord proc = startProcessLocked(app.processName, app,
16048                    false, 0, "backup", hostingName, false, false, false);
16049            if (proc == null) {
16050                Slog.e(TAG, "Unable to start backup agent process " + r);
16051                return false;
16052            }
16053
16054            r.app = proc;
16055            mBackupTarget = r;
16056            mBackupAppName = app.packageName;
16057
16058            // Try not to kill the process during backup
16059            updateOomAdjLocked(proc);
16060
16061            // If the process is already attached, schedule the creation of the backup agent now.
16062            // If it is not yet live, this will be done when it attaches to the framework.
16063            if (proc.thread != null) {
16064                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16065                try {
16066                    proc.thread.scheduleCreateBackupAgent(app,
16067                            compatibilityInfoForPackageLocked(app), backupMode);
16068                } catch (RemoteException e) {
16069                    // Will time out on the backup manager side
16070                }
16071            } else {
16072                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16073            }
16074            // Invariants: at this point, the target app process exists and the application
16075            // is either already running or in the process of coming up.  mBackupTarget and
16076            // mBackupAppName describe the app, so that when it binds back to the AM we
16077            // know that it's scheduled for a backup-agent operation.
16078        }
16079
16080        return true;
16081    }
16082
16083    @Override
16084    public void clearPendingBackup() {
16085        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16086        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16087
16088        synchronized (this) {
16089            mBackupTarget = null;
16090            mBackupAppName = null;
16091        }
16092    }
16093
16094    // A backup agent has just come up
16095    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16096        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16097                + " = " + agent);
16098
16099        synchronized(this) {
16100            if (!agentPackageName.equals(mBackupAppName)) {
16101                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16102                return;
16103            }
16104        }
16105
16106        long oldIdent = Binder.clearCallingIdentity();
16107        try {
16108            IBackupManager bm = IBackupManager.Stub.asInterface(
16109                    ServiceManager.getService(Context.BACKUP_SERVICE));
16110            bm.agentConnected(agentPackageName, agent);
16111        } catch (RemoteException e) {
16112            // can't happen; the backup manager service is local
16113        } catch (Exception e) {
16114            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16115            e.printStackTrace();
16116        } finally {
16117            Binder.restoreCallingIdentity(oldIdent);
16118        }
16119    }
16120
16121    // done with this agent
16122    public void unbindBackupAgent(ApplicationInfo appInfo) {
16123        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16124        if (appInfo == null) {
16125            Slog.w(TAG, "unbind backup agent for null app");
16126            return;
16127        }
16128
16129        synchronized(this) {
16130            try {
16131                if (mBackupAppName == null) {
16132                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16133                    return;
16134                }
16135
16136                if (!mBackupAppName.equals(appInfo.packageName)) {
16137                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16138                    return;
16139                }
16140
16141                // Not backing this app up any more; reset its OOM adjustment
16142                final ProcessRecord proc = mBackupTarget.app;
16143                updateOomAdjLocked(proc);
16144
16145                // If the app crashed during backup, 'thread' will be null here
16146                if (proc.thread != null) {
16147                    try {
16148                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16149                                compatibilityInfoForPackageLocked(appInfo));
16150                    } catch (Exception e) {
16151                        Slog.e(TAG, "Exception when unbinding backup agent:");
16152                        e.printStackTrace();
16153                    }
16154                }
16155            } finally {
16156                mBackupTarget = null;
16157                mBackupAppName = null;
16158            }
16159        }
16160    }
16161    // =========================================================
16162    // BROADCASTS
16163    // =========================================================
16164
16165    boolean isPendingBroadcastProcessLocked(int pid) {
16166        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16167                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16168    }
16169
16170    void skipPendingBroadcastLocked(int pid) {
16171            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16172            for (BroadcastQueue queue : mBroadcastQueues) {
16173                queue.skipPendingBroadcastLocked(pid);
16174            }
16175    }
16176
16177    // The app just attached; send any pending broadcasts that it should receive
16178    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16179        boolean didSomething = false;
16180        for (BroadcastQueue queue : mBroadcastQueues) {
16181            didSomething |= queue.sendPendingBroadcastsLocked(app);
16182        }
16183        return didSomething;
16184    }
16185
16186    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16187            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16188        enforceNotIsolatedCaller("registerReceiver");
16189        ArrayList<Intent> stickyIntents = null;
16190        ProcessRecord callerApp = null;
16191        int callingUid;
16192        int callingPid;
16193        synchronized(this) {
16194            if (caller != null) {
16195                callerApp = getRecordForAppLocked(caller);
16196                if (callerApp == null) {
16197                    throw new SecurityException(
16198                            "Unable to find app for caller " + caller
16199                            + " (pid=" + Binder.getCallingPid()
16200                            + ") when registering receiver " + receiver);
16201                }
16202                if (callerApp.info.uid != Process.SYSTEM_UID &&
16203                        !callerApp.pkgList.containsKey(callerPackage) &&
16204                        !"android".equals(callerPackage)) {
16205                    throw new SecurityException("Given caller package " + callerPackage
16206                            + " is not running in process " + callerApp);
16207                }
16208                callingUid = callerApp.info.uid;
16209                callingPid = callerApp.pid;
16210            } else {
16211                callerPackage = null;
16212                callingUid = Binder.getCallingUid();
16213                callingPid = Binder.getCallingPid();
16214            }
16215
16216            userId = handleIncomingUser(callingPid, callingUid, userId,
16217                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16218
16219            Iterator<String> actions = filter.actionsIterator();
16220            if (actions == null) {
16221                ArrayList<String> noAction = new ArrayList<String>(1);
16222                noAction.add(null);
16223                actions = noAction.iterator();
16224            }
16225
16226            // Collect stickies of users
16227            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16228            while (actions.hasNext()) {
16229                String action = actions.next();
16230                for (int id : userIds) {
16231                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16232                    if (stickies != null) {
16233                        ArrayList<Intent> intents = stickies.get(action);
16234                        if (intents != null) {
16235                            if (stickyIntents == null) {
16236                                stickyIntents = new ArrayList<Intent>();
16237                            }
16238                            stickyIntents.addAll(intents);
16239                        }
16240                    }
16241                }
16242            }
16243        }
16244
16245        ArrayList<Intent> allSticky = null;
16246        if (stickyIntents != null) {
16247            final ContentResolver resolver = mContext.getContentResolver();
16248            // Look for any matching sticky broadcasts...
16249            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16250                Intent intent = stickyIntents.get(i);
16251                // If intent has scheme "content", it will need to acccess
16252                // provider that needs to lock mProviderMap in ActivityThread
16253                // and also it may need to wait application response, so we
16254                // cannot lock ActivityManagerService here.
16255                if (filter.match(resolver, intent, true, TAG) >= 0) {
16256                    if (allSticky == null) {
16257                        allSticky = new ArrayList<Intent>();
16258                    }
16259                    allSticky.add(intent);
16260                }
16261            }
16262        }
16263
16264        // The first sticky in the list is returned directly back to the client.
16265        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16266        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16267        if (receiver == null) {
16268            return sticky;
16269        }
16270
16271        synchronized (this) {
16272            if (callerApp != null && (callerApp.thread == null
16273                    || callerApp.thread.asBinder() != caller.asBinder())) {
16274                // Original caller already died
16275                return null;
16276            }
16277            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16278            if (rl == null) {
16279                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16280                        userId, receiver);
16281                if (rl.app != null) {
16282                    rl.app.receivers.add(rl);
16283                } else {
16284                    try {
16285                        receiver.asBinder().linkToDeath(rl, 0);
16286                    } catch (RemoteException e) {
16287                        return sticky;
16288                    }
16289                    rl.linkedToDeath = true;
16290                }
16291                mRegisteredReceivers.put(receiver.asBinder(), rl);
16292            } else if (rl.uid != callingUid) {
16293                throw new IllegalArgumentException(
16294                        "Receiver requested to register for uid " + callingUid
16295                        + " was previously registered for uid " + rl.uid);
16296            } else if (rl.pid != callingPid) {
16297                throw new IllegalArgumentException(
16298                        "Receiver requested to register for pid " + callingPid
16299                        + " was previously registered for pid " + rl.pid);
16300            } else if (rl.userId != userId) {
16301                throw new IllegalArgumentException(
16302                        "Receiver requested to register for user " + userId
16303                        + " was previously registered for user " + rl.userId);
16304            }
16305            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16306                    permission, callingUid, userId);
16307            rl.add(bf);
16308            if (!bf.debugCheck()) {
16309                Slog.w(TAG, "==> For Dynamic broadcast");
16310            }
16311            mReceiverResolver.addFilter(bf);
16312
16313            // Enqueue broadcasts for all existing stickies that match
16314            // this filter.
16315            if (allSticky != null) {
16316                ArrayList receivers = new ArrayList();
16317                receivers.add(bf);
16318
16319                final int stickyCount = allSticky.size();
16320                for (int i = 0; i < stickyCount; i++) {
16321                    Intent intent = allSticky.get(i);
16322                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16323                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16324                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16325                            null, 0, null, null, false, true, true, -1);
16326                    queue.enqueueParallelBroadcastLocked(r);
16327                    queue.scheduleBroadcastsLocked();
16328                }
16329            }
16330
16331            return sticky;
16332        }
16333    }
16334
16335    public void unregisterReceiver(IIntentReceiver receiver) {
16336        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16337
16338        final long origId = Binder.clearCallingIdentity();
16339        try {
16340            boolean doTrim = false;
16341
16342            synchronized(this) {
16343                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16344                if (rl != null) {
16345                    final BroadcastRecord r = rl.curBroadcast;
16346                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16347                        final boolean doNext = r.queue.finishReceiverLocked(
16348                                r, r.resultCode, r.resultData, r.resultExtras,
16349                                r.resultAbort, false);
16350                        if (doNext) {
16351                            doTrim = true;
16352                            r.queue.processNextBroadcast(false);
16353                        }
16354                    }
16355
16356                    if (rl.app != null) {
16357                        rl.app.receivers.remove(rl);
16358                    }
16359                    removeReceiverLocked(rl);
16360                    if (rl.linkedToDeath) {
16361                        rl.linkedToDeath = false;
16362                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
16363                    }
16364                }
16365            }
16366
16367            // If we actually concluded any broadcasts, we might now be able
16368            // to trim the recipients' apps from our working set
16369            if (doTrim) {
16370                trimApplications();
16371                return;
16372            }
16373
16374        } finally {
16375            Binder.restoreCallingIdentity(origId);
16376        }
16377    }
16378
16379    void removeReceiverLocked(ReceiverList rl) {
16380        mRegisteredReceivers.remove(rl.receiver.asBinder());
16381        for (int i = rl.size() - 1; i >= 0; i--) {
16382            mReceiverResolver.removeFilter(rl.get(i));
16383        }
16384    }
16385
16386    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16387        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16388            ProcessRecord r = mLruProcesses.get(i);
16389            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16390                try {
16391                    r.thread.dispatchPackageBroadcast(cmd, packages);
16392                } catch (RemoteException ex) {
16393                }
16394            }
16395        }
16396    }
16397
16398    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16399            int callingUid, int[] users) {
16400        List<ResolveInfo> receivers = null;
16401        try {
16402            HashSet<ComponentName> singleUserReceivers = null;
16403            boolean scannedFirstReceivers = false;
16404            for (int user : users) {
16405                // Skip users that have Shell restrictions
16406                if (callingUid == Process.SHELL_UID
16407                        && getUserManagerLocked().hasUserRestriction(
16408                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
16409                    continue;
16410                }
16411                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16412                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
16413                if (user != UserHandle.USER_OWNER && newReceivers != null) {
16414                    // If this is not the primary user, we need to check for
16415                    // any receivers that should be filtered out.
16416                    for (int i=0; i<newReceivers.size(); i++) {
16417                        ResolveInfo ri = newReceivers.get(i);
16418                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
16419                            newReceivers.remove(i);
16420                            i--;
16421                        }
16422                    }
16423                }
16424                if (newReceivers != null && newReceivers.size() == 0) {
16425                    newReceivers = null;
16426                }
16427                if (receivers == null) {
16428                    receivers = newReceivers;
16429                } else if (newReceivers != null) {
16430                    // We need to concatenate the additional receivers
16431                    // found with what we have do far.  This would be easy,
16432                    // but we also need to de-dup any receivers that are
16433                    // singleUser.
16434                    if (!scannedFirstReceivers) {
16435                        // Collect any single user receivers we had already retrieved.
16436                        scannedFirstReceivers = true;
16437                        for (int i=0; i<receivers.size(); i++) {
16438                            ResolveInfo ri = receivers.get(i);
16439                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16440                                ComponentName cn = new ComponentName(
16441                                        ri.activityInfo.packageName, ri.activityInfo.name);
16442                                if (singleUserReceivers == null) {
16443                                    singleUserReceivers = new HashSet<ComponentName>();
16444                                }
16445                                singleUserReceivers.add(cn);
16446                            }
16447                        }
16448                    }
16449                    // Add the new results to the existing results, tracking
16450                    // and de-dupping single user receivers.
16451                    for (int i=0; i<newReceivers.size(); i++) {
16452                        ResolveInfo ri = newReceivers.get(i);
16453                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16454                            ComponentName cn = new ComponentName(
16455                                    ri.activityInfo.packageName, ri.activityInfo.name);
16456                            if (singleUserReceivers == null) {
16457                                singleUserReceivers = new HashSet<ComponentName>();
16458                            }
16459                            if (!singleUserReceivers.contains(cn)) {
16460                                singleUserReceivers.add(cn);
16461                                receivers.add(ri);
16462                            }
16463                        } else {
16464                            receivers.add(ri);
16465                        }
16466                    }
16467                }
16468            }
16469        } catch (RemoteException ex) {
16470            // pm is in same process, this will never happen.
16471        }
16472        return receivers;
16473    }
16474
16475    private final int broadcastIntentLocked(ProcessRecord callerApp,
16476            String callerPackage, Intent intent, String resolvedType,
16477            IIntentReceiver resultTo, int resultCode, String resultData,
16478            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle options,
16479            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
16480        intent = new Intent(intent);
16481
16482        // By default broadcasts do not go to stopped apps.
16483        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
16484
16485        // If we have not finished booting, don't allow this to launch new processes.
16486        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
16487            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16488        }
16489
16490        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
16491                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
16492                + " ordered=" + ordered + " userid=" + userId);
16493        if ((resultTo != null) && !ordered) {
16494            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
16495        }
16496
16497        userId = handleIncomingUser(callingPid, callingUid, userId,
16498                true, ALLOW_NON_FULL, "broadcast", callerPackage);
16499
16500        // Make sure that the user who is receiving this broadcast is running.
16501        // If not, we will just skip it. Make an exception for shutdown broadcasts
16502        // and upgrade steps.
16503
16504        if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
16505            if ((callingUid != Process.SYSTEM_UID
16506                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
16507                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
16508                Slog.w(TAG, "Skipping broadcast of " + intent
16509                        + ": user " + userId + " is stopped");
16510                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
16511            }
16512        }
16513
16514        BroadcastOptions brOptions = null;
16515        if (options != null) {
16516            brOptions = new BroadcastOptions(options);
16517            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
16518                // See if the caller is allowed to do this.  Note we are checking against
16519                // the actual real caller (not whoever provided the operation as say a
16520                // PendingIntent), because that who is actually supplied the arguments.
16521                if (checkComponentPermission(
16522                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
16523                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
16524                        != PackageManager.PERMISSION_GRANTED) {
16525                    String msg = "Permission Denial: " + intent.getAction()
16526                            + " broadcast from " + callerPackage + " (pid=" + callingPid
16527                            + ", uid=" + callingUid + ")"
16528                            + " requires "
16529                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
16530                    Slog.w(TAG, msg);
16531                    throw new SecurityException(msg);
16532                }
16533            }
16534        }
16535
16536        /*
16537         * Prevent non-system code (defined here to be non-persistent
16538         * processes) from sending protected broadcasts.
16539         */
16540        int callingAppId = UserHandle.getAppId(callingUid);
16541        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
16542            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
16543            || callingAppId == Process.NFC_UID || callingUid == 0) {
16544            // Always okay.
16545        } else if (callerApp == null || !callerApp.persistent) {
16546            try {
16547                if (AppGlobals.getPackageManager().isProtectedBroadcast(
16548                        intent.getAction())) {
16549                    String msg = "Permission Denial: not allowed to send broadcast "
16550                            + intent.getAction() + " from pid="
16551                            + callingPid + ", uid=" + callingUid;
16552                    Slog.w(TAG, msg);
16553                    throw new SecurityException(msg);
16554                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
16555                    // Special case for compatibility: we don't want apps to send this,
16556                    // but historically it has not been protected and apps may be using it
16557                    // to poke their own app widget.  So, instead of making it protected,
16558                    // just limit it to the caller.
16559                    if (callerApp == null) {
16560                        String msg = "Permission Denial: not allowed to send broadcast "
16561                                + intent.getAction() + " from unknown caller.";
16562                        Slog.w(TAG, msg);
16563                        throw new SecurityException(msg);
16564                    } else if (intent.getComponent() != null) {
16565                        // They are good enough to send to an explicit component...  verify
16566                        // it is being sent to the calling app.
16567                        if (!intent.getComponent().getPackageName().equals(
16568                                callerApp.info.packageName)) {
16569                            String msg = "Permission Denial: not allowed to send broadcast "
16570                                    + intent.getAction() + " to "
16571                                    + intent.getComponent().getPackageName() + " from "
16572                                    + callerApp.info.packageName;
16573                            Slog.w(TAG, msg);
16574                            throw new SecurityException(msg);
16575                        }
16576                    } else {
16577                        // Limit broadcast to their own package.
16578                        intent.setPackage(callerApp.info.packageName);
16579                    }
16580                }
16581            } catch (RemoteException e) {
16582                Slog.w(TAG, "Remote exception", e);
16583                return ActivityManager.BROADCAST_SUCCESS;
16584            }
16585        }
16586
16587        final String action = intent.getAction();
16588        if (action != null) {
16589            switch (action) {
16590                case Intent.ACTION_UID_REMOVED:
16591                case Intent.ACTION_PACKAGE_REMOVED:
16592                case Intent.ACTION_PACKAGE_CHANGED:
16593                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16594                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16595                    // Handle special intents: if this broadcast is from the package
16596                    // manager about a package being removed, we need to remove all of
16597                    // its activities from the history stack.
16598                    if (checkComponentPermission(
16599                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
16600                            callingPid, callingUid, -1, true)
16601                            != PackageManager.PERMISSION_GRANTED) {
16602                        String msg = "Permission Denial: " + intent.getAction()
16603                                + " broadcast from " + callerPackage + " (pid=" + callingPid
16604                                + ", uid=" + callingUid + ")"
16605                                + " requires "
16606                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
16607                        Slog.w(TAG, msg);
16608                        throw new SecurityException(msg);
16609                    }
16610                    switch (action) {
16611                        case Intent.ACTION_UID_REMOVED:
16612                            final Bundle intentExtras = intent.getExtras();
16613                            final int uid = intentExtras != null
16614                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
16615                            if (uid >= 0) {
16616                                mBatteryStatsService.removeUid(uid);
16617                                mAppOpsService.uidRemoved(uid);
16618                            }
16619                            break;
16620                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16621                            // If resources are unavailable just force stop all those packages
16622                            // and flush the attribute cache as well.
16623                            String list[] =
16624                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16625                            if (list != null && list.length > 0) {
16626                                for (int i = 0; i < list.length; i++) {
16627                                    forceStopPackageLocked(list[i], -1, false, true, true,
16628                                            false, false, userId, "storage unmount");
16629                                }
16630                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16631                                sendPackageBroadcastLocked(
16632                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
16633                                        userId);
16634                            }
16635                            break;
16636                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16637                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16638                            break;
16639                        case Intent.ACTION_PACKAGE_REMOVED:
16640                        case Intent.ACTION_PACKAGE_CHANGED:
16641                            Uri data = intent.getData();
16642                            String ssp;
16643                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
16644                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
16645                                boolean fullUninstall = removed &&
16646                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16647                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
16648                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
16649                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
16650                                            false, true, true, false, fullUninstall, userId,
16651                                            removed ? "pkg removed" : "pkg changed");
16652                                }
16653                                if (removed) {
16654                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
16655                                            new String[] {ssp}, userId);
16656                                    if (fullUninstall) {
16657                                        mAppOpsService.packageRemoved(
16658                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
16659
16660                                        // Remove all permissions granted from/to this package
16661                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
16662
16663                                        removeTasksByPackageNameLocked(ssp, userId);
16664                                        mBatteryStatsService.notePackageUninstalled(ssp);
16665                                    }
16666                                } else {
16667                                    cleanupDisabledPackageComponentsLocked(ssp, userId,
16668                                            intent.getStringArrayExtra(
16669                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
16670                                }
16671                            }
16672                            break;
16673                    }
16674                    break;
16675                case Intent.ACTION_PACKAGE_ADDED:
16676                    // Special case for adding a package: by default turn on compatibility mode.
16677                    Uri data = intent.getData();
16678                    String ssp;
16679                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
16680                        final boolean replacing =
16681                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16682                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
16683
16684                        try {
16685                            ApplicationInfo ai = AppGlobals.getPackageManager().
16686                                    getApplicationInfo(ssp, 0, 0);
16687                            mBatteryStatsService.notePackageInstalled(ssp,
16688                                    ai != null ? ai.versionCode : 0);
16689                        } catch (RemoteException e) {
16690                        }
16691                    }
16692                    break;
16693                case Intent.ACTION_TIMEZONE_CHANGED:
16694                    // If this is the time zone changed action, queue up a message that will reset
16695                    // the timezone of all currently running processes. This message will get
16696                    // queued up before the broadcast happens.
16697                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
16698                    break;
16699                case Intent.ACTION_TIME_CHANGED:
16700                    // If the user set the time, let all running processes know.
16701                    final int is24Hour =
16702                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
16703                                    : 0;
16704                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
16705                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16706                    synchronized (stats) {
16707                        stats.noteCurrentTimeChangedLocked();
16708                    }
16709                    break;
16710                case Intent.ACTION_CLEAR_DNS_CACHE:
16711                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
16712                    break;
16713                case Proxy.PROXY_CHANGE_ACTION:
16714                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
16715                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
16716                    break;
16717            }
16718        }
16719
16720        // Add to the sticky list if requested.
16721        if (sticky) {
16722            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
16723                    callingPid, callingUid)
16724                    != PackageManager.PERMISSION_GRANTED) {
16725                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
16726                        + callingPid + ", uid=" + callingUid
16727                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16728                Slog.w(TAG, msg);
16729                throw new SecurityException(msg);
16730            }
16731            if (requiredPermissions != null && requiredPermissions.length > 0) {
16732                Slog.w(TAG, "Can't broadcast sticky intent " + intent
16733                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
16734                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
16735            }
16736            if (intent.getComponent() != null) {
16737                throw new SecurityException(
16738                        "Sticky broadcasts can't target a specific component");
16739            }
16740            // We use userId directly here, since the "all" target is maintained
16741            // as a separate set of sticky broadcasts.
16742            if (userId != UserHandle.USER_ALL) {
16743                // But first, if this is not a broadcast to all users, then
16744                // make sure it doesn't conflict with an existing broadcast to
16745                // all users.
16746                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
16747                        UserHandle.USER_ALL);
16748                if (stickies != null) {
16749                    ArrayList<Intent> list = stickies.get(intent.getAction());
16750                    if (list != null) {
16751                        int N = list.size();
16752                        int i;
16753                        for (i=0; i<N; i++) {
16754                            if (intent.filterEquals(list.get(i))) {
16755                                throw new IllegalArgumentException(
16756                                        "Sticky broadcast " + intent + " for user "
16757                                        + userId + " conflicts with existing global broadcast");
16758                            }
16759                        }
16760                    }
16761                }
16762            }
16763            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16764            if (stickies == null) {
16765                stickies = new ArrayMap<>();
16766                mStickyBroadcasts.put(userId, stickies);
16767            }
16768            ArrayList<Intent> list = stickies.get(intent.getAction());
16769            if (list == null) {
16770                list = new ArrayList<>();
16771                stickies.put(intent.getAction(), list);
16772            }
16773            final int stickiesCount = list.size();
16774            int i;
16775            for (i = 0; i < stickiesCount; i++) {
16776                if (intent.filterEquals(list.get(i))) {
16777                    // This sticky already exists, replace it.
16778                    list.set(i, new Intent(intent));
16779                    break;
16780                }
16781            }
16782            if (i >= stickiesCount) {
16783                list.add(new Intent(intent));
16784            }
16785        }
16786
16787        int[] users;
16788        if (userId == UserHandle.USER_ALL) {
16789            // Caller wants broadcast to go to all started users.
16790            users = mStartedUserArray;
16791        } else {
16792            // Caller wants broadcast to go to one specific user.
16793            users = new int[] {userId};
16794        }
16795
16796        // Figure out who all will receive this broadcast.
16797        List receivers = null;
16798        List<BroadcastFilter> registeredReceivers = null;
16799        // Need to resolve the intent to interested receivers...
16800        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
16801                 == 0) {
16802            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
16803        }
16804        if (intent.getComponent() == null) {
16805            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
16806                // Query one target user at a time, excluding shell-restricted users
16807                UserManagerService ums = getUserManagerLocked();
16808                for (int i = 0; i < users.length; i++) {
16809                    if (ums.hasUserRestriction(
16810                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
16811                        continue;
16812                    }
16813                    List<BroadcastFilter> registeredReceiversForUser =
16814                            mReceiverResolver.queryIntent(intent,
16815                                    resolvedType, false, users[i]);
16816                    if (registeredReceivers == null) {
16817                        registeredReceivers = registeredReceiversForUser;
16818                    } else if (registeredReceiversForUser != null) {
16819                        registeredReceivers.addAll(registeredReceiversForUser);
16820                    }
16821                }
16822            } else {
16823                registeredReceivers = mReceiverResolver.queryIntent(intent,
16824                        resolvedType, false, userId);
16825            }
16826        }
16827
16828        final boolean replacePending =
16829                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16830
16831        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
16832                + " replacePending=" + replacePending);
16833
16834        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16835        if (!ordered && NR > 0) {
16836            // If we are not serializing this broadcast, then send the
16837            // registered receivers separately so they don't wait for the
16838            // components to be launched.
16839            final BroadcastQueue queue = broadcastQueueForIntent(intent);
16840            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16841                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
16842                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
16843                    resultExtras, ordered, sticky, false, userId);
16844            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
16845            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16846            if (!replaced) {
16847                queue.enqueueParallelBroadcastLocked(r);
16848                queue.scheduleBroadcastsLocked();
16849            }
16850            registeredReceivers = null;
16851            NR = 0;
16852        }
16853
16854        // Merge into one list.
16855        int ir = 0;
16856        if (receivers != null) {
16857            // A special case for PACKAGE_ADDED: do not allow the package
16858            // being added to see this broadcast.  This prevents them from
16859            // using this as a back door to get run as soon as they are
16860            // installed.  Maybe in the future we want to have a special install
16861            // broadcast or such for apps, but we'd like to deliberately make
16862            // this decision.
16863            String skipPackages[] = null;
16864            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16865                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16866                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16867                Uri data = intent.getData();
16868                if (data != null) {
16869                    String pkgName = data.getSchemeSpecificPart();
16870                    if (pkgName != null) {
16871                        skipPackages = new String[] { pkgName };
16872                    }
16873                }
16874            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16875                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16876            }
16877            if (skipPackages != null && (skipPackages.length > 0)) {
16878                for (String skipPackage : skipPackages) {
16879                    if (skipPackage != null) {
16880                        int NT = receivers.size();
16881                        for (int it=0; it<NT; it++) {
16882                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
16883                            if (curt.activityInfo.packageName.equals(skipPackage)) {
16884                                receivers.remove(it);
16885                                it--;
16886                                NT--;
16887                            }
16888                        }
16889                    }
16890                }
16891            }
16892
16893            int NT = receivers != null ? receivers.size() : 0;
16894            int it = 0;
16895            ResolveInfo curt = null;
16896            BroadcastFilter curr = null;
16897            while (it < NT && ir < NR) {
16898                if (curt == null) {
16899                    curt = (ResolveInfo)receivers.get(it);
16900                }
16901                if (curr == null) {
16902                    curr = registeredReceivers.get(ir);
16903                }
16904                if (curr.getPriority() >= curt.priority) {
16905                    // Insert this broadcast record into the final list.
16906                    receivers.add(it, curr);
16907                    ir++;
16908                    curr = null;
16909                    it++;
16910                    NT++;
16911                } else {
16912                    // Skip to the next ResolveInfo in the final list.
16913                    it++;
16914                    curt = null;
16915                }
16916            }
16917        }
16918        while (ir < NR) {
16919            if (receivers == null) {
16920                receivers = new ArrayList();
16921            }
16922            receivers.add(registeredReceivers.get(ir));
16923            ir++;
16924        }
16925
16926        if ((receivers != null && receivers.size() > 0)
16927                || resultTo != null) {
16928            BroadcastQueue queue = broadcastQueueForIntent(intent);
16929            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16930                    callerPackage, callingPid, callingUid, resolvedType,
16931                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
16932                    resultData, resultExtras, ordered, sticky, false, userId);
16933
16934            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
16935                    + ": prev had " + queue.mOrderedBroadcasts.size());
16936            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
16937                    "Enqueueing broadcast " + r.intent.getAction());
16938
16939            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16940            if (!replaced) {
16941                queue.enqueueOrderedBroadcastLocked(r);
16942                queue.scheduleBroadcastsLocked();
16943            }
16944        }
16945
16946        return ActivityManager.BROADCAST_SUCCESS;
16947    }
16948
16949    final Intent verifyBroadcastLocked(Intent intent) {
16950        // Refuse possible leaked file descriptors
16951        if (intent != null && intent.hasFileDescriptors() == true) {
16952            throw new IllegalArgumentException("File descriptors passed in Intent");
16953        }
16954
16955        int flags = intent.getFlags();
16956
16957        if (!mProcessesReady) {
16958            // if the caller really truly claims to know what they're doing, go
16959            // ahead and allow the broadcast without launching any receivers
16960            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16961                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
16962            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16963                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16964                        + " before boot completion");
16965                throw new IllegalStateException("Cannot broadcast before boot completed");
16966            }
16967        }
16968
16969        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16970            throw new IllegalArgumentException(
16971                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16972        }
16973
16974        return intent;
16975    }
16976
16977    public final int broadcastIntent(IApplicationThread caller,
16978            Intent intent, String resolvedType, IIntentReceiver resultTo,
16979            int resultCode, String resultData, Bundle resultExtras,
16980            String[] requiredPermissions, int appOp, Bundle options,
16981            boolean serialized, boolean sticky, int userId) {
16982        enforceNotIsolatedCaller("broadcastIntent");
16983        synchronized(this) {
16984            intent = verifyBroadcastLocked(intent);
16985
16986            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16987            final int callingPid = Binder.getCallingPid();
16988            final int callingUid = Binder.getCallingUid();
16989            final long origId = Binder.clearCallingIdentity();
16990            int res = broadcastIntentLocked(callerApp,
16991                    callerApp != null ? callerApp.info.packageName : null,
16992                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
16993                    requiredPermissions, appOp, null, serialized, sticky,
16994                    callingPid, callingUid, userId);
16995            Binder.restoreCallingIdentity(origId);
16996            return res;
16997        }
16998    }
16999
17000
17001    int broadcastIntentInPackage(String packageName, int uid,
17002            Intent intent, String resolvedType, IIntentReceiver resultTo,
17003            int resultCode, String resultData, Bundle resultExtras,
17004            String requiredPermission, Bundle options, boolean serialized, boolean sticky,
17005            int userId) {
17006        synchronized(this) {
17007            intent = verifyBroadcastLocked(intent);
17008
17009            final long origId = Binder.clearCallingIdentity();
17010            String[] requiredPermissions = requiredPermission == null ? null
17011                    : new String[] {requiredPermission};
17012            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17013                    resultTo, resultCode, resultData, resultExtras,
17014                    requiredPermissions, AppOpsManager.OP_NONE, options, serialized,
17015                    sticky, -1, uid, userId);
17016            Binder.restoreCallingIdentity(origId);
17017            return res;
17018        }
17019    }
17020
17021    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17022        // Refuse possible leaked file descriptors
17023        if (intent != null && intent.hasFileDescriptors() == true) {
17024            throw new IllegalArgumentException("File descriptors passed in Intent");
17025        }
17026
17027        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17028                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17029
17030        synchronized(this) {
17031            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17032                    != PackageManager.PERMISSION_GRANTED) {
17033                String msg = "Permission Denial: unbroadcastIntent() from pid="
17034                        + Binder.getCallingPid()
17035                        + ", uid=" + Binder.getCallingUid()
17036                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17037                Slog.w(TAG, msg);
17038                throw new SecurityException(msg);
17039            }
17040            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17041            if (stickies != null) {
17042                ArrayList<Intent> list = stickies.get(intent.getAction());
17043                if (list != null) {
17044                    int N = list.size();
17045                    int i;
17046                    for (i=0; i<N; i++) {
17047                        if (intent.filterEquals(list.get(i))) {
17048                            list.remove(i);
17049                            break;
17050                        }
17051                    }
17052                    if (list.size() <= 0) {
17053                        stickies.remove(intent.getAction());
17054                    }
17055                }
17056                if (stickies.size() <= 0) {
17057                    mStickyBroadcasts.remove(userId);
17058                }
17059            }
17060        }
17061    }
17062
17063    void backgroundServicesFinishedLocked(int userId) {
17064        for (BroadcastQueue queue : mBroadcastQueues) {
17065            queue.backgroundServicesFinishedLocked(userId);
17066        }
17067    }
17068
17069    public void finishReceiver(IBinder who, int resultCode, String resultData,
17070            Bundle resultExtras, boolean resultAbort, int flags) {
17071        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17072
17073        // Refuse possible leaked file descriptors
17074        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17075            throw new IllegalArgumentException("File descriptors passed in Bundle");
17076        }
17077
17078        final long origId = Binder.clearCallingIdentity();
17079        try {
17080            boolean doNext = false;
17081            BroadcastRecord r;
17082
17083            synchronized(this) {
17084                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17085                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17086                r = queue.getMatchingOrderedReceiver(who);
17087                if (r != null) {
17088                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17089                        resultData, resultExtras, resultAbort, true);
17090                }
17091            }
17092
17093            if (doNext) {
17094                r.queue.processNextBroadcast(false);
17095            }
17096            trimApplications();
17097        } finally {
17098            Binder.restoreCallingIdentity(origId);
17099        }
17100    }
17101
17102    // =========================================================
17103    // INSTRUMENTATION
17104    // =========================================================
17105
17106    public boolean startInstrumentation(ComponentName className,
17107            String profileFile, int flags, Bundle arguments,
17108            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17109            int userId, String abiOverride) {
17110        enforceNotIsolatedCaller("startInstrumentation");
17111        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17112                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17113        // Refuse possible leaked file descriptors
17114        if (arguments != null && arguments.hasFileDescriptors()) {
17115            throw new IllegalArgumentException("File descriptors passed in Bundle");
17116        }
17117
17118        synchronized(this) {
17119            InstrumentationInfo ii = null;
17120            ApplicationInfo ai = null;
17121            try {
17122                ii = mContext.getPackageManager().getInstrumentationInfo(
17123                    className, STOCK_PM_FLAGS);
17124                ai = AppGlobals.getPackageManager().getApplicationInfo(
17125                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17126            } catch (PackageManager.NameNotFoundException e) {
17127            } catch (RemoteException e) {
17128            }
17129            if (ii == null) {
17130                reportStartInstrumentationFailure(watcher, className,
17131                        "Unable to find instrumentation info for: " + className);
17132                return false;
17133            }
17134            if (ai == null) {
17135                reportStartInstrumentationFailure(watcher, className,
17136                        "Unable to find instrumentation target package: " + ii.targetPackage);
17137                return false;
17138            }
17139
17140            int match = mContext.getPackageManager().checkSignatures(
17141                    ii.targetPackage, ii.packageName);
17142            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17143                String msg = "Permission Denial: starting instrumentation "
17144                        + className + " from pid="
17145                        + Binder.getCallingPid()
17146                        + ", uid=" + Binder.getCallingPid()
17147                        + " not allowed because package " + ii.packageName
17148                        + " does not have a signature matching the target "
17149                        + ii.targetPackage;
17150                reportStartInstrumentationFailure(watcher, className, msg);
17151                throw new SecurityException(msg);
17152            }
17153
17154            final long origId = Binder.clearCallingIdentity();
17155            // Instrumentation can kill and relaunch even persistent processes
17156            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17157                    "start instr");
17158            ProcessRecord app = addAppLocked(ai, false, abiOverride);
17159            app.instrumentationClass = className;
17160            app.instrumentationInfo = ai;
17161            app.instrumentationProfileFile = profileFile;
17162            app.instrumentationArguments = arguments;
17163            app.instrumentationWatcher = watcher;
17164            app.instrumentationUiAutomationConnection = uiAutomationConnection;
17165            app.instrumentationResultClass = className;
17166            Binder.restoreCallingIdentity(origId);
17167        }
17168
17169        return true;
17170    }
17171
17172    /**
17173     * Report errors that occur while attempting to start Instrumentation.  Always writes the
17174     * error to the logs, but if somebody is watching, send the report there too.  This enables
17175     * the "am" command to report errors with more information.
17176     *
17177     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17178     * @param cn The component name of the instrumentation.
17179     * @param report The error report.
17180     */
17181    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
17182            ComponentName cn, String report) {
17183        Slog.w(TAG, report);
17184        try {
17185            if (watcher != null) {
17186                Bundle results = new Bundle();
17187                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17188                results.putString("Error", report);
17189                watcher.instrumentationStatus(cn, -1, results);
17190            }
17191        } catch (RemoteException e) {
17192            Slog.w(TAG, e);
17193        }
17194    }
17195
17196    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17197        if (app.instrumentationWatcher != null) {
17198            try {
17199                // NOTE:  IInstrumentationWatcher *must* be oneway here
17200                app.instrumentationWatcher.instrumentationFinished(
17201                    app.instrumentationClass,
17202                    resultCode,
17203                    results);
17204            } catch (RemoteException e) {
17205            }
17206        }
17207
17208        // Can't call out of the system process with a lock held, so post a message.
17209        if (app.instrumentationUiAutomationConnection != null) {
17210            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17211                    app.instrumentationUiAutomationConnection).sendToTarget();
17212        }
17213
17214        app.instrumentationWatcher = null;
17215        app.instrumentationUiAutomationConnection = null;
17216        app.instrumentationClass = null;
17217        app.instrumentationInfo = null;
17218        app.instrumentationProfileFile = null;
17219        app.instrumentationArguments = null;
17220
17221        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17222                "finished inst");
17223    }
17224
17225    public void finishInstrumentation(IApplicationThread target,
17226            int resultCode, Bundle results) {
17227        int userId = UserHandle.getCallingUserId();
17228        // Refuse possible leaked file descriptors
17229        if (results != null && results.hasFileDescriptors()) {
17230            throw new IllegalArgumentException("File descriptors passed in Intent");
17231        }
17232
17233        synchronized(this) {
17234            ProcessRecord app = getRecordForAppLocked(target);
17235            if (app == null) {
17236                Slog.w(TAG, "finishInstrumentation: no app for " + target);
17237                return;
17238            }
17239            final long origId = Binder.clearCallingIdentity();
17240            finishInstrumentationLocked(app, resultCode, results);
17241            Binder.restoreCallingIdentity(origId);
17242        }
17243    }
17244
17245    // =========================================================
17246    // CONFIGURATION
17247    // =========================================================
17248
17249    public ConfigurationInfo getDeviceConfigurationInfo() {
17250        ConfigurationInfo config = new ConfigurationInfo();
17251        synchronized (this) {
17252            config.reqTouchScreen = mConfiguration.touchscreen;
17253            config.reqKeyboardType = mConfiguration.keyboard;
17254            config.reqNavigation = mConfiguration.navigation;
17255            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17256                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17257                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17258            }
17259            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17260                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17261                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17262            }
17263            config.reqGlEsVersion = GL_ES_VERSION;
17264        }
17265        return config;
17266    }
17267
17268    ActivityStack getFocusedStack() {
17269        return mStackSupervisor.getFocusedStack();
17270    }
17271
17272    @Override
17273    public int getFocusedStackId() throws RemoteException {
17274        ActivityStack focusedStack = getFocusedStack();
17275        if (focusedStack != null) {
17276            return focusedStack.getStackId();
17277        }
17278        return -1;
17279    }
17280
17281    public Configuration getConfiguration() {
17282        Configuration ci;
17283        synchronized(this) {
17284            ci = new Configuration(mConfiguration);
17285            ci.userSetLocale = false;
17286        }
17287        return ci;
17288    }
17289
17290    public void updatePersistentConfiguration(Configuration values) {
17291        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17292                "updateConfiguration()");
17293        enforceWriteSettingsPermission("updateConfiguration()");
17294        if (values == null) {
17295            throw new NullPointerException("Configuration must not be null");
17296        }
17297
17298        synchronized(this) {
17299            final long origId = Binder.clearCallingIdentity();
17300            updateConfigurationLocked(values, null, true, false);
17301            Binder.restoreCallingIdentity(origId);
17302        }
17303    }
17304
17305    private void enforceWriteSettingsPermission(String func) {
17306        int uid = Binder.getCallingUid();
17307        if (uid == Process.ROOT_UID) {
17308            return;
17309        }
17310
17311        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
17312                Settings.getPackageNameForUid(mContext, uid), false)) {
17313            return;
17314        }
17315
17316        String msg = "Permission Denial: " + func + " from pid="
17317                + Binder.getCallingPid()
17318                + ", uid=" + uid
17319                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
17320        Slog.w(TAG, msg);
17321        throw new SecurityException(msg);
17322    }
17323
17324    public void updateConfiguration(Configuration values) {
17325        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17326                "updateConfiguration()");
17327
17328        synchronized(this) {
17329            if (values == null && mWindowManager != null) {
17330                // sentinel: fetch the current configuration from the window manager
17331                values = mWindowManager.computeNewConfiguration();
17332            }
17333
17334            if (mWindowManager != null) {
17335                mProcessList.applyDisplaySize(mWindowManager);
17336            }
17337
17338            final long origId = Binder.clearCallingIdentity();
17339            if (values != null) {
17340                Settings.System.clearConfiguration(values);
17341            }
17342            updateConfigurationLocked(values, null, false, false);
17343            Binder.restoreCallingIdentity(origId);
17344        }
17345    }
17346
17347    /**
17348     * Do either or both things: (1) change the current configuration, and (2)
17349     * make sure the given activity is running with the (now) current
17350     * configuration.  Returns true if the activity has been left running, or
17351     * false if <var>starting</var> is being destroyed to match the new
17352     * configuration.
17353     * @param persistent TODO
17354     */
17355    boolean updateConfigurationLocked(Configuration values,
17356            ActivityRecord starting, boolean persistent, boolean initLocale) {
17357        int changes = 0;
17358
17359        if (values != null) {
17360            Configuration newConfig = new Configuration(mConfiguration);
17361            changes = newConfig.updateFrom(values);
17362            if (changes != 0) {
17363                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
17364                        "Updating configuration to: " + values);
17365
17366                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
17367
17368                if (!initLocale && values.locale != null && values.userSetLocale) {
17369                    final String languageTag = values.locale.toLanguageTag();
17370                    SystemProperties.set("persist.sys.locale", languageTag);
17371                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
17372                            values.locale));
17373                }
17374
17375                mConfigurationSeq++;
17376                if (mConfigurationSeq <= 0) {
17377                    mConfigurationSeq = 1;
17378                }
17379                newConfig.seq = mConfigurationSeq;
17380                mConfiguration = newConfig;
17381                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
17382                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
17383                //mUsageStatsService.noteStartConfig(newConfig);
17384
17385                final Configuration configCopy = new Configuration(mConfiguration);
17386
17387                // TODO: If our config changes, should we auto dismiss any currently
17388                // showing dialogs?
17389                mShowDialogs = shouldShowDialogs(newConfig);
17390
17391                AttributeCache ac = AttributeCache.instance();
17392                if (ac != null) {
17393                    ac.updateConfiguration(configCopy);
17394                }
17395
17396                // Make sure all resources in our process are updated
17397                // right now, so that anyone who is going to retrieve
17398                // resource values after we return will be sure to get
17399                // the new ones.  This is especially important during
17400                // boot, where the first config change needs to guarantee
17401                // all resources have that config before following boot
17402                // code is executed.
17403                mSystemThread.applyConfigurationToResources(configCopy);
17404
17405                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
17406                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
17407                    msg.obj = new Configuration(configCopy);
17408                    mHandler.sendMessage(msg);
17409                }
17410
17411                for (int i=mLruProcesses.size()-1; i>=0; i--) {
17412                    ProcessRecord app = mLruProcesses.get(i);
17413                    try {
17414                        if (app.thread != null) {
17415                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
17416                                    + app.processName + " new config " + mConfiguration);
17417                            app.thread.scheduleConfigurationChanged(configCopy);
17418                        }
17419                    } catch (Exception e) {
17420                    }
17421                }
17422                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
17423                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17424                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
17425                        | Intent.FLAG_RECEIVER_FOREGROUND);
17426                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
17427                        null, AppOpsManager.OP_NONE, null, false, false,
17428                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17429                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
17430                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
17431                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17432                    if (!mProcessesReady) {
17433                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17434                    }
17435                    broadcastIntentLocked(null, null, intent,
17436                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17437                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17438                }
17439            }
17440        }
17441
17442        boolean kept = true;
17443        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
17444        // mainStack is null during startup.
17445        if (mainStack != null) {
17446            if (changes != 0 && starting == null) {
17447                // If the configuration changed, and the caller is not already
17448                // in the process of starting an activity, then find the top
17449                // activity to check if its configuration needs to change.
17450                starting = mainStack.topRunningActivityLocked(null);
17451            }
17452
17453            if (starting != null) {
17454                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
17455                // And we need to make sure at this point that all other activities
17456                // are made visible with the correct configuration.
17457                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
17458            }
17459        }
17460
17461        if (values != null && mWindowManager != null) {
17462            mWindowManager.setNewConfiguration(mConfiguration);
17463        }
17464
17465        return kept;
17466    }
17467
17468    /**
17469     * Decide based on the configuration whether we should shouw the ANR,
17470     * crash, etc dialogs.  The idea is that if there is no affordnace to
17471     * press the on-screen buttons, we shouldn't show the dialog.
17472     *
17473     * A thought: SystemUI might also want to get told about this, the Power
17474     * dialog / global actions also might want different behaviors.
17475     */
17476    private static final boolean shouldShowDialogs(Configuration config) {
17477        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
17478                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
17479                && config.navigation == Configuration.NAVIGATION_NONAV);
17480    }
17481
17482    @Override
17483    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
17484        synchronized (this) {
17485            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
17486            if (srec != null) {
17487                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
17488            }
17489        }
17490        return false;
17491    }
17492
17493    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
17494            Intent resultData) {
17495
17496        synchronized (this) {
17497            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
17498            if (r != null) {
17499                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
17500            }
17501            return false;
17502        }
17503    }
17504
17505    public int getLaunchedFromUid(IBinder activityToken) {
17506        ActivityRecord srec;
17507        synchronized (this) {
17508            srec = ActivityRecord.forTokenLocked(activityToken);
17509        }
17510        if (srec == null) {
17511            return -1;
17512        }
17513        return srec.launchedFromUid;
17514    }
17515
17516    public String getLaunchedFromPackage(IBinder activityToken) {
17517        ActivityRecord srec;
17518        synchronized (this) {
17519            srec = ActivityRecord.forTokenLocked(activityToken);
17520        }
17521        if (srec == null) {
17522            return null;
17523        }
17524        return srec.launchedFromPackage;
17525    }
17526
17527    // =========================================================
17528    // LIFETIME MANAGEMENT
17529    // =========================================================
17530
17531    // Returns which broadcast queue the app is the current [or imminent] receiver
17532    // on, or 'null' if the app is not an active broadcast recipient.
17533    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
17534        BroadcastRecord r = app.curReceiver;
17535        if (r != null) {
17536            return r.queue;
17537        }
17538
17539        // It's not the current receiver, but it might be starting up to become one
17540        synchronized (this) {
17541            for (BroadcastQueue queue : mBroadcastQueues) {
17542                r = queue.mPendingBroadcast;
17543                if (r != null && r.curApp == app) {
17544                    // found it; report which queue it's in
17545                    return queue;
17546                }
17547            }
17548        }
17549
17550        return null;
17551    }
17552
17553    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17554            ComponentName targetComponent, String targetProcess) {
17555        if (!mTrackingAssociations) {
17556            return null;
17557        }
17558        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17559                = mAssociations.get(targetUid);
17560        if (components == null) {
17561            components = new ArrayMap<>();
17562            mAssociations.put(targetUid, components);
17563        }
17564        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17565        if (sourceUids == null) {
17566            sourceUids = new SparseArray<>();
17567            components.put(targetComponent, sourceUids);
17568        }
17569        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17570        if (sourceProcesses == null) {
17571            sourceProcesses = new ArrayMap<>();
17572            sourceUids.put(sourceUid, sourceProcesses);
17573        }
17574        Association ass = sourceProcesses.get(sourceProcess);
17575        if (ass == null) {
17576            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
17577                    targetProcess);
17578            sourceProcesses.put(sourceProcess, ass);
17579        }
17580        ass.mCount++;
17581        ass.mNesting++;
17582        if (ass.mNesting == 1) {
17583            ass.mStartTime = SystemClock.uptimeMillis();
17584        }
17585        return ass;
17586    }
17587
17588    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17589            ComponentName targetComponent) {
17590        if (!mTrackingAssociations) {
17591            return;
17592        }
17593        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17594                = mAssociations.get(targetUid);
17595        if (components == null) {
17596            return;
17597        }
17598        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17599        if (sourceUids == null) {
17600            return;
17601        }
17602        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17603        if (sourceProcesses == null) {
17604            return;
17605        }
17606        Association ass = sourceProcesses.get(sourceProcess);
17607        if (ass == null || ass.mNesting <= 0) {
17608            return;
17609        }
17610        ass.mNesting--;
17611        if (ass.mNesting == 0) {
17612            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
17613        }
17614    }
17615
17616    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
17617            boolean doingAll, long now) {
17618        if (mAdjSeq == app.adjSeq) {
17619            // This adjustment has already been computed.
17620            return app.curRawAdj;
17621        }
17622
17623        if (app.thread == null) {
17624            app.adjSeq = mAdjSeq;
17625            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17626            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17627            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
17628        }
17629
17630        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
17631        app.adjSource = null;
17632        app.adjTarget = null;
17633        app.empty = false;
17634        app.cached = false;
17635
17636        final int activitiesSize = app.activities.size();
17637
17638        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17639            // The max adjustment doesn't allow this app to be anything
17640            // below foreground, so it is not worth doing work for it.
17641            app.adjType = "fixed";
17642            app.adjSeq = mAdjSeq;
17643            app.curRawAdj = app.maxAdj;
17644            app.foregroundActivities = false;
17645            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
17646            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
17647            // System processes can do UI, and when they do we want to have
17648            // them trim their memory after the user leaves the UI.  To
17649            // facilitate this, here we need to determine whether or not it
17650            // is currently showing UI.
17651            app.systemNoUi = true;
17652            if (app == TOP_APP) {
17653                app.systemNoUi = false;
17654            } else if (activitiesSize > 0) {
17655                for (int j = 0; j < activitiesSize; j++) {
17656                    final ActivityRecord r = app.activities.get(j);
17657                    if (r.visible) {
17658                        app.systemNoUi = false;
17659                    }
17660                }
17661            }
17662            if (!app.systemNoUi) {
17663                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
17664            }
17665            return (app.curAdj=app.maxAdj);
17666        }
17667
17668        app.systemNoUi = false;
17669
17670        final int PROCESS_STATE_TOP = mTopProcessState;
17671
17672        // Determine the importance of the process, starting with most
17673        // important to least, and assign an appropriate OOM adjustment.
17674        int adj;
17675        int schedGroup;
17676        int procState;
17677        boolean foregroundActivities = false;
17678        BroadcastQueue queue;
17679        if (app == TOP_APP) {
17680            // The last app on the list is the foreground app.
17681            adj = ProcessList.FOREGROUND_APP_ADJ;
17682            schedGroup = Process.THREAD_GROUP_DEFAULT;
17683            app.adjType = "top-activity";
17684            foregroundActivities = true;
17685            procState = PROCESS_STATE_TOP;
17686        } else if (app.instrumentationClass != null) {
17687            // Don't want to kill running instrumentation.
17688            adj = ProcessList.FOREGROUND_APP_ADJ;
17689            schedGroup = Process.THREAD_GROUP_DEFAULT;
17690            app.adjType = "instrumentation";
17691            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17692        } else if ((queue = isReceivingBroadcast(app)) != null) {
17693            // An app that is currently receiving a broadcast also
17694            // counts as being in the foreground for OOM killer purposes.
17695            // It's placed in a sched group based on the nature of the
17696            // broadcast as reflected by which queue it's active in.
17697            adj = ProcessList.FOREGROUND_APP_ADJ;
17698            schedGroup = (queue == mFgBroadcastQueue)
17699                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17700            app.adjType = "broadcast";
17701            procState = ActivityManager.PROCESS_STATE_RECEIVER;
17702        } else if (app.executingServices.size() > 0) {
17703            // An app that is currently executing a service callback also
17704            // counts as being in the foreground.
17705            adj = ProcessList.FOREGROUND_APP_ADJ;
17706            schedGroup = app.execServicesFg ?
17707                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17708            app.adjType = "exec-service";
17709            procState = ActivityManager.PROCESS_STATE_SERVICE;
17710            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
17711        } else {
17712            // As far as we know the process is empty.  We may change our mind later.
17713            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17714            // At this point we don't actually know the adjustment.  Use the cached adj
17715            // value that the caller wants us to.
17716            adj = cachedAdj;
17717            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17718            app.cached = true;
17719            app.empty = true;
17720            app.adjType = "cch-empty";
17721        }
17722
17723        // Examine all activities if not already foreground.
17724        if (!foregroundActivities && activitiesSize > 0) {
17725            for (int j = 0; j < activitiesSize; j++) {
17726                final ActivityRecord r = app.activities.get(j);
17727                if (r.app != app) {
17728                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
17729                            + app + "?!? Using " + r.app + " instead.");
17730                    continue;
17731                }
17732                if (r.visible) {
17733                    // App has a visible activity; only upgrade adjustment.
17734                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17735                        adj = ProcessList.VISIBLE_APP_ADJ;
17736                        app.adjType = "visible";
17737                    }
17738                    if (procState > PROCESS_STATE_TOP) {
17739                        procState = PROCESS_STATE_TOP;
17740                    }
17741                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17742                    app.cached = false;
17743                    app.empty = false;
17744                    foregroundActivities = true;
17745                    break;
17746                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
17747                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17748                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17749                        app.adjType = "pausing";
17750                    }
17751                    if (procState > PROCESS_STATE_TOP) {
17752                        procState = PROCESS_STATE_TOP;
17753                    }
17754                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17755                    app.cached = false;
17756                    app.empty = false;
17757                    foregroundActivities = true;
17758                } else if (r.state == ActivityState.STOPPING) {
17759                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17760                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17761                        app.adjType = "stopping";
17762                    }
17763                    // For the process state, we will at this point consider the
17764                    // process to be cached.  It will be cached either as an activity
17765                    // or empty depending on whether the activity is finishing.  We do
17766                    // this so that we can treat the process as cached for purposes of
17767                    // memory trimming (determing current memory level, trim command to
17768                    // send to process) since there can be an arbitrary number of stopping
17769                    // processes and they should soon all go into the cached state.
17770                    if (!r.finishing) {
17771                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17772                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17773                        }
17774                    }
17775                    app.cached = false;
17776                    app.empty = false;
17777                    foregroundActivities = true;
17778                } else {
17779                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17780                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17781                        app.adjType = "cch-act";
17782                    }
17783                }
17784            }
17785        }
17786
17787        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17788            if (app.foregroundServices) {
17789                // The user is aware of this app, so make it visible.
17790                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17791                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17792                app.cached = false;
17793                app.adjType = "fg-service";
17794                schedGroup = Process.THREAD_GROUP_DEFAULT;
17795            } else if (app.forcingToForeground != null) {
17796                // The user is aware of this app, so make it visible.
17797                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17798                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17799                app.cached = false;
17800                app.adjType = "force-fg";
17801                app.adjSource = app.forcingToForeground;
17802                schedGroup = Process.THREAD_GROUP_DEFAULT;
17803            }
17804        }
17805
17806        if (app == mHeavyWeightProcess) {
17807            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
17808                // We don't want to kill the current heavy-weight process.
17809                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
17810                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17811                app.cached = false;
17812                app.adjType = "heavy";
17813            }
17814            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17815                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
17816            }
17817        }
17818
17819        if (app == mHomeProcess) {
17820            if (adj > ProcessList.HOME_APP_ADJ) {
17821                // This process is hosting what we currently consider to be the
17822                // home app, so we don't want to let it go into the background.
17823                adj = ProcessList.HOME_APP_ADJ;
17824                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17825                app.cached = false;
17826                app.adjType = "home";
17827            }
17828            if (procState > ActivityManager.PROCESS_STATE_HOME) {
17829                procState = ActivityManager.PROCESS_STATE_HOME;
17830            }
17831        }
17832
17833        if (app == mPreviousProcess && app.activities.size() > 0) {
17834            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
17835                // This was the previous process that showed UI to the user.
17836                // We want to try to keep it around more aggressively, to give
17837                // a good experience around switching between two apps.
17838                adj = ProcessList.PREVIOUS_APP_ADJ;
17839                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17840                app.cached = false;
17841                app.adjType = "previous";
17842            }
17843            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17844                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17845            }
17846        }
17847
17848        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
17849                + " reason=" + app.adjType);
17850
17851        // By default, we use the computed adjustment.  It may be changed if
17852        // there are applications dependent on our services or providers, but
17853        // this gives us a baseline and makes sure we don't get into an
17854        // infinite recursion.
17855        app.adjSeq = mAdjSeq;
17856        app.curRawAdj = adj;
17857        app.hasStartedServices = false;
17858
17859        if (mBackupTarget != null && app == mBackupTarget.app) {
17860            // If possible we want to avoid killing apps while they're being backed up
17861            if (adj > ProcessList.BACKUP_APP_ADJ) {
17862                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
17863                adj = ProcessList.BACKUP_APP_ADJ;
17864                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17865                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17866                }
17867                app.adjType = "backup";
17868                app.cached = false;
17869            }
17870            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
17871                procState = ActivityManager.PROCESS_STATE_BACKUP;
17872            }
17873        }
17874
17875        boolean mayBeTop = false;
17876
17877        for (int is = app.services.size()-1;
17878                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17879                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17880                        || procState > ActivityManager.PROCESS_STATE_TOP);
17881                is--) {
17882            ServiceRecord s = app.services.valueAt(is);
17883            if (s.startRequested) {
17884                app.hasStartedServices = true;
17885                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
17886                    procState = ActivityManager.PROCESS_STATE_SERVICE;
17887                }
17888                if (app.hasShownUi && app != mHomeProcess) {
17889                    // If this process has shown some UI, let it immediately
17890                    // go to the LRU list because it may be pretty heavy with
17891                    // UI stuff.  We'll tag it with a label just to help
17892                    // debug and understand what is going on.
17893                    if (adj > ProcessList.SERVICE_ADJ) {
17894                        app.adjType = "cch-started-ui-services";
17895                    }
17896                } else {
17897                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17898                        // This service has seen some activity within
17899                        // recent memory, so we will keep its process ahead
17900                        // of the background processes.
17901                        if (adj > ProcessList.SERVICE_ADJ) {
17902                            adj = ProcessList.SERVICE_ADJ;
17903                            app.adjType = "started-services";
17904                            app.cached = false;
17905                        }
17906                    }
17907                    // If we have let the service slide into the background
17908                    // state, still have some text describing what it is doing
17909                    // even though the service no longer has an impact.
17910                    if (adj > ProcessList.SERVICE_ADJ) {
17911                        app.adjType = "cch-started-services";
17912                    }
17913                }
17914            }
17915            for (int conni = s.connections.size()-1;
17916                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17917                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17918                            || procState > ActivityManager.PROCESS_STATE_TOP);
17919                    conni--) {
17920                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17921                for (int i = 0;
17922                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17923                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17924                                || procState > ActivityManager.PROCESS_STATE_TOP);
17925                        i++) {
17926                    // XXX should compute this based on the max of
17927                    // all connected clients.
17928                    ConnectionRecord cr = clist.get(i);
17929                    if (cr.binding.client == app) {
17930                        // Binding to ourself is not interesting.
17931                        continue;
17932                    }
17933                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17934                        ProcessRecord client = cr.binding.client;
17935                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
17936                                TOP_APP, doingAll, now);
17937                        int clientProcState = client.curProcState;
17938                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17939                            // If the other app is cached for any reason, for purposes here
17940                            // we are going to consider it empty.  The specific cached state
17941                            // doesn't propagate except under certain conditions.
17942                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17943                        }
17944                        String adjType = null;
17945                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17946                            // Not doing bind OOM management, so treat
17947                            // this guy more like a started service.
17948                            if (app.hasShownUi && app != mHomeProcess) {
17949                                // If this process has shown some UI, let it immediately
17950                                // go to the LRU list because it may be pretty heavy with
17951                                // UI stuff.  We'll tag it with a label just to help
17952                                // debug and understand what is going on.
17953                                if (adj > clientAdj) {
17954                                    adjType = "cch-bound-ui-services";
17955                                }
17956                                app.cached = false;
17957                                clientAdj = adj;
17958                                clientProcState = procState;
17959                            } else {
17960                                if (now >= (s.lastActivity
17961                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17962                                    // This service has not seen activity within
17963                                    // recent memory, so allow it to drop to the
17964                                    // LRU list if there is no other reason to keep
17965                                    // it around.  We'll also tag it with a label just
17966                                    // to help debug and undertand what is going on.
17967                                    if (adj > clientAdj) {
17968                                        adjType = "cch-bound-services";
17969                                    }
17970                                    clientAdj = adj;
17971                                }
17972                            }
17973                        }
17974                        if (adj > clientAdj) {
17975                            // If this process has recently shown UI, and
17976                            // the process that is binding to it is less
17977                            // important than being visible, then we don't
17978                            // care about the binding as much as we care
17979                            // about letting this process get into the LRU
17980                            // list to be killed and restarted if needed for
17981                            // memory.
17982                            if (app.hasShownUi && app != mHomeProcess
17983                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17984                                adjType = "cch-bound-ui-services";
17985                            } else {
17986                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17987                                        |Context.BIND_IMPORTANT)) != 0) {
17988                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17989                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17990                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17991                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17992                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17993                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17994                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17995                                    adj = clientAdj;
17996                                } else {
17997                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17998                                        adj = ProcessList.VISIBLE_APP_ADJ;
17999                                    }
18000                                }
18001                                if (!client.cached) {
18002                                    app.cached = false;
18003                                }
18004                                adjType = "service";
18005                            }
18006                        }
18007                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18008                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18009                                schedGroup = Process.THREAD_GROUP_DEFAULT;
18010                            }
18011                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18012                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18013                                    // Special handling of clients who are in the top state.
18014                                    // We *may* want to consider this process to be in the
18015                                    // top state as well, but only if there is not another
18016                                    // reason for it to be running.  Being on the top is a
18017                                    // special state, meaning you are specifically running
18018                                    // for the current top app.  If the process is already
18019                                    // running in the background for some other reason, it
18020                                    // is more important to continue considering it to be
18021                                    // in the background state.
18022                                    mayBeTop = true;
18023                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18024                                } else {
18025                                    // Special handling for above-top states (persistent
18026                                    // processes).  These should not bring the current process
18027                                    // into the top state, since they are not on top.  Instead
18028                                    // give them the best state after that.
18029                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18030                                        clientProcState =
18031                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18032                                    } else if (mWakefulness
18033                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18034                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18035                                                    != 0) {
18036                                        clientProcState =
18037                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18038                                    } else {
18039                                        clientProcState =
18040                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18041                                    }
18042                                }
18043                            }
18044                        } else {
18045                            if (clientProcState <
18046                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18047                                clientProcState =
18048                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18049                            }
18050                        }
18051                        if (procState > clientProcState) {
18052                            procState = clientProcState;
18053                        }
18054                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18055                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18056                            app.pendingUiClean = true;
18057                        }
18058                        if (adjType != null) {
18059                            app.adjType = adjType;
18060                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18061                                    .REASON_SERVICE_IN_USE;
18062                            app.adjSource = cr.binding.client;
18063                            app.adjSourceProcState = clientProcState;
18064                            app.adjTarget = s.name;
18065                        }
18066                    }
18067                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18068                        app.treatLikeActivity = true;
18069                    }
18070                    final ActivityRecord a = cr.activity;
18071                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18072                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18073                                (a.visible || a.state == ActivityState.RESUMED
18074                                 || a.state == ActivityState.PAUSING)) {
18075                            adj = ProcessList.FOREGROUND_APP_ADJ;
18076                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18077                                schedGroup = Process.THREAD_GROUP_DEFAULT;
18078                            }
18079                            app.cached = false;
18080                            app.adjType = "service";
18081                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18082                                    .REASON_SERVICE_IN_USE;
18083                            app.adjSource = a;
18084                            app.adjSourceProcState = procState;
18085                            app.adjTarget = s.name;
18086                        }
18087                    }
18088                }
18089            }
18090        }
18091
18092        for (int provi = app.pubProviders.size()-1;
18093                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18094                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18095                        || procState > ActivityManager.PROCESS_STATE_TOP);
18096                provi--) {
18097            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18098            for (int i = cpr.connections.size()-1;
18099                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18100                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18101                            || procState > ActivityManager.PROCESS_STATE_TOP);
18102                    i--) {
18103                ContentProviderConnection conn = cpr.connections.get(i);
18104                ProcessRecord client = conn.client;
18105                if (client == app) {
18106                    // Being our own client is not interesting.
18107                    continue;
18108                }
18109                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18110                int clientProcState = client.curProcState;
18111                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18112                    // If the other app is cached for any reason, for purposes here
18113                    // we are going to consider it empty.
18114                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18115                }
18116                if (adj > clientAdj) {
18117                    if (app.hasShownUi && app != mHomeProcess
18118                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18119                        app.adjType = "cch-ui-provider";
18120                    } else {
18121                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18122                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18123                        app.adjType = "provider";
18124                    }
18125                    app.cached &= client.cached;
18126                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18127                            .REASON_PROVIDER_IN_USE;
18128                    app.adjSource = client;
18129                    app.adjSourceProcState = clientProcState;
18130                    app.adjTarget = cpr.name;
18131                }
18132                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18133                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18134                        // Special handling of clients who are in the top state.
18135                        // We *may* want to consider this process to be in the
18136                        // top state as well, but only if there is not another
18137                        // reason for it to be running.  Being on the top is a
18138                        // special state, meaning you are specifically running
18139                        // for the current top app.  If the process is already
18140                        // running in the background for some other reason, it
18141                        // is more important to continue considering it to be
18142                        // in the background state.
18143                        mayBeTop = true;
18144                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18145                    } else {
18146                        // Special handling for above-top states (persistent
18147                        // processes).  These should not bring the current process
18148                        // into the top state, since they are not on top.  Instead
18149                        // give them the best state after that.
18150                        clientProcState =
18151                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18152                    }
18153                }
18154                if (procState > clientProcState) {
18155                    procState = clientProcState;
18156                }
18157                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18158                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18159                }
18160            }
18161            // If the provider has external (non-framework) process
18162            // dependencies, ensure that its adjustment is at least
18163            // FOREGROUND_APP_ADJ.
18164            if (cpr.hasExternalProcessHandles()) {
18165                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
18166                    adj = ProcessList.FOREGROUND_APP_ADJ;
18167                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18168                    app.cached = false;
18169                    app.adjType = "provider";
18170                    app.adjTarget = cpr.name;
18171                }
18172                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18173                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18174                }
18175            }
18176        }
18177
18178        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
18179            // A client of one of our services or providers is in the top state.  We
18180            // *may* want to be in the top state, but not if we are already running in
18181            // the background for some other reason.  For the decision here, we are going
18182            // to pick out a few specific states that we want to remain in when a client
18183            // is top (states that tend to be longer-term) and otherwise allow it to go
18184            // to the top state.
18185            switch (procState) {
18186                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
18187                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
18188                case ActivityManager.PROCESS_STATE_SERVICE:
18189                    // These all are longer-term states, so pull them up to the top
18190                    // of the background states, but not all the way to the top state.
18191                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18192                    break;
18193                default:
18194                    // Otherwise, top is a better choice, so take it.
18195                    procState = ActivityManager.PROCESS_STATE_TOP;
18196                    break;
18197            }
18198        }
18199
18200        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
18201            if (app.hasClientActivities) {
18202                // This is a cached process, but with client activities.  Mark it so.
18203                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
18204                app.adjType = "cch-client-act";
18205            } else if (app.treatLikeActivity) {
18206                // This is a cached process, but somebody wants us to treat it like it has
18207                // an activity, okay!
18208                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18209                app.adjType = "cch-as-act";
18210            }
18211        }
18212
18213        if (adj == ProcessList.SERVICE_ADJ) {
18214            if (doingAll) {
18215                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
18216                mNewNumServiceProcs++;
18217                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
18218                if (!app.serviceb) {
18219                    // This service isn't far enough down on the LRU list to
18220                    // normally be a B service, but if we are low on RAM and it
18221                    // is large we want to force it down since we would prefer to
18222                    // keep launcher over it.
18223                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
18224                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
18225                        app.serviceHighRam = true;
18226                        app.serviceb = true;
18227                        //Slog.i(TAG, "ADJ " + app + " high ram!");
18228                    } else {
18229                        mNewNumAServiceProcs++;
18230                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
18231                    }
18232                } else {
18233                    app.serviceHighRam = false;
18234                }
18235            }
18236            if (app.serviceb) {
18237                adj = ProcessList.SERVICE_B_ADJ;
18238            }
18239        }
18240
18241        app.curRawAdj = adj;
18242
18243        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
18244        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
18245        if (adj > app.maxAdj) {
18246            adj = app.maxAdj;
18247            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
18248                schedGroup = Process.THREAD_GROUP_DEFAULT;
18249            }
18250        }
18251
18252        // Do final modification to adj.  Everything we do between here and applying
18253        // the final setAdj must be done in this function, because we will also use
18254        // it when computing the final cached adj later.  Note that we don't need to
18255        // worry about this for max adj above, since max adj will always be used to
18256        // keep it out of the cached vaues.
18257        app.curAdj = app.modifyRawOomAdj(adj);
18258        app.curSchedGroup = schedGroup;
18259        app.curProcState = procState;
18260        app.foregroundActivities = foregroundActivities;
18261
18262        return app.curRawAdj;
18263    }
18264
18265    /**
18266     * Record new PSS sample for a process.
18267     */
18268    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long now) {
18269        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024);
18270        proc.lastPssTime = now;
18271        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
18272        if (DEBUG_PSS) Slog.d(TAG_PSS,
18273                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
18274                + " state=" + ProcessList.makeProcStateString(procState));
18275        if (proc.initialIdlePss == 0) {
18276            proc.initialIdlePss = pss;
18277        }
18278        proc.lastPss = pss;
18279        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
18280            proc.lastCachedPss = pss;
18281        }
18282
18283        final SparseArray<Pair<Long, String>> watchUids
18284                = mMemWatchProcesses.getMap().get(proc.processName);
18285        Long check = null;
18286        if (watchUids != null) {
18287            Pair<Long, String> val = watchUids.get(proc.uid);
18288            if (val == null) {
18289                val = watchUids.get(0);
18290            }
18291            if (val != null) {
18292                check = val.first;
18293            }
18294        }
18295        if (check != null) {
18296            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
18297                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18298                if (!isDebuggable) {
18299                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
18300                        isDebuggable = true;
18301                    }
18302                }
18303                if (isDebuggable) {
18304                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
18305                    final ProcessRecord myProc = proc;
18306                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
18307                    mMemWatchDumpProcName = proc.processName;
18308                    mMemWatchDumpFile = heapdumpFile.toString();
18309                    mMemWatchDumpPid = proc.pid;
18310                    mMemWatchDumpUid = proc.uid;
18311                    BackgroundThread.getHandler().post(new Runnable() {
18312                        @Override
18313                        public void run() {
18314                            revokeUriPermission(ActivityThread.currentActivityThread()
18315                                            .getApplicationThread(),
18316                                    DumpHeapActivity.JAVA_URI,
18317                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
18318                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
18319                                    UserHandle.myUserId());
18320                            ParcelFileDescriptor fd = null;
18321                            try {
18322                                heapdumpFile.delete();
18323                                fd = ParcelFileDescriptor.open(heapdumpFile,
18324                                        ParcelFileDescriptor.MODE_CREATE |
18325                                                ParcelFileDescriptor.MODE_TRUNCATE |
18326                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
18327                                                ParcelFileDescriptor.MODE_APPEND);
18328                                IApplicationThread thread = myProc.thread;
18329                                if (thread != null) {
18330                                    try {
18331                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
18332                                                "Requesting dump heap from "
18333                                                + myProc + " to " + heapdumpFile);
18334                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
18335                                    } catch (RemoteException e) {
18336                                    }
18337                                }
18338                            } catch (FileNotFoundException e) {
18339                                e.printStackTrace();
18340                            } finally {
18341                                if (fd != null) {
18342                                    try {
18343                                        fd.close();
18344                                    } catch (IOException e) {
18345                                    }
18346                                }
18347                            }
18348                        }
18349                    });
18350                } else {
18351                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
18352                            + ", but debugging not enabled");
18353                }
18354            }
18355        }
18356    }
18357
18358    /**
18359     * Schedule PSS collection of a process.
18360     */
18361    void requestPssLocked(ProcessRecord proc, int procState) {
18362        if (mPendingPssProcesses.contains(proc)) {
18363            return;
18364        }
18365        if (mPendingPssProcesses.size() == 0) {
18366            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18367        }
18368        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
18369        proc.pssProcState = procState;
18370        mPendingPssProcesses.add(proc);
18371    }
18372
18373    /**
18374     * Schedule PSS collection of all processes.
18375     */
18376    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
18377        if (!always) {
18378            if (now < (mLastFullPssTime +
18379                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
18380                return;
18381            }
18382        }
18383        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
18384        mLastFullPssTime = now;
18385        mFullPssPending = true;
18386        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
18387        mPendingPssProcesses.clear();
18388        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18389            ProcessRecord app = mLruProcesses.get(i);
18390            if (app.thread == null
18391                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
18392                continue;
18393            }
18394            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
18395                app.pssProcState = app.setProcState;
18396                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18397                        mTestPssMode, isSleeping(), now);
18398                mPendingPssProcesses.add(app);
18399            }
18400        }
18401        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18402    }
18403
18404    public void setTestPssMode(boolean enabled) {
18405        synchronized (this) {
18406            mTestPssMode = enabled;
18407            if (enabled) {
18408                // Whenever we enable the mode, we want to take a snapshot all of current
18409                // process mem use.
18410                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
18411            }
18412        }
18413    }
18414
18415    /**
18416     * Ask a given process to GC right now.
18417     */
18418    final void performAppGcLocked(ProcessRecord app) {
18419        try {
18420            app.lastRequestedGc = SystemClock.uptimeMillis();
18421            if (app.thread != null) {
18422                if (app.reportLowMemory) {
18423                    app.reportLowMemory = false;
18424                    app.thread.scheduleLowMemory();
18425                } else {
18426                    app.thread.processInBackground();
18427                }
18428            }
18429        } catch (Exception e) {
18430            // whatever.
18431        }
18432    }
18433
18434    /**
18435     * Returns true if things are idle enough to perform GCs.
18436     */
18437    private final boolean canGcNowLocked() {
18438        boolean processingBroadcasts = false;
18439        for (BroadcastQueue q : mBroadcastQueues) {
18440            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
18441                processingBroadcasts = true;
18442            }
18443        }
18444        return !processingBroadcasts
18445                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
18446    }
18447
18448    /**
18449     * Perform GCs on all processes that are waiting for it, but only
18450     * if things are idle.
18451     */
18452    final void performAppGcsLocked() {
18453        final int N = mProcessesToGc.size();
18454        if (N <= 0) {
18455            return;
18456        }
18457        if (canGcNowLocked()) {
18458            while (mProcessesToGc.size() > 0) {
18459                ProcessRecord proc = mProcessesToGc.remove(0);
18460                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
18461                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
18462                            <= SystemClock.uptimeMillis()) {
18463                        // To avoid spamming the system, we will GC processes one
18464                        // at a time, waiting a few seconds between each.
18465                        performAppGcLocked(proc);
18466                        scheduleAppGcsLocked();
18467                        return;
18468                    } else {
18469                        // It hasn't been long enough since we last GCed this
18470                        // process...  put it in the list to wait for its time.
18471                        addProcessToGcListLocked(proc);
18472                        break;
18473                    }
18474                }
18475            }
18476
18477            scheduleAppGcsLocked();
18478        }
18479    }
18480
18481    /**
18482     * If all looks good, perform GCs on all processes waiting for them.
18483     */
18484    final void performAppGcsIfAppropriateLocked() {
18485        if (canGcNowLocked()) {
18486            performAppGcsLocked();
18487            return;
18488        }
18489        // Still not idle, wait some more.
18490        scheduleAppGcsLocked();
18491    }
18492
18493    /**
18494     * Schedule the execution of all pending app GCs.
18495     */
18496    final void scheduleAppGcsLocked() {
18497        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
18498
18499        if (mProcessesToGc.size() > 0) {
18500            // Schedule a GC for the time to the next process.
18501            ProcessRecord proc = mProcessesToGc.get(0);
18502            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
18503
18504            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
18505            long now = SystemClock.uptimeMillis();
18506            if (when < (now+GC_TIMEOUT)) {
18507                when = now + GC_TIMEOUT;
18508            }
18509            mHandler.sendMessageAtTime(msg, when);
18510        }
18511    }
18512
18513    /**
18514     * Add a process to the array of processes waiting to be GCed.  Keeps the
18515     * list in sorted order by the last GC time.  The process can't already be
18516     * on the list.
18517     */
18518    final void addProcessToGcListLocked(ProcessRecord proc) {
18519        boolean added = false;
18520        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
18521            if (mProcessesToGc.get(i).lastRequestedGc <
18522                    proc.lastRequestedGc) {
18523                added = true;
18524                mProcessesToGc.add(i+1, proc);
18525                break;
18526            }
18527        }
18528        if (!added) {
18529            mProcessesToGc.add(0, proc);
18530        }
18531    }
18532
18533    /**
18534     * Set up to ask a process to GC itself.  This will either do it
18535     * immediately, or put it on the list of processes to gc the next
18536     * time things are idle.
18537     */
18538    final void scheduleAppGcLocked(ProcessRecord app) {
18539        long now = SystemClock.uptimeMillis();
18540        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
18541            return;
18542        }
18543        if (!mProcessesToGc.contains(app)) {
18544            addProcessToGcListLocked(app);
18545            scheduleAppGcsLocked();
18546        }
18547    }
18548
18549    final void checkExcessivePowerUsageLocked(boolean doKills) {
18550        updateCpuStatsNow();
18551
18552        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18553        boolean doWakeKills = doKills;
18554        boolean doCpuKills = doKills;
18555        if (mLastPowerCheckRealtime == 0) {
18556            doWakeKills = false;
18557        }
18558        if (mLastPowerCheckUptime == 0) {
18559            doCpuKills = false;
18560        }
18561        if (stats.isScreenOn()) {
18562            doWakeKills = false;
18563        }
18564        final long curRealtime = SystemClock.elapsedRealtime();
18565        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
18566        final long curUptime = SystemClock.uptimeMillis();
18567        final long uptimeSince = curUptime - mLastPowerCheckUptime;
18568        mLastPowerCheckRealtime = curRealtime;
18569        mLastPowerCheckUptime = curUptime;
18570        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
18571            doWakeKills = false;
18572        }
18573        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
18574            doCpuKills = false;
18575        }
18576        int i = mLruProcesses.size();
18577        while (i > 0) {
18578            i--;
18579            ProcessRecord app = mLruProcesses.get(i);
18580            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18581                long wtime;
18582                synchronized (stats) {
18583                    wtime = stats.getProcessWakeTime(app.info.uid,
18584                            app.pid, curRealtime);
18585                }
18586                long wtimeUsed = wtime - app.lastWakeTime;
18587                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
18588                if (DEBUG_POWER) {
18589                    StringBuilder sb = new StringBuilder(128);
18590                    sb.append("Wake for ");
18591                    app.toShortString(sb);
18592                    sb.append(": over ");
18593                    TimeUtils.formatDuration(realtimeSince, sb);
18594                    sb.append(" used ");
18595                    TimeUtils.formatDuration(wtimeUsed, sb);
18596                    sb.append(" (");
18597                    sb.append((wtimeUsed*100)/realtimeSince);
18598                    sb.append("%)");
18599                    Slog.i(TAG_POWER, sb.toString());
18600                    sb.setLength(0);
18601                    sb.append("CPU for ");
18602                    app.toShortString(sb);
18603                    sb.append(": over ");
18604                    TimeUtils.formatDuration(uptimeSince, sb);
18605                    sb.append(" used ");
18606                    TimeUtils.formatDuration(cputimeUsed, sb);
18607                    sb.append(" (");
18608                    sb.append((cputimeUsed*100)/uptimeSince);
18609                    sb.append("%)");
18610                    Slog.i(TAG_POWER, sb.toString());
18611                }
18612                // If a process has held a wake lock for more
18613                // than 50% of the time during this period,
18614                // that sounds bad.  Kill!
18615                if (doWakeKills && realtimeSince > 0
18616                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
18617                    synchronized (stats) {
18618                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
18619                                realtimeSince, wtimeUsed);
18620                    }
18621                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
18622                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
18623                } else if (doCpuKills && uptimeSince > 0
18624                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
18625                    synchronized (stats) {
18626                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
18627                                uptimeSince, cputimeUsed);
18628                    }
18629                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
18630                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
18631                } else {
18632                    app.lastWakeTime = wtime;
18633                    app.lastCpuTime = app.curCpuTime;
18634                }
18635            }
18636        }
18637    }
18638
18639    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now) {
18640        boolean success = true;
18641
18642        if (app.curRawAdj != app.setRawAdj) {
18643            app.setRawAdj = app.curRawAdj;
18644        }
18645
18646        int changes = 0;
18647
18648        if (app.curAdj != app.setAdj) {
18649            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
18650            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18651                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
18652                    + app.adjType);
18653            app.setAdj = app.curAdj;
18654        }
18655
18656        if (app.setSchedGroup != app.curSchedGroup) {
18657            app.setSchedGroup = app.curSchedGroup;
18658            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18659                    "Setting process group of " + app.processName
18660                    + " to " + app.curSchedGroup);
18661            if (app.waitingToKill != null && app.curReceiver == null
18662                    && app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
18663                app.kill(app.waitingToKill, true);
18664                success = false;
18665            } else {
18666                if (true) {
18667                    long oldId = Binder.clearCallingIdentity();
18668                    try {
18669                        Process.setProcessGroup(app.pid, app.curSchedGroup);
18670                    } catch (Exception e) {
18671                        Slog.w(TAG, "Failed setting process group of " + app.pid
18672                                + " to " + app.curSchedGroup);
18673                        e.printStackTrace();
18674                    } finally {
18675                        Binder.restoreCallingIdentity(oldId);
18676                    }
18677                } else {
18678                    if (app.thread != null) {
18679                        try {
18680                            app.thread.setSchedulingGroup(app.curSchedGroup);
18681                        } catch (RemoteException e) {
18682                        }
18683                    }
18684                }
18685                Process.setSwappiness(app.pid,
18686                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
18687            }
18688        }
18689        if (app.repForegroundActivities != app.foregroundActivities) {
18690            app.repForegroundActivities = app.foregroundActivities;
18691            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
18692        }
18693        if (app.repProcState != app.curProcState) {
18694            app.repProcState = app.curProcState;
18695            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
18696            if (app.thread != null) {
18697                try {
18698                    if (false) {
18699                        //RuntimeException h = new RuntimeException("here");
18700                        Slog.i(TAG, "Sending new process state " + app.repProcState
18701                                + " to " + app /*, h*/);
18702                    }
18703                    app.thread.setProcessState(app.repProcState);
18704                } catch (RemoteException e) {
18705                }
18706            }
18707        }
18708        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
18709                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
18710            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
18711                // Experimental code to more aggressively collect pss while
18712                // running test...  the problem is that this tends to collect
18713                // the data right when a process is transitioning between process
18714                // states, which well tend to give noisy data.
18715                long start = SystemClock.uptimeMillis();
18716                long pss = Debug.getPss(app.pid, mTmpLong, null);
18717                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], now);
18718                mPendingPssProcesses.remove(app);
18719                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
18720                        + " to " + app.curProcState + ": "
18721                        + (SystemClock.uptimeMillis()-start) + "ms");
18722            }
18723            app.lastStateTime = now;
18724            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18725                    mTestPssMode, isSleeping(), now);
18726            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
18727                    + ProcessList.makeProcStateString(app.setProcState) + " to "
18728                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
18729                    + (app.nextPssTime-now) + ": " + app);
18730        } else {
18731            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
18732                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
18733                    mTestPssMode)))) {
18734                requestPssLocked(app, app.setProcState);
18735                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
18736                        mTestPssMode, isSleeping(), now);
18737            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
18738                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
18739        }
18740        if (app.setProcState != app.curProcState) {
18741            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18742                    "Proc state change of " + app.processName
18743                    + " to " + app.curProcState);
18744            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
18745            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
18746            if (setImportant && !curImportant) {
18747                // This app is no longer something we consider important enough to allow to
18748                // use arbitrary amounts of battery power.  Note
18749                // its current wake lock time to later know to kill it if
18750                // it is not behaving well.
18751                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18752                synchronized (stats) {
18753                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
18754                            app.pid, SystemClock.elapsedRealtime());
18755                }
18756                app.lastCpuTime = app.curCpuTime;
18757
18758            }
18759            // Inform UsageStats of important process state change
18760            // Must be called before updating setProcState
18761            maybeUpdateUsageStatsLocked(app);
18762
18763            app.setProcState = app.curProcState;
18764            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18765                app.notCachedSinceIdle = false;
18766            }
18767            if (!doingAll) {
18768                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
18769            } else {
18770                app.procStateChanged = true;
18771            }
18772        }
18773
18774        if (changes != 0) {
18775            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18776                    "Changes in " + app + ": " + changes);
18777            int i = mPendingProcessChanges.size()-1;
18778            ProcessChangeItem item = null;
18779            while (i >= 0) {
18780                item = mPendingProcessChanges.get(i);
18781                if (item.pid == app.pid) {
18782                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18783                            "Re-using existing item: " + item);
18784                    break;
18785                }
18786                i--;
18787            }
18788            if (i < 0) {
18789                // No existing item in pending changes; need a new one.
18790                final int NA = mAvailProcessChanges.size();
18791                if (NA > 0) {
18792                    item = mAvailProcessChanges.remove(NA-1);
18793                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18794                            "Retrieving available item: " + item);
18795                } else {
18796                    item = new ProcessChangeItem();
18797                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18798                            "Allocating new item: " + item);
18799                }
18800                item.changes = 0;
18801                item.pid = app.pid;
18802                item.uid = app.info.uid;
18803                if (mPendingProcessChanges.size() == 0) {
18804                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18805                            "*** Enqueueing dispatch processes changed!");
18806                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
18807                }
18808                mPendingProcessChanges.add(item);
18809            }
18810            item.changes |= changes;
18811            item.processState = app.repProcState;
18812            item.foregroundActivities = app.repForegroundActivities;
18813            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18814                    "Item " + Integer.toHexString(System.identityHashCode(item))
18815                    + " " + app.toShortString() + ": changes=" + item.changes
18816                    + " procState=" + item.processState
18817                    + " foreground=" + item.foregroundActivities
18818                    + " type=" + app.adjType + " source=" + app.adjSource
18819                    + " target=" + app.adjTarget);
18820        }
18821
18822        return success;
18823    }
18824
18825    private final void enqueueUidChangeLocked(UidRecord uidRec, boolean gone) {
18826        if (uidRec.pendingChange == null) {
18827            if (mPendingUidChanges.size() == 0) {
18828                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18829                        "*** Enqueueing dispatch uid changed!");
18830                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_MSG).sendToTarget();
18831            }
18832            final int NA = mAvailUidChanges.size();
18833            if (NA > 0) {
18834                uidRec.pendingChange = mAvailUidChanges.remove(NA-1);
18835                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18836                        "Retrieving available item: " + uidRec.pendingChange);
18837            } else {
18838                uidRec.pendingChange = new UidRecord.ChangeItem();
18839                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18840                        "Allocating new item: " + uidRec.pendingChange);
18841            }
18842            uidRec.pendingChange.uidRecord = uidRec;
18843            uidRec.pendingChange.uid = uidRec.uid;
18844            mPendingUidChanges.add(uidRec.pendingChange);
18845        }
18846        uidRec.pendingChange.gone = gone;
18847        uidRec.pendingChange.processState = uidRec.setProcState;
18848    }
18849
18850    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
18851            String authority) {
18852        if (app == null) return;
18853        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18854            UserState userState = mStartedUsers.get(app.userId);
18855            if (userState == null) return;
18856            final long now = SystemClock.elapsedRealtime();
18857            Long lastReported = userState.mProviderLastReportedFg.get(authority);
18858            if (lastReported == null || lastReported < now - 60 * 1000L) {
18859                mUsageStatsService.reportContentProviderUsage(
18860                        authority, providerPkgName, app.userId);
18861                userState.mProviderLastReportedFg.put(authority, now);
18862            }
18863        }
18864    }
18865
18866    private void maybeUpdateUsageStatsLocked(ProcessRecord app) {
18867        if (DEBUG_USAGE_STATS) {
18868            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
18869                    + "] state changes: old = " + app.setProcState + ", new = "
18870                    + app.curProcState);
18871        }
18872        if (mUsageStatsService == null) {
18873            return;
18874        }
18875        boolean isInteraction;
18876        // To avoid some abuse patterns, we are going to be careful about what we consider
18877        // to be an app interaction.  Being the top activity doesn't count while the display
18878        // is sleeping, nor do short foreground services.
18879        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
18880            isInteraction = true;
18881            app.fgInteractionTime = 0;
18882        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
18883            final long now = SystemClock.elapsedRealtime();
18884            if (app.fgInteractionTime == 0) {
18885                app.fgInteractionTime = now;
18886                isInteraction = false;
18887            } else {
18888                isInteraction = now > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
18889            }
18890        } else {
18891            isInteraction = app.curProcState
18892                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18893            app.fgInteractionTime = 0;
18894        }
18895        if (isInteraction && !app.reportedInteraction) {
18896            String[] packages = app.getPackageList();
18897            if (packages != null) {
18898                for (int i = 0; i < packages.length; i++) {
18899                    mUsageStatsService.reportEvent(packages[i], app.userId,
18900                            UsageEvents.Event.SYSTEM_INTERACTION);
18901                }
18902            }
18903        }
18904        app.reportedInteraction = isInteraction;
18905    }
18906
18907    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
18908        if (proc.thread != null) {
18909            if (proc.baseProcessTracker != null) {
18910                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
18911            }
18912            if (proc.repProcState >= 0) {
18913                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
18914                        proc.repProcState);
18915            }
18916        }
18917    }
18918
18919    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
18920            ProcessRecord TOP_APP, boolean doingAll, long now) {
18921        if (app.thread == null) {
18922            return false;
18923        }
18924
18925        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
18926
18927        return applyOomAdjLocked(app, doingAll, now);
18928    }
18929
18930    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
18931            boolean oomAdj) {
18932        if (isForeground != proc.foregroundServices) {
18933            proc.foregroundServices = isForeground;
18934            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
18935                    proc.info.uid);
18936            if (isForeground) {
18937                if (curProcs == null) {
18938                    curProcs = new ArrayList<ProcessRecord>();
18939                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
18940                }
18941                if (!curProcs.contains(proc)) {
18942                    curProcs.add(proc);
18943                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
18944                            proc.info.packageName, proc.info.uid);
18945                }
18946            } else {
18947                if (curProcs != null) {
18948                    if (curProcs.remove(proc)) {
18949                        mBatteryStatsService.noteEvent(
18950                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
18951                                proc.info.packageName, proc.info.uid);
18952                        if (curProcs.size() <= 0) {
18953                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
18954                        }
18955                    }
18956                }
18957            }
18958            if (oomAdj) {
18959                updateOomAdjLocked();
18960            }
18961        }
18962    }
18963
18964    private final ActivityRecord resumedAppLocked() {
18965        ActivityRecord act = mStackSupervisor.resumedAppLocked();
18966        String pkg;
18967        int uid;
18968        if (act != null) {
18969            pkg = act.packageName;
18970            uid = act.info.applicationInfo.uid;
18971        } else {
18972            pkg = null;
18973            uid = -1;
18974        }
18975        // Has the UID or resumed package name changed?
18976        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
18977                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
18978            if (mCurResumedPackage != null) {
18979                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
18980                        mCurResumedPackage, mCurResumedUid);
18981            }
18982            mCurResumedPackage = pkg;
18983            mCurResumedUid = uid;
18984            if (mCurResumedPackage != null) {
18985                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
18986                        mCurResumedPackage, mCurResumedUid);
18987            }
18988        }
18989        return act;
18990    }
18991
18992    final boolean updateOomAdjLocked(ProcessRecord app) {
18993        final ActivityRecord TOP_ACT = resumedAppLocked();
18994        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18995        final boolean wasCached = app.cached;
18996
18997        mAdjSeq++;
18998
18999        // This is the desired cached adjusment we want to tell it to use.
19000        // If our app is currently cached, we know it, and that is it.  Otherwise,
19001        // we don't know it yet, and it needs to now be cached we will then
19002        // need to do a complete oom adj.
19003        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19004                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19005        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19006                SystemClock.uptimeMillis());
19007        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19008            // Changed to/from cached state, so apps after it in the LRU
19009            // list may also be changed.
19010            updateOomAdjLocked();
19011        }
19012        return success;
19013    }
19014
19015    final void updateOomAdjLocked() {
19016        final ActivityRecord TOP_ACT = resumedAppLocked();
19017        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19018        final long now = SystemClock.uptimeMillis();
19019        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19020        final int N = mLruProcesses.size();
19021
19022        if (false) {
19023            RuntimeException e = new RuntimeException();
19024            e.fillInStackTrace();
19025            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
19026        }
19027
19028        // Reset state in all uid records.
19029        for (int i=mActiveUids.size()-1; i>=0; i--) {
19030            final UidRecord uidRec = mActiveUids.valueAt(i);
19031            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19032                    "Starting update of " + uidRec);
19033            uidRec.reset();
19034        }
19035
19036        mAdjSeq++;
19037        mNewNumServiceProcs = 0;
19038        mNewNumAServiceProcs = 0;
19039
19040        final int emptyProcessLimit;
19041        final int cachedProcessLimit;
19042        if (mProcessLimit <= 0) {
19043            emptyProcessLimit = cachedProcessLimit = 0;
19044        } else if (mProcessLimit == 1) {
19045            emptyProcessLimit = 1;
19046            cachedProcessLimit = 0;
19047        } else {
19048            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
19049            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19050        }
19051
19052        // Let's determine how many processes we have running vs.
19053        // how many slots we have for background processes; we may want
19054        // to put multiple processes in a slot of there are enough of
19055        // them.
19056        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19057                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19058        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19059        if (numEmptyProcs > cachedProcessLimit) {
19060            // If there are more empty processes than our limit on cached
19061            // processes, then use the cached process limit for the factor.
19062            // This ensures that the really old empty processes get pushed
19063            // down to the bottom, so if we are running low on memory we will
19064            // have a better chance at keeping around more cached processes
19065            // instead of a gazillion empty processes.
19066            numEmptyProcs = cachedProcessLimit;
19067        }
19068        int emptyFactor = numEmptyProcs/numSlots;
19069        if (emptyFactor < 1) emptyFactor = 1;
19070        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
19071        if (cachedFactor < 1) cachedFactor = 1;
19072        int stepCached = 0;
19073        int stepEmpty = 0;
19074        int numCached = 0;
19075        int numEmpty = 0;
19076        int numTrimming = 0;
19077
19078        mNumNonCachedProcs = 0;
19079        mNumCachedHiddenProcs = 0;
19080
19081        // First update the OOM adjustment for each of the
19082        // application processes based on their current state.
19083        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19084        int nextCachedAdj = curCachedAdj+1;
19085        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
19086        int nextEmptyAdj = curEmptyAdj+2;
19087        for (int i=N-1; i>=0; i--) {
19088            ProcessRecord app = mLruProcesses.get(i);
19089            if (!app.killedByAm && app.thread != null) {
19090                app.procStateChanged = false;
19091                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19092
19093                // If we haven't yet assigned the final cached adj
19094                // to the process, do that now.
19095                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
19096                    switch (app.curProcState) {
19097                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19098                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19099                            // This process is a cached process holding activities...
19100                            // assign it the next cached value for that type, and then
19101                            // step that cached level.
19102                            app.curRawAdj = curCachedAdj;
19103                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
19104                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
19105                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
19106                                    + ")");
19107                            if (curCachedAdj != nextCachedAdj) {
19108                                stepCached++;
19109                                if (stepCached >= cachedFactor) {
19110                                    stepCached = 0;
19111                                    curCachedAdj = nextCachedAdj;
19112                                    nextCachedAdj += 2;
19113                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19114                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
19115                                    }
19116                                }
19117                            }
19118                            break;
19119                        default:
19120                            // For everything else, assign next empty cached process
19121                            // level and bump that up.  Note that this means that
19122                            // long-running services that have dropped down to the
19123                            // cached level will be treated as empty (since their process
19124                            // state is still as a service), which is what we want.
19125                            app.curRawAdj = curEmptyAdj;
19126                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
19127                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
19128                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
19129                                    + ")");
19130                            if (curEmptyAdj != nextEmptyAdj) {
19131                                stepEmpty++;
19132                                if (stepEmpty >= emptyFactor) {
19133                                    stepEmpty = 0;
19134                                    curEmptyAdj = nextEmptyAdj;
19135                                    nextEmptyAdj += 2;
19136                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19137                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
19138                                    }
19139                                }
19140                            }
19141                            break;
19142                    }
19143                }
19144
19145                applyOomAdjLocked(app, true, now);
19146
19147                // Count the number of process types.
19148                switch (app.curProcState) {
19149                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19150                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19151                        mNumCachedHiddenProcs++;
19152                        numCached++;
19153                        if (numCached > cachedProcessLimit) {
19154                            app.kill("cached #" + numCached, true);
19155                        }
19156                        break;
19157                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
19158                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
19159                                && app.lastActivityTime < oldTime) {
19160                            app.kill("empty for "
19161                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
19162                                    / 1000) + "s", true);
19163                        } else {
19164                            numEmpty++;
19165                            if (numEmpty > emptyProcessLimit) {
19166                                app.kill("empty #" + numEmpty, true);
19167                            }
19168                        }
19169                        break;
19170                    default:
19171                        mNumNonCachedProcs++;
19172                        break;
19173                }
19174
19175                if (app.isolated && app.services.size() <= 0) {
19176                    // If this is an isolated process, and there are no
19177                    // services running in it, then the process is no longer
19178                    // needed.  We agressively kill these because we can by
19179                    // definition not re-use the same process again, and it is
19180                    // good to avoid having whatever code was running in them
19181                    // left sitting around after no longer needed.
19182                    app.kill("isolated not needed", true);
19183                } else {
19184                    // Keeping this process, update its uid.
19185                    final UidRecord uidRec = app.uidRecord;
19186                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
19187                        uidRec.curProcState = app.curProcState;
19188                    }
19189                }
19190
19191                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19192                        && !app.killedByAm) {
19193                    numTrimming++;
19194                }
19195            }
19196        }
19197
19198        mNumServiceProcs = mNewNumServiceProcs;
19199
19200        // Now determine the memory trimming level of background processes.
19201        // Unfortunately we need to start at the back of the list to do this
19202        // properly.  We only do this if the number of background apps we
19203        // are managing to keep around is less than half the maximum we desire;
19204        // if we are keeping a good number around, we'll let them use whatever
19205        // memory they want.
19206        final int numCachedAndEmpty = numCached + numEmpty;
19207        int memFactor;
19208        if (numCached <= ProcessList.TRIM_CACHED_APPS
19209                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
19210            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
19211                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
19212            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
19213                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
19214            } else {
19215                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
19216            }
19217        } else {
19218            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
19219        }
19220        // We always allow the memory level to go up (better).  We only allow it to go
19221        // down if we are in a state where that is allowed, *and* the total number of processes
19222        // has gone down since last time.
19223        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
19224                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
19225                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
19226        if (memFactor > mLastMemoryLevel) {
19227            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
19228                memFactor = mLastMemoryLevel;
19229                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
19230            }
19231        }
19232        mLastMemoryLevel = memFactor;
19233        mLastNumProcesses = mLruProcesses.size();
19234        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
19235        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
19236        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
19237            if (mLowRamStartTime == 0) {
19238                mLowRamStartTime = now;
19239            }
19240            int step = 0;
19241            int fgTrimLevel;
19242            switch (memFactor) {
19243                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
19244                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
19245                    break;
19246                case ProcessStats.ADJ_MEM_FACTOR_LOW:
19247                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
19248                    break;
19249                default:
19250                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
19251                    break;
19252            }
19253            int factor = numTrimming/3;
19254            int minFactor = 2;
19255            if (mHomeProcess != null) minFactor++;
19256            if (mPreviousProcess != null) minFactor++;
19257            if (factor < minFactor) factor = minFactor;
19258            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
19259            for (int i=N-1; i>=0; i--) {
19260                ProcessRecord app = mLruProcesses.get(i);
19261                if (allChanged || app.procStateChanged) {
19262                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
19263                    app.procStateChanged = false;
19264                }
19265                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19266                        && !app.killedByAm) {
19267                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
19268                        try {
19269                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19270                                    "Trimming memory of " + app.processName + " to " + curLevel);
19271                            app.thread.scheduleTrimMemory(curLevel);
19272                        } catch (RemoteException e) {
19273                        }
19274                        if (false) {
19275                            // For now we won't do this; our memory trimming seems
19276                            // to be good enough at this point that destroying
19277                            // activities causes more harm than good.
19278                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
19279                                    && app != mHomeProcess && app != mPreviousProcess) {
19280                                // Need to do this on its own message because the stack may not
19281                                // be in a consistent state at this point.
19282                                // For these apps we will also finish their activities
19283                                // to help them free memory.
19284                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
19285                            }
19286                        }
19287                    }
19288                    app.trimMemoryLevel = curLevel;
19289                    step++;
19290                    if (step >= factor) {
19291                        step = 0;
19292                        switch (curLevel) {
19293                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
19294                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
19295                                break;
19296                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
19297                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19298                                break;
19299                        }
19300                    }
19301                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19302                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
19303                            && app.thread != null) {
19304                        try {
19305                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19306                                    "Trimming memory of heavy-weight " + app.processName
19307                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19308                            app.thread.scheduleTrimMemory(
19309                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19310                        } catch (RemoteException e) {
19311                        }
19312                    }
19313                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19314                } else {
19315                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19316                            || app.systemNoUi) && app.pendingUiClean) {
19317                        // If this application is now in the background and it
19318                        // had done UI, then give it the special trim level to
19319                        // have it free UI resources.
19320                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
19321                        if (app.trimMemoryLevel < level && app.thread != null) {
19322                            try {
19323                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19324                                        "Trimming memory of bg-ui " + app.processName
19325                                        + " to " + level);
19326                                app.thread.scheduleTrimMemory(level);
19327                            } catch (RemoteException e) {
19328                            }
19329                        }
19330                        app.pendingUiClean = false;
19331                    }
19332                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
19333                        try {
19334                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19335                                    "Trimming memory of fg " + app.processName
19336                                    + " to " + fgTrimLevel);
19337                            app.thread.scheduleTrimMemory(fgTrimLevel);
19338                        } catch (RemoteException e) {
19339                        }
19340                    }
19341                    app.trimMemoryLevel = fgTrimLevel;
19342                }
19343            }
19344        } else {
19345            if (mLowRamStartTime != 0) {
19346                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
19347                mLowRamStartTime = 0;
19348            }
19349            for (int i=N-1; i>=0; i--) {
19350                ProcessRecord app = mLruProcesses.get(i);
19351                if (allChanged || app.procStateChanged) {
19352                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
19353                    app.procStateChanged = false;
19354                }
19355                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19356                        || app.systemNoUi) && app.pendingUiClean) {
19357                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
19358                            && app.thread != null) {
19359                        try {
19360                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19361                                    "Trimming memory of ui hidden " + app.processName
19362                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19363                            app.thread.scheduleTrimMemory(
19364                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19365                        } catch (RemoteException e) {
19366                        }
19367                    }
19368                    app.pendingUiClean = false;
19369                }
19370                app.trimMemoryLevel = 0;
19371            }
19372        }
19373
19374        if (mAlwaysFinishActivities) {
19375            // Need to do this on its own message because the stack may not
19376            // be in a consistent state at this point.
19377            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
19378        }
19379
19380        if (allChanged) {
19381            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
19382        }
19383
19384        // Update from any uid changes.
19385        for (int i=mActiveUids.size()-1; i>=0; i--) {
19386            final UidRecord uidRec = mActiveUids.valueAt(i);
19387            if (uidRec.setProcState != uidRec.curProcState) {
19388                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19389                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
19390                        + " to " + uidRec.curProcState);
19391                uidRec.setProcState = uidRec.curProcState;
19392                enqueueUidChangeLocked(uidRec, false);
19393            }
19394        }
19395
19396        if (mProcessStats.shouldWriteNowLocked(now)) {
19397            mHandler.post(new Runnable() {
19398                @Override public void run() {
19399                    synchronized (ActivityManagerService.this) {
19400                        mProcessStats.writeStateAsyncLocked();
19401                    }
19402                }
19403            });
19404        }
19405
19406        if (DEBUG_OOM_ADJ) {
19407            final long duration = SystemClock.uptimeMillis() - now;
19408            if (false) {
19409                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
19410                        new RuntimeException("here").fillInStackTrace());
19411            } else {
19412                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
19413            }
19414        }
19415    }
19416
19417    final void trimApplications() {
19418        synchronized (this) {
19419            int i;
19420
19421            // First remove any unused application processes whose package
19422            // has been removed.
19423            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
19424                final ProcessRecord app = mRemovedProcesses.get(i);
19425                if (app.activities.size() == 0
19426                        && app.curReceiver == null && app.services.size() == 0) {
19427                    Slog.i(
19428                        TAG, "Exiting empty application process "
19429                        + app.processName + " ("
19430                        + (app.thread != null ? app.thread.asBinder() : null)
19431                        + ")\n");
19432                    if (app.pid > 0 && app.pid != MY_PID) {
19433                        app.kill("empty", false);
19434                    } else {
19435                        try {
19436                            app.thread.scheduleExit();
19437                        } catch (Exception e) {
19438                            // Ignore exceptions.
19439                        }
19440                    }
19441                    cleanUpApplicationRecordLocked(app, false, true, -1);
19442                    mRemovedProcesses.remove(i);
19443
19444                    if (app.persistent) {
19445                        addAppLocked(app.info, false, null /* ABI override */);
19446                    }
19447                }
19448            }
19449
19450            // Now update the oom adj for all processes.
19451            updateOomAdjLocked();
19452        }
19453    }
19454
19455    /** This method sends the specified signal to each of the persistent apps */
19456    public void signalPersistentProcesses(int sig) throws RemoteException {
19457        if (sig != Process.SIGNAL_USR1) {
19458            throw new SecurityException("Only SIGNAL_USR1 is allowed");
19459        }
19460
19461        synchronized (this) {
19462            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
19463                    != PackageManager.PERMISSION_GRANTED) {
19464                throw new SecurityException("Requires permission "
19465                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
19466            }
19467
19468            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
19469                ProcessRecord r = mLruProcesses.get(i);
19470                if (r.thread != null && r.persistent) {
19471                    Process.sendSignal(r.pid, sig);
19472                }
19473            }
19474        }
19475    }
19476
19477    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
19478        if (proc == null || proc == mProfileProc) {
19479            proc = mProfileProc;
19480            profileType = mProfileType;
19481            clearProfilerLocked();
19482        }
19483        if (proc == null) {
19484            return;
19485        }
19486        try {
19487            proc.thread.profilerControl(false, null, profileType);
19488        } catch (RemoteException e) {
19489            throw new IllegalStateException("Process disappeared");
19490        }
19491    }
19492
19493    private void clearProfilerLocked() {
19494        if (mProfileFd != null) {
19495            try {
19496                mProfileFd.close();
19497            } catch (IOException e) {
19498            }
19499        }
19500        mProfileApp = null;
19501        mProfileProc = null;
19502        mProfileFile = null;
19503        mProfileType = 0;
19504        mAutoStopProfiler = false;
19505        mSamplingInterval = 0;
19506    }
19507
19508    public boolean profileControl(String process, int userId, boolean start,
19509            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
19510
19511        try {
19512            synchronized (this) {
19513                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19514                // its own permission.
19515                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19516                        != PackageManager.PERMISSION_GRANTED) {
19517                    throw new SecurityException("Requires permission "
19518                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19519                }
19520
19521                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
19522                    throw new IllegalArgumentException("null profile info or fd");
19523                }
19524
19525                ProcessRecord proc = null;
19526                if (process != null) {
19527                    proc = findProcessLocked(process, userId, "profileControl");
19528                }
19529
19530                if (start && (proc == null || proc.thread == null)) {
19531                    throw new IllegalArgumentException("Unknown process: " + process);
19532                }
19533
19534                if (start) {
19535                    stopProfilerLocked(null, 0);
19536                    setProfileApp(proc.info, proc.processName, profilerInfo);
19537                    mProfileProc = proc;
19538                    mProfileType = profileType;
19539                    ParcelFileDescriptor fd = profilerInfo.profileFd;
19540                    try {
19541                        fd = fd.dup();
19542                    } catch (IOException e) {
19543                        fd = null;
19544                    }
19545                    profilerInfo.profileFd = fd;
19546                    proc.thread.profilerControl(start, profilerInfo, profileType);
19547                    fd = null;
19548                    mProfileFd = null;
19549                } else {
19550                    stopProfilerLocked(proc, profileType);
19551                    if (profilerInfo != null && profilerInfo.profileFd != null) {
19552                        try {
19553                            profilerInfo.profileFd.close();
19554                        } catch (IOException e) {
19555                        }
19556                    }
19557                }
19558
19559                return true;
19560            }
19561        } catch (RemoteException e) {
19562            throw new IllegalStateException("Process disappeared");
19563        } finally {
19564            if (profilerInfo != null && profilerInfo.profileFd != null) {
19565                try {
19566                    profilerInfo.profileFd.close();
19567                } catch (IOException e) {
19568                }
19569            }
19570        }
19571    }
19572
19573    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
19574        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19575                userId, true, ALLOW_FULL_ONLY, callName, null);
19576        ProcessRecord proc = null;
19577        try {
19578            int pid = Integer.parseInt(process);
19579            synchronized (mPidsSelfLocked) {
19580                proc = mPidsSelfLocked.get(pid);
19581            }
19582        } catch (NumberFormatException e) {
19583        }
19584
19585        if (proc == null) {
19586            ArrayMap<String, SparseArray<ProcessRecord>> all
19587                    = mProcessNames.getMap();
19588            SparseArray<ProcessRecord> procs = all.get(process);
19589            if (procs != null && procs.size() > 0) {
19590                proc = procs.valueAt(0);
19591                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
19592                    for (int i=1; i<procs.size(); i++) {
19593                        ProcessRecord thisProc = procs.valueAt(i);
19594                        if (thisProc.userId == userId) {
19595                            proc = thisProc;
19596                            break;
19597                        }
19598                    }
19599                }
19600            }
19601        }
19602
19603        return proc;
19604    }
19605
19606    public boolean dumpHeap(String process, int userId, boolean managed,
19607            String path, ParcelFileDescriptor fd) throws RemoteException {
19608
19609        try {
19610            synchronized (this) {
19611                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19612                // its own permission (same as profileControl).
19613                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19614                        != PackageManager.PERMISSION_GRANTED) {
19615                    throw new SecurityException("Requires permission "
19616                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19617                }
19618
19619                if (fd == null) {
19620                    throw new IllegalArgumentException("null fd");
19621                }
19622
19623                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
19624                if (proc == null || proc.thread == null) {
19625                    throw new IllegalArgumentException("Unknown process: " + process);
19626                }
19627
19628                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19629                if (!isDebuggable) {
19630                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19631                        throw new SecurityException("Process not debuggable: " + proc);
19632                    }
19633                }
19634
19635                proc.thread.dumpHeap(managed, path, fd);
19636                fd = null;
19637                return true;
19638            }
19639        } catch (RemoteException e) {
19640            throw new IllegalStateException("Process disappeared");
19641        } finally {
19642            if (fd != null) {
19643                try {
19644                    fd.close();
19645                } catch (IOException e) {
19646                }
19647            }
19648        }
19649    }
19650
19651    @Override
19652    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
19653            String reportPackage) {
19654        if (processName != null) {
19655            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
19656                    "setDumpHeapDebugLimit()");
19657        } else {
19658            synchronized (mPidsSelfLocked) {
19659                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
19660                if (proc == null) {
19661                    throw new SecurityException("No process found for calling pid "
19662                            + Binder.getCallingPid());
19663                }
19664                if (!Build.IS_DEBUGGABLE
19665                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19666                    throw new SecurityException("Not running a debuggable build");
19667                }
19668                processName = proc.processName;
19669                uid = proc.uid;
19670                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
19671                    throw new SecurityException("Package " + reportPackage + " is not running in "
19672                            + proc);
19673                }
19674            }
19675        }
19676        synchronized (this) {
19677            if (maxMemSize > 0) {
19678                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
19679            } else {
19680                if (uid != 0) {
19681                    mMemWatchProcesses.remove(processName, uid);
19682                } else {
19683                    mMemWatchProcesses.getMap().remove(processName);
19684                }
19685            }
19686        }
19687    }
19688
19689    @Override
19690    public void dumpHeapFinished(String path) {
19691        synchronized (this) {
19692            if (Binder.getCallingPid() != mMemWatchDumpPid) {
19693                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
19694                        + " does not match last pid " + mMemWatchDumpPid);
19695                return;
19696            }
19697            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
19698                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
19699                        + " does not match last path " + mMemWatchDumpFile);
19700                return;
19701            }
19702            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
19703            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
19704        }
19705    }
19706
19707    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
19708    public void monitor() {
19709        synchronized (this) { }
19710    }
19711
19712    void onCoreSettingsChange(Bundle settings) {
19713        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19714            ProcessRecord processRecord = mLruProcesses.get(i);
19715            try {
19716                if (processRecord.thread != null) {
19717                    processRecord.thread.setCoreSettings(settings);
19718                }
19719            } catch (RemoteException re) {
19720                /* ignore */
19721            }
19722        }
19723    }
19724
19725    // Multi-user methods
19726
19727    /**
19728     * Start user, if its not already running, but don't bring it to foreground.
19729     */
19730    @Override
19731    public boolean startUserInBackground(final int userId) {
19732        return startUser(userId, /* foreground */ false);
19733    }
19734
19735    /**
19736     * Start user, if its not already running, and bring it to foreground.
19737     */
19738    boolean startUserInForeground(final int userId, Dialog dlg) {
19739        boolean result = startUser(userId, /* foreground */ true);
19740        dlg.dismiss();
19741        return result;
19742    }
19743
19744    /**
19745     * Refreshes the list of users related to the current user when either a
19746     * user switch happens or when a new related user is started in the
19747     * background.
19748     */
19749    private void updateCurrentProfileIdsLocked() {
19750        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19751                mCurrentUserId, false /* enabledOnly */);
19752        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
19753        for (int i = 0; i < currentProfileIds.length; i++) {
19754            currentProfileIds[i] = profiles.get(i).id;
19755        }
19756        mCurrentProfileIds = currentProfileIds;
19757
19758        synchronized (mUserProfileGroupIdsSelfLocked) {
19759            mUserProfileGroupIdsSelfLocked.clear();
19760            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
19761            for (int i = 0; i < users.size(); i++) {
19762                UserInfo user = users.get(i);
19763                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
19764                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
19765                }
19766            }
19767        }
19768    }
19769
19770    private Set<Integer> getProfileIdsLocked(int userId) {
19771        Set<Integer> userIds = new HashSet<Integer>();
19772        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19773                userId, false /* enabledOnly */);
19774        for (UserInfo user : profiles) {
19775            userIds.add(Integer.valueOf(user.id));
19776        }
19777        return userIds;
19778    }
19779
19780    @Override
19781    public boolean switchUser(final int userId) {
19782        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19783        String userName;
19784        synchronized (this) {
19785            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19786            if (userInfo == null) {
19787                Slog.w(TAG, "No user info for user #" + userId);
19788                return false;
19789            }
19790            if (userInfo.isManagedProfile()) {
19791                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19792                return false;
19793            }
19794            userName = userInfo.name;
19795            mTargetUserId = userId;
19796        }
19797        mUiHandler.removeMessages(START_USER_SWITCH_MSG);
19798        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
19799        return true;
19800    }
19801
19802    private void showUserSwitchDialog(int userId, String userName) {
19803        // The dialog will show and then initiate the user switch by calling startUserInForeground
19804        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
19805                true /* above system */);
19806        d.show();
19807    }
19808
19809    private boolean startUser(final int userId, final boolean foreground) {
19810        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19811                != PackageManager.PERMISSION_GRANTED) {
19812            String msg = "Permission Denial: switchUser() from pid="
19813                    + Binder.getCallingPid()
19814                    + ", uid=" + Binder.getCallingUid()
19815                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19816            Slog.w(TAG, msg);
19817            throw new SecurityException(msg);
19818        }
19819
19820        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
19821
19822        final long ident = Binder.clearCallingIdentity();
19823        try {
19824            synchronized (this) {
19825                final int oldUserId = mCurrentUserId;
19826                if (oldUserId == userId) {
19827                    return true;
19828                }
19829
19830                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
19831                        "startUser", false);
19832
19833                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19834                if (userInfo == null) {
19835                    Slog.w(TAG, "No user info for user #" + userId);
19836                    return false;
19837                }
19838                if (foreground && userInfo.isManagedProfile()) {
19839                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19840                    return false;
19841                }
19842
19843                if (foreground) {
19844                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
19845                            R.anim.screen_user_enter);
19846                }
19847
19848                boolean needStart = false;
19849
19850                // If the user we are switching to is not currently started, then
19851                // we need to start it now.
19852                if (mStartedUsers.get(userId) == null) {
19853                    mStartedUsers.put(userId, new UserState(new UserHandle(userId), false));
19854                    updateStartedUserArrayLocked();
19855                    needStart = true;
19856                }
19857
19858                final Integer userIdInt = Integer.valueOf(userId);
19859                mUserLru.remove(userIdInt);
19860                mUserLru.add(userIdInt);
19861
19862                if (foreground) {
19863                    mCurrentUserId = userId;
19864                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
19865                    updateCurrentProfileIdsLocked();
19866                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
19867                    // Once the internal notion of the active user has switched, we lock the device
19868                    // with the option to show the user switcher on the keyguard.
19869                    mWindowManager.lockNow(null);
19870                } else {
19871                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
19872                    updateCurrentProfileIdsLocked();
19873                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
19874                    mUserLru.remove(currentUserIdInt);
19875                    mUserLru.add(currentUserIdInt);
19876                }
19877
19878                final UserState uss = mStartedUsers.get(userId);
19879
19880                // Make sure user is in the started state.  If it is currently
19881                // stopping, we need to knock that off.
19882                if (uss.mState == UserState.STATE_STOPPING) {
19883                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
19884                    // so we can just fairly silently bring the user back from
19885                    // the almost-dead.
19886                    uss.mState = UserState.STATE_RUNNING;
19887                    updateStartedUserArrayLocked();
19888                    needStart = true;
19889                } else if (uss.mState == UserState.STATE_SHUTDOWN) {
19890                    // This means ACTION_SHUTDOWN has been sent, so we will
19891                    // need to treat this as a new boot of the user.
19892                    uss.mState = UserState.STATE_BOOTING;
19893                    updateStartedUserArrayLocked();
19894                    needStart = true;
19895                }
19896
19897                if (uss.mState == UserState.STATE_BOOTING) {
19898                    // Booting up a new user, need to tell system services about it.
19899                    // Note that this is on the same handler as scheduling of broadcasts,
19900                    // which is important because it needs to go first.
19901                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
19902                }
19903
19904                if (foreground) {
19905                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
19906                            oldUserId));
19907                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
19908                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19909                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
19910                            oldUserId, userId, uss));
19911                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
19912                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
19913                }
19914
19915                if (needStart) {
19916                    // Send USER_STARTED broadcast
19917                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
19918                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19919                            | Intent.FLAG_RECEIVER_FOREGROUND);
19920                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19921                    broadcastIntentLocked(null, null, intent,
19922                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19923                            null, false, false, MY_PID, Process.SYSTEM_UID, userId);
19924                }
19925
19926                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
19927                    if (userId != UserHandle.USER_OWNER) {
19928                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
19929                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19930                        broadcastIntentLocked(null, null, intent, null,
19931                                new IIntentReceiver.Stub() {
19932                                    public void performReceive(Intent intent, int resultCode,
19933                                            String data, Bundle extras, boolean ordered,
19934                                            boolean sticky, int sendingUser) {
19935                                        onUserInitialized(uss, foreground, oldUserId, userId);
19936                                    }
19937                                }, 0, null, null, null, AppOpsManager.OP_NONE,
19938                                null, true, false, MY_PID, Process.SYSTEM_UID, userId);
19939                        uss.initializing = true;
19940                    } else {
19941                        getUserManagerLocked().makeInitialized(userInfo.id);
19942                    }
19943                }
19944
19945                if (foreground) {
19946                    if (!uss.initializing) {
19947                        moveUserToForeground(uss, oldUserId, userId);
19948                    }
19949                } else {
19950                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
19951                }
19952
19953                if (needStart) {
19954                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
19955                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19956                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19957                    broadcastIntentLocked(null, null, intent,
19958                            null, new IIntentReceiver.Stub() {
19959                                @Override
19960                                public void performReceive(Intent intent, int resultCode,
19961                                        String data, Bundle extras, boolean ordered, boolean sticky,
19962                                        int sendingUser) throws RemoteException {
19963                                }
19964                            }, 0, null, null,
19965                            new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
19966                            null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19967                }
19968            }
19969        } finally {
19970            Binder.restoreCallingIdentity(ident);
19971        }
19972
19973        return true;
19974    }
19975
19976    void dispatchForegroundProfileChanged(int userId) {
19977        final int N = mUserSwitchObservers.beginBroadcast();
19978        for (int i = 0; i < N; i++) {
19979            try {
19980                mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
19981            } catch (RemoteException e) {
19982                // Ignore
19983            }
19984        }
19985        mUserSwitchObservers.finishBroadcast();
19986    }
19987
19988    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
19989        long ident = Binder.clearCallingIdentity();
19990        try {
19991            Intent intent;
19992            if (oldUserId >= 0) {
19993                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
19994                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
19995                int count = profiles.size();
19996                for (int i = 0; i < count; i++) {
19997                    int profileUserId = profiles.get(i).id;
19998                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
19999                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
20000                            | Intent.FLAG_RECEIVER_FOREGROUND);
20001                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
20002                    broadcastIntentLocked(null, null, intent,
20003                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
20004                            null, false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
20005                }
20006            }
20007            if (newUserId >= 0) {
20008                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
20009                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
20010                int count = profiles.size();
20011                for (int i = 0; i < count; i++) {
20012                    int profileUserId = profiles.get(i).id;
20013                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
20014                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
20015                            | Intent.FLAG_RECEIVER_FOREGROUND);
20016                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
20017                    broadcastIntentLocked(null, null, intent,
20018                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
20019                            null, false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
20020                }
20021                intent = new Intent(Intent.ACTION_USER_SWITCHED);
20022                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
20023                        | Intent.FLAG_RECEIVER_FOREGROUND);
20024                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
20025                broadcastIntentLocked(null, null, intent,
20026                        null, null, 0, null, null,
20027                        new String[] {android.Manifest.permission.MANAGE_USERS},
20028                        AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
20029                        UserHandle.USER_ALL);
20030            }
20031        } finally {
20032            Binder.restoreCallingIdentity(ident);
20033        }
20034    }
20035
20036    void dispatchUserSwitch(final UserState uss, final int oldUserId,
20037            final int newUserId) {
20038        final int N = mUserSwitchObservers.beginBroadcast();
20039        if (N > 0) {
20040            final IRemoteCallback callback = new IRemoteCallback.Stub() {
20041                int mCount = 0;
20042                @Override
20043                public void sendResult(Bundle data) throws RemoteException {
20044                    synchronized (ActivityManagerService.this) {
20045                        if (mCurUserSwitchCallback == this) {
20046                            mCount++;
20047                            if (mCount == N) {
20048                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
20049                            }
20050                        }
20051                    }
20052                }
20053            };
20054            synchronized (this) {
20055                uss.switching = true;
20056                mCurUserSwitchCallback = callback;
20057            }
20058            for (int i=0; i<N; i++) {
20059                try {
20060                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
20061                            newUserId, callback);
20062                } catch (RemoteException e) {
20063                }
20064            }
20065        } else {
20066            synchronized (this) {
20067                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
20068            }
20069        }
20070        mUserSwitchObservers.finishBroadcast();
20071    }
20072
20073    void timeoutUserSwitch(UserState uss, int oldUserId, int newUserId) {
20074        synchronized (this) {
20075            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
20076            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
20077        }
20078    }
20079
20080    void sendContinueUserSwitchLocked(UserState uss, int oldUserId, int newUserId) {
20081        mCurUserSwitchCallback = null;
20082        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
20083        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
20084                oldUserId, newUserId, uss));
20085    }
20086
20087    void onUserInitialized(UserState uss, boolean foreground, int oldUserId, int newUserId) {
20088        synchronized (this) {
20089            if (foreground) {
20090                moveUserToForeground(uss, oldUserId, newUserId);
20091            }
20092        }
20093
20094        completeSwitchAndInitialize(uss, newUserId, true, false);
20095    }
20096
20097    void moveUserToForeground(UserState uss, int oldUserId, int newUserId) {
20098        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
20099        if (homeInFront) {
20100            startHomeActivityLocked(newUserId, "moveUserToFroreground");
20101        } else {
20102            mStackSupervisor.resumeTopActivitiesLocked();
20103        }
20104        EventLogTags.writeAmSwitchUser(newUserId);
20105        getUserManagerLocked().onUserForeground(newUserId);
20106        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
20107    }
20108
20109    void continueUserSwitch(UserState uss, int oldUserId, int newUserId) {
20110        completeSwitchAndInitialize(uss, newUserId, false, true);
20111    }
20112
20113    void completeSwitchAndInitialize(UserState uss, int newUserId,
20114            boolean clearInitializing, boolean clearSwitching) {
20115        boolean unfrozen = false;
20116        synchronized (this) {
20117            if (clearInitializing) {
20118                uss.initializing = false;
20119                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
20120            }
20121            if (clearSwitching) {
20122                uss.switching = false;
20123            }
20124            if (!uss.switching && !uss.initializing) {
20125                mWindowManager.stopFreezingScreen();
20126                unfrozen = true;
20127            }
20128        }
20129        if (unfrozen) {
20130            mHandler.removeMessages(REPORT_USER_SWITCH_COMPLETE_MSG);
20131            mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_COMPLETE_MSG,
20132                    newUserId, 0));
20133        }
20134        stopGuestUserIfBackground();
20135    }
20136
20137    /** Called on handler thread */
20138    void dispatchUserSwitchComplete(int userId) {
20139        final int observerCount = mUserSwitchObservers.beginBroadcast();
20140        for (int i = 0; i < observerCount; i++) {
20141            try {
20142                mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(userId);
20143            } catch (RemoteException e) {
20144            }
20145        }
20146        mUserSwitchObservers.finishBroadcast();
20147    }
20148
20149    /**
20150     * Stops the guest user if it has gone to the background.
20151     */
20152    private void stopGuestUserIfBackground() {
20153        synchronized (this) {
20154            final int num = mUserLru.size();
20155            for (int i = 0; i < num; i++) {
20156                Integer oldUserId = mUserLru.get(i);
20157                UserState oldUss = mStartedUsers.get(oldUserId);
20158                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
20159                        || oldUss.mState == UserState.STATE_STOPPING
20160                        || oldUss.mState == UserState.STATE_SHUTDOWN) {
20161                    continue;
20162                }
20163                UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
20164                if (userInfo.isGuest()) {
20165                    // This is a user to be stopped.
20166                    stopUserLocked(oldUserId, null);
20167                    break;
20168                }
20169            }
20170        }
20171    }
20172
20173    void scheduleStartProfilesLocked() {
20174        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20175            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20176                    DateUtils.SECOND_IN_MILLIS);
20177        }
20178    }
20179
20180    void startProfilesLocked() {
20181        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
20182        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
20183                mCurrentUserId, false /* enabledOnly */);
20184        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
20185        for (UserInfo user : profiles) {
20186            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
20187                    && user.id != mCurrentUserId) {
20188                toStart.add(user);
20189            }
20190        }
20191        final int n = toStart.size();
20192        int i = 0;
20193        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
20194            startUserInBackground(toStart.get(i).id);
20195        }
20196        if (i < n) {
20197            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
20198        }
20199    }
20200
20201    void finishUserBoot(UserState uss) {
20202        synchronized (this) {
20203            if (uss.mState == UserState.STATE_BOOTING
20204                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
20205                uss.mState = UserState.STATE_RUNNING;
20206                final int userId = uss.mHandle.getIdentifier();
20207                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
20208                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20209                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
20210                broadcastIntentLocked(null, null, intent,
20211                        null, null, 0, null, null,
20212                        new String[] {android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
20213                        AppOpsManager.OP_NONE, null, true, false, MY_PID, Process.SYSTEM_UID,
20214                        userId);
20215            }
20216        }
20217    }
20218
20219    void finishUserSwitch(UserState uss) {
20220        synchronized (this) {
20221            finishUserBoot(uss);
20222
20223            startProfilesLocked();
20224
20225            int num = mUserLru.size();
20226            int i = 0;
20227            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
20228                Integer oldUserId = mUserLru.get(i);
20229                UserState oldUss = mStartedUsers.get(oldUserId);
20230                if (oldUss == null) {
20231                    // Shouldn't happen, but be sane if it does.
20232                    mUserLru.remove(i);
20233                    num--;
20234                    continue;
20235                }
20236                if (oldUss.mState == UserState.STATE_STOPPING
20237                        || oldUss.mState == UserState.STATE_SHUTDOWN) {
20238                    // This user is already stopping, doesn't count.
20239                    num--;
20240                    i++;
20241                    continue;
20242                }
20243                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
20244                    // Owner and current can't be stopped, but count as running.
20245                    i++;
20246                    continue;
20247                }
20248                // This is a user to be stopped.
20249                stopUserLocked(oldUserId, null);
20250                num--;
20251                i++;
20252            }
20253        }
20254    }
20255
20256    @Override
20257    public int stopUser(final int userId, final IStopUserCallback callback) {
20258        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20259                != PackageManager.PERMISSION_GRANTED) {
20260            String msg = "Permission Denial: switchUser() from pid="
20261                    + Binder.getCallingPid()
20262                    + ", uid=" + Binder.getCallingUid()
20263                    + " requires " + INTERACT_ACROSS_USERS_FULL;
20264            Slog.w(TAG, msg);
20265            throw new SecurityException(msg);
20266        }
20267        if (userId < 0 || userId == UserHandle.USER_OWNER) {
20268            throw new IllegalArgumentException("Can't stop primary user " + userId);
20269        }
20270        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
20271        synchronized (this) {
20272            return stopUserLocked(userId, callback);
20273        }
20274    }
20275
20276    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
20277        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
20278        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
20279            return ActivityManager.USER_OP_IS_CURRENT;
20280        }
20281
20282        final UserState uss = mStartedUsers.get(userId);
20283        if (uss == null) {
20284            // User is not started, nothing to do...  but we do need to
20285            // callback if requested.
20286            if (callback != null) {
20287                mHandler.post(new Runnable() {
20288                    @Override
20289                    public void run() {
20290                        try {
20291                            callback.userStopped(userId);
20292                        } catch (RemoteException e) {
20293                        }
20294                    }
20295                });
20296            }
20297            return ActivityManager.USER_OP_SUCCESS;
20298        }
20299
20300        if (callback != null) {
20301            uss.mStopCallbacks.add(callback);
20302        }
20303
20304        if (uss.mState != UserState.STATE_STOPPING
20305                && uss.mState != UserState.STATE_SHUTDOWN) {
20306            uss.mState = UserState.STATE_STOPPING;
20307            updateStartedUserArrayLocked();
20308
20309            long ident = Binder.clearCallingIdentity();
20310            try {
20311                // We are going to broadcast ACTION_USER_STOPPING and then
20312                // once that is done send a final ACTION_SHUTDOWN and then
20313                // stop the user.
20314                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
20315                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20316                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20317                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
20318                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
20319                // This is the result receiver for the final shutdown broadcast.
20320                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
20321                    @Override
20322                    public void performReceive(Intent intent, int resultCode, String data,
20323                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
20324                        finishUserStop(uss);
20325                    }
20326                };
20327                // This is the result receiver for the initial stopping broadcast.
20328                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
20329                    @Override
20330                    public void performReceive(Intent intent, int resultCode, String data,
20331                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
20332                        // On to the next.
20333                        synchronized (ActivityManagerService.this) {
20334                            if (uss.mState != UserState.STATE_STOPPING) {
20335                                // Whoops, we are being started back up.  Abort, abort!
20336                                return;
20337                            }
20338                            uss.mState = UserState.STATE_SHUTDOWN;
20339                        }
20340                        mBatteryStatsService.noteEvent(
20341                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
20342                                Integer.toString(userId), userId);
20343                        mSystemServiceManager.stopUser(userId);
20344                        broadcastIntentLocked(null, null, shutdownIntent,
20345                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
20346                                null, true, false, MY_PID, Process.SYSTEM_UID, userId);
20347                    }
20348                };
20349                // Kick things off.
20350                broadcastIntentLocked(null, null, stoppingIntent,
20351                        null, stoppingReceiver, 0, null, null,
20352                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
20353                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
20354            } finally {
20355                Binder.restoreCallingIdentity(ident);
20356            }
20357        }
20358
20359        return ActivityManager.USER_OP_SUCCESS;
20360    }
20361
20362    void finishUserStop(UserState uss) {
20363        final int userId = uss.mHandle.getIdentifier();
20364        boolean stopped;
20365        ArrayList<IStopUserCallback> callbacks;
20366        synchronized (this) {
20367            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
20368            if (mStartedUsers.get(userId) != uss) {
20369                stopped = false;
20370            } else if (uss.mState != UserState.STATE_SHUTDOWN) {
20371                stopped = false;
20372            } else {
20373                stopped = true;
20374                // User can no longer run.
20375                mStartedUsers.remove(userId);
20376                mUserLru.remove(Integer.valueOf(userId));
20377                updateStartedUserArrayLocked();
20378
20379                // Clean up all state and processes associated with the user.
20380                // Kill all the processes for the user.
20381                forceStopUserLocked(userId, "finish user");
20382            }
20383
20384            // Explicitly remove the old information in mRecentTasks.
20385            mRecentTasks.removeTasksForUserLocked(userId);
20386        }
20387
20388        for (int i=0; i<callbacks.size(); i++) {
20389            try {
20390                if (stopped) callbacks.get(i).userStopped(userId);
20391                else callbacks.get(i).userStopAborted(userId);
20392            } catch (RemoteException e) {
20393            }
20394        }
20395
20396        if (stopped) {
20397            mSystemServiceManager.cleanupUser(userId);
20398            synchronized (this) {
20399                mStackSupervisor.removeUserLocked(userId);
20400            }
20401        }
20402    }
20403
20404    @Override
20405    public UserInfo getCurrentUser() {
20406        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
20407                != PackageManager.PERMISSION_GRANTED) && (
20408                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20409                != PackageManager.PERMISSION_GRANTED)) {
20410            String msg = "Permission Denial: getCurrentUser() from pid="
20411                    + Binder.getCallingPid()
20412                    + ", uid=" + Binder.getCallingUid()
20413                    + " requires " + INTERACT_ACROSS_USERS;
20414            Slog.w(TAG, msg);
20415            throw new SecurityException(msg);
20416        }
20417        synchronized (this) {
20418            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20419            return getUserManagerLocked().getUserInfo(userId);
20420        }
20421    }
20422
20423    int getCurrentUserIdLocked() {
20424        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20425    }
20426
20427    @Override
20428    public boolean isUserRunning(int userId, boolean orStopped) {
20429        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20430                != PackageManager.PERMISSION_GRANTED) {
20431            String msg = "Permission Denial: isUserRunning() from pid="
20432                    + Binder.getCallingPid()
20433                    + ", uid=" + Binder.getCallingUid()
20434                    + " requires " + INTERACT_ACROSS_USERS;
20435            Slog.w(TAG, msg);
20436            throw new SecurityException(msg);
20437        }
20438        synchronized (this) {
20439            return isUserRunningLocked(userId, orStopped);
20440        }
20441    }
20442
20443    boolean isUserRunningLocked(int userId, boolean orStopped) {
20444        UserState state = mStartedUsers.get(userId);
20445        if (state == null) {
20446            return false;
20447        }
20448        if (orStopped) {
20449            return true;
20450        }
20451        return state.mState != UserState.STATE_STOPPING
20452                && state.mState != UserState.STATE_SHUTDOWN;
20453    }
20454
20455    @Override
20456    public int[] getRunningUserIds() {
20457        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20458                != PackageManager.PERMISSION_GRANTED) {
20459            String msg = "Permission Denial: isUserRunning() from pid="
20460                    + Binder.getCallingPid()
20461                    + ", uid=" + Binder.getCallingUid()
20462                    + " requires " + INTERACT_ACROSS_USERS;
20463            Slog.w(TAG, msg);
20464            throw new SecurityException(msg);
20465        }
20466        synchronized (this) {
20467            return mStartedUserArray;
20468        }
20469    }
20470
20471    private void updateStartedUserArrayLocked() {
20472        int num = 0;
20473        for (int i=0; i<mStartedUsers.size();  i++) {
20474            UserState uss = mStartedUsers.valueAt(i);
20475            // This list does not include stopping users.
20476            if (uss.mState != UserState.STATE_STOPPING
20477                    && uss.mState != UserState.STATE_SHUTDOWN) {
20478                num++;
20479            }
20480        }
20481        mStartedUserArray = new int[num];
20482        num = 0;
20483        for (int i=0; i<mStartedUsers.size();  i++) {
20484            UserState uss = mStartedUsers.valueAt(i);
20485            if (uss.mState != UserState.STATE_STOPPING
20486                    && uss.mState != UserState.STATE_SHUTDOWN) {
20487                mStartedUserArray[num] = mStartedUsers.keyAt(i);
20488                num++;
20489            }
20490        }
20491    }
20492
20493    @Override
20494    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20495        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20496                != PackageManager.PERMISSION_GRANTED) {
20497            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
20498                    + Binder.getCallingPid()
20499                    + ", uid=" + Binder.getCallingUid()
20500                    + " requires " + INTERACT_ACROSS_USERS_FULL;
20501            Slog.w(TAG, msg);
20502            throw new SecurityException(msg);
20503        }
20504
20505        mUserSwitchObservers.register(observer);
20506    }
20507
20508    @Override
20509    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20510        mUserSwitchObservers.unregister(observer);
20511    }
20512
20513    int[] getUsersLocked() {
20514        UserManagerService ums = getUserManagerLocked();
20515        return ums != null ? ums.getUserIds() : new int[] { 0 };
20516    }
20517
20518    UserManagerService getUserManagerLocked() {
20519        if (mUserManager == null) {
20520            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
20521            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
20522        }
20523        return mUserManager;
20524    }
20525
20526    private int applyUserId(int uid, int userId) {
20527        return UserHandle.getUid(userId, uid);
20528    }
20529
20530    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20531        if (info == null) return null;
20532        ApplicationInfo newInfo = new ApplicationInfo(info);
20533        newInfo.uid = applyUserId(info.uid, userId);
20534        newInfo.dataDir = Environment
20535                .getDataUserPackageDirectory(info.volumeUuid, userId, info.packageName)
20536                .getAbsolutePath();
20537        return newInfo;
20538    }
20539
20540    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20541        if (aInfo == null
20542                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20543            return aInfo;
20544        }
20545
20546        ActivityInfo info = new ActivityInfo(aInfo);
20547        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20548        return info;
20549    }
20550
20551    private final class LocalService extends ActivityManagerInternal {
20552        @Override
20553        public void onWakefulnessChanged(int wakefulness) {
20554            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20555        }
20556
20557        @Override
20558        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20559                String processName, String abiOverride, int uid, Runnable crashHandler) {
20560            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20561                    processName, abiOverride, uid, crashHandler);
20562        }
20563
20564        @Override
20565        public SleepToken acquireSleepToken(String tag) {
20566            Preconditions.checkNotNull(tag);
20567
20568            synchronized (ActivityManagerService.this) {
20569                SleepTokenImpl token = new SleepTokenImpl(tag);
20570                mSleepTokens.add(token);
20571                updateSleepIfNeededLocked();
20572                return token;
20573            }
20574        }
20575
20576        @Override
20577        public ComponentName getHomeActivityForUser(int userId) {
20578            synchronized (ActivityManagerService.this) {
20579                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20580                return homeActivity == null ? null : homeActivity.realActivity;
20581            }
20582        }
20583    }
20584
20585    private final class SleepTokenImpl extends SleepToken {
20586        private final String mTag;
20587        private final long mAcquireTime;
20588
20589        public SleepTokenImpl(String tag) {
20590            mTag = tag;
20591            mAcquireTime = SystemClock.uptimeMillis();
20592        }
20593
20594        @Override
20595        public void release() {
20596            synchronized (ActivityManagerService.this) {
20597                if (mSleepTokens.remove(this)) {
20598                    updateSleepIfNeededLocked();
20599                }
20600            }
20601        }
20602
20603        @Override
20604        public String toString() {
20605            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20606        }
20607    }
20608
20609    /**
20610     * An implementation of IAppTask, that allows an app to manage its own tasks via
20611     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
20612     * only the process that calls getAppTasks() can call the AppTask methods.
20613     */
20614    class AppTaskImpl extends IAppTask.Stub {
20615        private int mTaskId;
20616        private int mCallingUid;
20617
20618        public AppTaskImpl(int taskId, int callingUid) {
20619            mTaskId = taskId;
20620            mCallingUid = callingUid;
20621        }
20622
20623        private void checkCaller() {
20624            if (mCallingUid != Binder.getCallingUid()) {
20625                throw new SecurityException("Caller " + mCallingUid
20626                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
20627            }
20628        }
20629
20630        @Override
20631        public void finishAndRemoveTask() {
20632            checkCaller();
20633
20634            synchronized (ActivityManagerService.this) {
20635                long origId = Binder.clearCallingIdentity();
20636                try {
20637                    if (!removeTaskByIdLocked(mTaskId, false)) {
20638                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20639                    }
20640                } finally {
20641                    Binder.restoreCallingIdentity(origId);
20642                }
20643            }
20644        }
20645
20646        @Override
20647        public ActivityManager.RecentTaskInfo getTaskInfo() {
20648            checkCaller();
20649
20650            synchronized (ActivityManagerService.this) {
20651                long origId = Binder.clearCallingIdentity();
20652                try {
20653                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20654                    if (tr == null) {
20655                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20656                    }
20657                    return createRecentTaskInfoFromTaskRecord(tr);
20658                } finally {
20659                    Binder.restoreCallingIdentity(origId);
20660                }
20661            }
20662        }
20663
20664        @Override
20665        public void moveToFront() {
20666            checkCaller();
20667            // Will bring task to front if it already has a root activity.
20668            startActivityFromRecentsInner(mTaskId, null);
20669        }
20670
20671        @Override
20672        public int startActivity(IBinder whoThread, String callingPackage,
20673                Intent intent, String resolvedType, Bundle options) {
20674            checkCaller();
20675
20676            int callingUser = UserHandle.getCallingUserId();
20677            TaskRecord tr;
20678            IApplicationThread appThread;
20679            synchronized (ActivityManagerService.this) {
20680                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20681                if (tr == null) {
20682                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20683                }
20684                appThread = ApplicationThreadNative.asInterface(whoThread);
20685                if (appThread == null) {
20686                    throw new IllegalArgumentException("Bad app thread " + appThread);
20687                }
20688            }
20689            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
20690                    resolvedType, null, null, null, null, 0, 0, null, null,
20691                    null, options, false, callingUser, null, tr);
20692        }
20693
20694        @Override
20695        public void setExcludeFromRecents(boolean exclude) {
20696            checkCaller();
20697
20698            synchronized (ActivityManagerService.this) {
20699                long origId = Binder.clearCallingIdentity();
20700                try {
20701                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20702                    if (tr == null) {
20703                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20704                    }
20705                    Intent intent = tr.getBaseIntent();
20706                    if (exclude) {
20707                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20708                    } else {
20709                        intent.setFlags(intent.getFlags()
20710                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20711                    }
20712                } finally {
20713                    Binder.restoreCallingIdentity(origId);
20714                }
20715            }
20716        }
20717    }
20718}
20719