ActivityManagerService.java revision c200f44c46b7d6ddb104c0f09f2a4c679e218d0b
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.StorageManager;
66import android.service.voice.IVoiceInteractionSession;
67import android.util.ArrayMap;
68import android.util.ArraySet;
69import android.util.DebugUtils;
70import android.util.SparseIntArray;
71import android.view.Display;
72
73import com.android.internal.R;
74import com.android.internal.annotations.GuardedBy;
75import com.android.internal.app.DumpHeapActivity;
76import com.android.internal.app.IAppOpsService;
77import com.android.internal.app.IVoiceInteractor;
78import com.android.internal.app.ProcessMap;
79import com.android.internal.app.ProcessStats;
80import com.android.internal.os.BackgroundThread;
81import com.android.internal.os.BatteryStatsImpl;
82import com.android.internal.os.IResultReceiver;
83import com.android.internal.os.ProcessCpuTracker;
84import com.android.internal.os.TransferPipe;
85import com.android.internal.os.Zygote;
86import com.android.internal.util.ArrayUtils;
87import com.android.internal.util.FastPrintWriter;
88import com.android.internal.util.FastXmlSerializer;
89import com.android.internal.util.MemInfoReader;
90import com.android.internal.util.Preconditions;
91import com.android.server.AppOpsService;
92import com.android.server.AttributeCache;
93import com.android.server.DeviceIdleController;
94import com.android.server.IntentResolver;
95import com.android.server.LocalServices;
96import com.android.server.ServiceThread;
97import com.android.server.SystemService;
98import com.android.server.SystemServiceManager;
99import com.android.server.Watchdog;
100import com.android.server.am.ActivityStack.ActivityState;
101import com.android.server.firewall.IntentFirewall;
102import com.android.server.pm.Installer;
103import com.android.server.pm.UserManagerService;
104import com.android.server.statusbar.StatusBarManagerInternal;
105import com.android.server.wm.AppTransition;
106import com.android.server.wm.WindowManagerService;
107import com.google.android.collect.Lists;
108import com.google.android.collect.Maps;
109
110import libcore.io.IoUtils;
111import libcore.util.EmptyArray;
112
113import org.xmlpull.v1.XmlPullParser;
114import org.xmlpull.v1.XmlPullParserException;
115import org.xmlpull.v1.XmlSerializer;
116
117import android.app.Activity;
118import android.app.ActivityManager;
119import android.app.ActivityManager.RunningTaskInfo;
120import android.app.ActivityManager.StackInfo;
121import android.app.ActivityManagerInternal;
122import android.app.ActivityManagerInternal.SleepToken;
123import android.app.ActivityManagerNative;
124import android.app.ActivityOptions;
125import android.app.ActivityThread;
126import android.app.AlertDialog;
127import android.app.AppGlobals;
128import android.app.ApplicationErrorReport;
129import android.app.Dialog;
130import android.app.IActivityController;
131import android.app.IApplicationThread;
132import android.app.IInstrumentationWatcher;
133import android.app.INotificationManager;
134import android.app.IProcessObserver;
135import android.app.IServiceConnection;
136import android.app.IStopUserCallback;
137import android.app.IUidObserver;
138import android.app.IUiAutomationConnection;
139import android.app.IUserSwitchObserver;
140import android.app.Instrumentation;
141import android.app.Notification;
142import android.app.NotificationManager;
143import android.app.PendingIntent;
144import android.app.backup.IBackupManager;
145import android.app.admin.DevicePolicyManager;
146import android.content.ActivityNotFoundException;
147import android.content.BroadcastReceiver;
148import android.content.ClipData;
149import android.content.ComponentCallbacks2;
150import android.content.ComponentName;
151import android.content.ContentProvider;
152import android.content.ContentResolver;
153import android.content.Context;
154import android.content.DialogInterface;
155import android.content.IContentProvider;
156import android.content.IIntentReceiver;
157import android.content.IIntentSender;
158import android.content.Intent;
159import android.content.IntentFilter;
160import android.content.IntentSender;
161import android.content.pm.ActivityInfo;
162import android.content.pm.ApplicationInfo;
163import android.content.pm.ConfigurationInfo;
164import android.content.pm.IPackageDataObserver;
165import android.content.pm.IPackageManager;
166import android.content.pm.InstrumentationInfo;
167import android.content.pm.PackageInfo;
168import android.content.pm.PackageManager;
169import android.content.pm.ParceledListSlice;
170import android.content.pm.UserInfo;
171import android.content.pm.PackageManager.NameNotFoundException;
172import android.content.pm.PathPermission;
173import android.content.pm.ProviderInfo;
174import android.content.pm.ResolveInfo;
175import android.content.pm.ServiceInfo;
176import android.content.res.CompatibilityInfo;
177import android.content.res.Configuration;
178import android.net.Proxy;
179import android.net.ProxyInfo;
180import android.net.Uri;
181import android.os.Binder;
182import android.os.Build;
183import android.os.Bundle;
184import android.os.Debug;
185import android.os.DropBoxManager;
186import android.os.Environment;
187import android.os.FactoryTest;
188import android.os.FileObserver;
189import android.os.FileUtils;
190import android.os.Handler;
191import android.os.IBinder;
192import android.os.IPermissionController;
193import android.os.IProcessInfoService;
194import android.os.IRemoteCallback;
195import android.os.IUserManager;
196import android.os.Looper;
197import android.os.Message;
198import android.os.Parcel;
199import android.os.ParcelFileDescriptor;
200import android.os.PowerManagerInternal;
201import android.os.Process;
202import android.os.RemoteCallbackList;
203import android.os.RemoteException;
204import android.os.SELinux;
205import android.os.ServiceManager;
206import android.os.StrictMode;
207import android.os.SystemClock;
208import android.os.SystemProperties;
209import android.os.UpdateLock;
210import android.os.UserHandle;
211import android.os.UserManager;
212import android.provider.Settings;
213import android.text.format.DateUtils;
214import android.text.format.Time;
215import android.util.AtomicFile;
216import android.util.EventLog;
217import android.util.Log;
218import android.util.Pair;
219import android.util.PrintWriterPrinter;
220import android.util.Slog;
221import android.util.SparseArray;
222import android.util.TimeUtils;
223import android.util.Xml;
224import android.view.Gravity;
225import android.view.LayoutInflater;
226import android.view.View;
227import android.view.WindowManager;
228
229import dalvik.system.VMRuntime;
230
231import java.io.BufferedInputStream;
232import java.io.BufferedOutputStream;
233import java.io.DataInputStream;
234import java.io.DataOutputStream;
235import java.io.File;
236import java.io.FileDescriptor;
237import java.io.FileInputStream;
238import java.io.FileNotFoundException;
239import java.io.FileOutputStream;
240import java.io.IOException;
241import java.io.InputStreamReader;
242import java.io.PrintWriter;
243import java.io.StringWriter;
244import java.lang.ref.WeakReference;
245import java.nio.charset.StandardCharsets;
246import java.util.ArrayList;
247import java.util.Arrays;
248import java.util.Collections;
249import java.util.Comparator;
250import java.util.HashMap;
251import java.util.HashSet;
252import java.util.Iterator;
253import java.util.List;
254import java.util.Locale;
255import java.util.Map;
256import java.util.Set;
257import java.util.concurrent.atomic.AtomicBoolean;
258import java.util.concurrent.atomic.AtomicLong;
259
260public final class ActivityManagerService extends ActivityManagerNative
261        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
262
263    // File that stores last updated system version and called preboot receivers
264    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
265
266    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
267    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
268    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
269    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
270    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
271    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
272    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
273    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
274    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
275    private static final String TAG_LRU = TAG + POSTFIX_LRU;
276    private static final String TAG_MU = TAG + POSTFIX_MU;
277    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
278    private static final String TAG_POWER = TAG + POSTFIX_POWER;
279    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
280    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
281    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
282    private static final String TAG_PSS = TAG + POSTFIX_PSS;
283    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
284    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
285    private static final String TAG_STACK = TAG + POSTFIX_STACK;
286    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
287    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
288    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
289    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
290    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
291
292    /** Control over CPU and battery monitoring */
293    // write battery stats every 30 minutes.
294    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
295    static final boolean MONITOR_CPU_USAGE = true;
296    // don't sample cpu less than every 5 seconds.
297    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
298    // wait possibly forever for next cpu sample.
299    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
300    static final boolean MONITOR_THREAD_CPU_USAGE = false;
301
302    // The flags that are set for all calls we make to the package manager.
303    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
304
305    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
306
307    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
308
309    // Amount of time after a call to stopAppSwitches() during which we will
310    // prevent further untrusted switches from happening.
311    static final long APP_SWITCH_DELAY_TIME = 5*1000;
312
313    // How long we wait for a launched process to attach to the activity manager
314    // before we decide it's never going to come up for real.
315    static final int PROC_START_TIMEOUT = 10*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, when the process was
319    // started with a wrapper for instrumentation (such as Valgrind) because it
320    // could take much longer than usual.
321    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
322
323    // How long to wait after going idle before forcing apps to GC.
324    static final int GC_TIMEOUT = 5*1000;
325
326    // The minimum amount of time between successive GC requests for a process.
327    static final int GC_MIN_INTERVAL = 60*1000;
328
329    // The minimum amount of time between successive PSS requests for a process.
330    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
331
332    // The minimum amount of time between successive PSS requests for a process
333    // when the request is due to the memory state being lowered.
334    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
335
336    // The rate at which we check for apps using excessive power -- 15 mins.
337    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
338
339    // The minimum sample duration we will allow before deciding we have
340    // enough data on wake locks to start killing things.
341    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
342
343    // The minimum sample duration we will allow before deciding we have
344    // enough data on CPU usage to start killing things.
345    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
346
347    // How long we allow a receiver to run before giving up on it.
348    static final int BROADCAST_FG_TIMEOUT = 10*1000;
349    static final int BROADCAST_BG_TIMEOUT = 60*1000;
350
351    // How long we wait until we timeout on key dispatching.
352    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
353
354    // How long we wait until we timeout on key dispatching during instrumentation.
355    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
356
357    // Amount of time we wait for observers to handle a user switch before
358    // giving up on them and unfreezing the screen.
359    static final int USER_SWITCH_TIMEOUT = 2*1000;
360
361    // This is the amount of time an app needs to be running a foreground service before
362    // we will consider it to be doing interaction for usage stats.
363    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
364
365    // Maximum number of users we allow to be running at a time.
366    static final int MAX_RUNNING_USERS = 3;
367
368    // How long to wait in getAssistContextExtras for the activity and foreground services
369    // to respond with the result.
370    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
371
372    // How long top wait when going through the modern assist (which doesn't need to block
373    // on getting this result before starting to launch its UI).
374    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
375
376    // Maximum number of persisted Uri grants a package is allowed
377    static final int MAX_PERSISTED_URI_GRANTS = 128;
378
379    static final int MY_PID = Process.myPid();
380
381    static final String[] EMPTY_STRING_ARRAY = new String[0];
382
383    // How many bytes to write into the dropbox log before truncating
384    static final int DROPBOX_MAX_SIZE = 256 * 1024;
385
386    // Access modes for handleIncomingUser.
387    static final int ALLOW_NON_FULL = 0;
388    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
389    static final int ALLOW_FULL_ONLY = 2;
390
391    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
392
393    // Delay in notifying task stack change listeners (in millis)
394    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
395
396    // Necessary ApplicationInfo flags to mark an app as persistent
397    private static final int PERSISTENT_MASK =
398            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
399
400    /** All system services */
401    SystemServiceManager mSystemServiceManager;
402
403    private Installer mInstaller;
404
405    /** Run all ActivityStacks through this */
406    ActivityStackSupervisor mStackSupervisor;
407
408    /** Task stack change listeners. */
409    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
410            new RemoteCallbackList<ITaskStackListener>();
411
412    public IntentFirewall mIntentFirewall;
413
414    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
415    // default actuion automatically.  Important for devices without direct input
416    // devices.
417    private boolean mShowDialogs = true;
418
419    BroadcastQueue mFgBroadcastQueue;
420    BroadcastQueue mBgBroadcastQueue;
421    // Convenient for easy iteration over the queues. Foreground is first
422    // so that dispatch of foreground broadcasts gets precedence.
423    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
424
425    BroadcastQueue broadcastQueueForIntent(Intent intent) {
426        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
427        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
428                "Broadcast intent " + intent + " on "
429                + (isFg ? "foreground" : "background") + " queue");
430        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
431    }
432
433    /**
434     * Activity we have told the window manager to have key focus.
435     */
436    ActivityRecord mFocusedActivity = null;
437
438    /**
439     * User id of the last activity mFocusedActivity was set to.
440     */
441    private int mLastFocusedUserId;
442
443    /**
444     * If non-null, we are tracking the time the user spends in the currently focused app.
445     */
446    private AppTimeTracker mCurAppTimeTracker;
447
448    /**
449     * List of intents that were used to start the most recent tasks.
450     */
451    private final RecentTasks mRecentTasks;
452
453    /**
454     * For addAppTask: cached of the last activity component that was added.
455     */
456    ComponentName mLastAddedTaskComponent;
457
458    /**
459     * For addAppTask: cached of the last activity uid that was added.
460     */
461    int mLastAddedTaskUid;
462
463    /**
464     * For addAppTask: cached of the last ActivityInfo that was added.
465     */
466    ActivityInfo mLastAddedTaskActivity;
467
468    /**
469     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
470     */
471    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
472
473    /**
474     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
475     */
476    String mDeviceOwnerName;
477
478    public class PendingAssistExtras extends Binder implements Runnable {
479        public final ActivityRecord activity;
480        public final Bundle extras;
481        public final Intent intent;
482        public final String hint;
483        public final IResultReceiver receiver;
484        public final int userHandle;
485        public boolean haveResult = false;
486        public Bundle result = null;
487        public AssistStructure structure = null;
488        public AssistContent content = null;
489        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
490                String _hint, IResultReceiver _receiver, int _userHandle) {
491            activity = _activity;
492            extras = _extras;
493            intent = _intent;
494            hint = _hint;
495            receiver = _receiver;
496            userHandle = _userHandle;
497        }
498        @Override
499        public void run() {
500            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
501            synchronized (ActivityManagerService.this) {
502                synchronized (this) {
503                    haveResult = true;
504                    notifyAll();
505                }
506                pendingAssistExtrasTimedOutLocked(this);
507            }
508        }
509    }
510
511    final ArrayList<PendingAssistExtras> mPendingAssistExtras
512            = new ArrayList<PendingAssistExtras>();
513
514    /**
515     * Process management.
516     */
517    final ProcessList mProcessList = new ProcessList();
518
519    /**
520     * All of the applications we currently have running organized by name.
521     * The keys are strings of the application package name (as
522     * returned by the package manager), and the keys are ApplicationRecord
523     * objects.
524     */
525    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
526
527    /**
528     * Tracking long-term execution of processes to look for abuse and other
529     * bad app behavior.
530     */
531    final ProcessStatsService mProcessStats;
532
533    /**
534     * The currently running isolated processes.
535     */
536    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
537
538    /**
539     * Counter for assigning isolated process uids, to avoid frequently reusing the
540     * same ones.
541     */
542    int mNextIsolatedProcessUid = 0;
543
544    /**
545     * The currently running heavy-weight process, if any.
546     */
547    ProcessRecord mHeavyWeightProcess = null;
548
549    /**
550     * The last time that various processes have crashed.
551     */
552    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
553
554    /**
555     * Information about a process that is currently marked as bad.
556     */
557    static final class BadProcessInfo {
558        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
559            this.time = time;
560            this.shortMsg = shortMsg;
561            this.longMsg = longMsg;
562            this.stack = stack;
563        }
564
565        final long time;
566        final String shortMsg;
567        final String longMsg;
568        final String stack;
569    }
570
571    /**
572     * Set of applications that we consider to be bad, and will reject
573     * incoming broadcasts from (which the user has no control over).
574     * Processes are added to this set when they have crashed twice within
575     * a minimum amount of time; they are removed from it when they are
576     * later restarted (hopefully due to some user action).  The value is the
577     * time it was added to the list.
578     */
579    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
580
581    /**
582     * All of the processes we currently have running organized by pid.
583     * The keys are the pid running the application.
584     *
585     * <p>NOTE: This object is protected by its own lock, NOT the global
586     * activity manager lock!
587     */
588    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
589
590    /**
591     * All of the processes that have been forced to be foreground.  The key
592     * is the pid of the caller who requested it (we hold a death
593     * link on it).
594     */
595    abstract class ForegroundToken implements IBinder.DeathRecipient {
596        int pid;
597        IBinder token;
598    }
599    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
600
601    /**
602     * List of records for processes that someone had tried to start before the
603     * system was ready.  We don't start them at that point, but ensure they
604     * are started by the time booting is complete.
605     */
606    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
607
608    /**
609     * List of persistent applications that are in the process
610     * of being started.
611     */
612    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
613
614    /**
615     * Processes that are being forcibly torn down.
616     */
617    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
618
619    /**
620     * List of running applications, sorted by recent usage.
621     * The first entry in the list is the least recently used.
622     */
623    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
624
625    /**
626     * Where in mLruProcesses that the processes hosting activities start.
627     */
628    int mLruProcessActivityStart = 0;
629
630    /**
631     * Where in mLruProcesses that the processes hosting services start.
632     * This is after (lower index) than mLruProcessesActivityStart.
633     */
634    int mLruProcessServiceStart = 0;
635
636    /**
637     * List of processes that should gc as soon as things are idle.
638     */
639    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
640
641    /**
642     * Processes we want to collect PSS data from.
643     */
644    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
645
646    /**
647     * Last time we requested PSS data of all processes.
648     */
649    long mLastFullPssTime = SystemClock.uptimeMillis();
650
651    /**
652     * If set, the next time we collect PSS data we should do a full collection
653     * with data from native processes and the kernel.
654     */
655    boolean mFullPssPending = false;
656
657    /**
658     * This is the process holding what we currently consider to be
659     * the "home" activity.
660     */
661    ProcessRecord mHomeProcess;
662
663    /**
664     * This is the process holding the activity the user last visited that
665     * is in a different process from the one they are currently in.
666     */
667    ProcessRecord mPreviousProcess;
668
669    /**
670     * The time at which the previous process was last visible.
671     */
672    long mPreviousProcessVisibleTime;
673
674    /**
675     * Track all uids that have actively running processes.
676     */
677    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
678
679    /**
680     * Which users have been started, so are allowed to run code.
681     */
682    final SparseArray<UserState> mStartedUsers = new SparseArray<>();
683
684    /**
685     * LRU list of history of current users.  Most recently current is at the end.
686     */
687    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
688
689    /**
690     * Constant array of the users that are currently started.
691     */
692    int[] mStartedUserArray = new int[] { 0 };
693
694    /**
695     * Registered observers of the user switching mechanics.
696     */
697    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
698            = new RemoteCallbackList<IUserSwitchObserver>();
699
700    /**
701     * Currently active user switch.
702     */
703    Object mCurUserSwitchCallback;
704
705    /**
706     * Packages that the user has asked to have run in screen size
707     * compatibility mode instead of filling the screen.
708     */
709    final CompatModePackages mCompatModePackages;
710
711    /**
712     * Set of IntentSenderRecord objects that are currently active.
713     */
714    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
715            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
716
717    /**
718     * Fingerprints (hashCode()) of stack traces that we've
719     * already logged DropBox entries for.  Guarded by itself.  If
720     * something (rogue user app) forces this over
721     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
722     */
723    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
724    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
725
726    /**
727     * Strict Mode background batched logging state.
728     *
729     * The string buffer is guarded by itself, and its lock is also
730     * used to determine if another batched write is already
731     * in-flight.
732     */
733    private final StringBuilder mStrictModeBuffer = new StringBuilder();
734
735    /**
736     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
737     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
738     */
739    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
740
741    /**
742     * Resolver for broadcast intents to registered receivers.
743     * Holds BroadcastFilter (subclass of IntentFilter).
744     */
745    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
746            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
747        @Override
748        protected boolean allowFilterResult(
749                BroadcastFilter filter, List<BroadcastFilter> dest) {
750            IBinder target = filter.receiverList.receiver.asBinder();
751            for (int i = dest.size() - 1; i >= 0; i--) {
752                if (dest.get(i).receiverList.receiver.asBinder() == target) {
753                    return false;
754                }
755            }
756            return true;
757        }
758
759        @Override
760        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
761            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
762                    || userId == filter.owningUserId) {
763                return super.newResult(filter, match, userId);
764            }
765            return null;
766        }
767
768        @Override
769        protected BroadcastFilter[] newArray(int size) {
770            return new BroadcastFilter[size];
771        }
772
773        @Override
774        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
775            return packageName.equals(filter.packageName);
776        }
777    };
778
779    /**
780     * State of all active sticky broadcasts per user.  Keys are the action of the
781     * sticky Intent, values are an ArrayList of all broadcasted intents with
782     * that action (which should usually be one).  The SparseArray is keyed
783     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
784     * for stickies that are sent to all users.
785     */
786    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
787            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
788
789    final ActiveServices mServices;
790
791    final static class Association {
792        final int mSourceUid;
793        final String mSourceProcess;
794        final int mTargetUid;
795        final ComponentName mTargetComponent;
796        final String mTargetProcess;
797
798        int mCount;
799        long mTime;
800
801        int mNesting;
802        long mStartTime;
803
804        Association(int sourceUid, String sourceProcess, int targetUid,
805                ComponentName targetComponent, String targetProcess) {
806            mSourceUid = sourceUid;
807            mSourceProcess = sourceProcess;
808            mTargetUid = targetUid;
809            mTargetComponent = targetComponent;
810            mTargetProcess = targetProcess;
811        }
812    }
813
814    /**
815     * When service association tracking is enabled, this is all of the associations we
816     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
817     * -> association data.
818     */
819    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
820            mAssociations = new SparseArray<>();
821    boolean mTrackingAssociations;
822
823    /**
824     * Backup/restore process management
825     */
826    String mBackupAppName = null;
827    BackupRecord mBackupTarget = null;
828
829    final ProviderMap mProviderMap;
830
831    /**
832     * List of content providers who have clients waiting for them.  The
833     * application is currently being launched and the provider will be
834     * removed from this list once it is published.
835     */
836    final ArrayList<ContentProviderRecord> mLaunchingProviders
837            = new ArrayList<ContentProviderRecord>();
838
839    /**
840     * File storing persisted {@link #mGrantedUriPermissions}.
841     */
842    private final AtomicFile mGrantFile;
843
844    /** XML constants used in {@link #mGrantFile} */
845    private static final String TAG_URI_GRANTS = "uri-grants";
846    private static final String TAG_URI_GRANT = "uri-grant";
847    private static final String ATTR_USER_HANDLE = "userHandle";
848    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
849    private static final String ATTR_TARGET_USER_ID = "targetUserId";
850    private static final String ATTR_SOURCE_PKG = "sourcePkg";
851    private static final String ATTR_TARGET_PKG = "targetPkg";
852    private static final String ATTR_URI = "uri";
853    private static final String ATTR_MODE_FLAGS = "modeFlags";
854    private static final String ATTR_CREATED_TIME = "createdTime";
855    private static final String ATTR_PREFIX = "prefix";
856
857    /**
858     * Global set of specific {@link Uri} permissions that have been granted.
859     * This optimized lookup structure maps from {@link UriPermission#targetUid}
860     * to {@link UriPermission#uri} to {@link UriPermission}.
861     */
862    @GuardedBy("this")
863    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
864            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
865
866    public static class GrantUri {
867        public final int sourceUserId;
868        public final Uri uri;
869        public boolean prefix;
870
871        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
872            this.sourceUserId = sourceUserId;
873            this.uri = uri;
874            this.prefix = prefix;
875        }
876
877        @Override
878        public int hashCode() {
879            int hashCode = 1;
880            hashCode = 31 * hashCode + sourceUserId;
881            hashCode = 31 * hashCode + uri.hashCode();
882            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
883            return hashCode;
884        }
885
886        @Override
887        public boolean equals(Object o) {
888            if (o instanceof GrantUri) {
889                GrantUri other = (GrantUri) o;
890                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
891                        && prefix == other.prefix;
892            }
893            return false;
894        }
895
896        @Override
897        public String toString() {
898            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
899            if (prefix) result += " [prefix]";
900            return result;
901        }
902
903        public String toSafeString() {
904            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
905            if (prefix) result += " [prefix]";
906            return result;
907        }
908
909        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
910            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
911                    ContentProvider.getUriWithoutUserId(uri), false);
912        }
913    }
914
915    CoreSettingsObserver mCoreSettingsObserver;
916
917    /**
918     * Thread-local storage used to carry caller permissions over through
919     * indirect content-provider access.
920     */
921    private class Identity {
922        public final IBinder token;
923        public final int pid;
924        public final int uid;
925
926        Identity(IBinder _token, int _pid, int _uid) {
927            token = _token;
928            pid = _pid;
929            uid = _uid;
930        }
931    }
932
933    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
934
935    /**
936     * All information we have collected about the runtime performance of
937     * any user id that can impact battery performance.
938     */
939    final BatteryStatsService mBatteryStatsService;
940
941    /**
942     * Information about component usage
943     */
944    UsageStatsManagerInternal mUsageStatsService;
945
946    /**
947     * Access to DeviceIdleController service.
948     */
949    DeviceIdleController.LocalService mLocalDeviceIdleController;
950
951    /**
952     * Information about and control over application operations
953     */
954    final AppOpsService mAppOpsService;
955
956    /**
957     * Save recent tasks information across reboots.
958     */
959    final TaskPersister mTaskPersister;
960
961    /**
962     * Current configuration information.  HistoryRecord objects are given
963     * a reference to this object to indicate which configuration they are
964     * currently running in, so this object must be kept immutable.
965     */
966    Configuration mConfiguration = new Configuration();
967
968    /**
969     * Current sequencing integer of the configuration, for skipping old
970     * configurations.
971     */
972    int mConfigurationSeq = 0;
973
974    /**
975     * Hardware-reported OpenGLES version.
976     */
977    final int GL_ES_VERSION;
978
979    /**
980     * List of initialization arguments to pass to all processes when binding applications to them.
981     * For example, references to the commonly used services.
982     */
983    HashMap<String, IBinder> mAppBindArgs;
984
985    /**
986     * Temporary to avoid allocations.  Protected by main lock.
987     */
988    final StringBuilder mStringBuilder = new StringBuilder(256);
989
990    /**
991     * Used to control how we initialize the service.
992     */
993    ComponentName mTopComponent;
994    String mTopAction = Intent.ACTION_MAIN;
995    String mTopData;
996    boolean mProcessesReady = false;
997    boolean mSystemReady = false;
998    boolean mBooting = false;
999    boolean mCallFinishBooting = false;
1000    boolean mBootAnimationComplete = false;
1001    boolean mWaitingUpdate = false;
1002    boolean mDidUpdate = false;
1003    boolean mOnBattery = false;
1004    boolean mLaunchWarningShown = false;
1005
1006    Context mContext;
1007
1008    int mFactoryTest;
1009
1010    boolean mCheckedForSetup;
1011
1012    /**
1013     * The time at which we will allow normal application switches again,
1014     * after a call to {@link #stopAppSwitches()}.
1015     */
1016    long mAppSwitchesAllowedTime;
1017
1018    /**
1019     * This is set to true after the first switch after mAppSwitchesAllowedTime
1020     * is set; any switches after that will clear the time.
1021     */
1022    boolean mDidAppSwitch;
1023
1024    /**
1025     * Last time (in realtime) at which we checked for power usage.
1026     */
1027    long mLastPowerCheckRealtime;
1028
1029    /**
1030     * Last time (in uptime) at which we checked for power usage.
1031     */
1032    long mLastPowerCheckUptime;
1033
1034    /**
1035     * Set while we are wanting to sleep, to prevent any
1036     * activities from being started/resumed.
1037     */
1038    private boolean mSleeping = false;
1039
1040    /**
1041     * The process state used for processes that are running the top activities.
1042     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1043     */
1044    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1045
1046    /**
1047     * Set while we are running a voice interaction.  This overrides
1048     * sleeping while it is active.
1049     */
1050    private IVoiceInteractionSession mRunningVoice;
1051
1052    /**
1053     * For some direct access we need to power manager.
1054     */
1055    PowerManagerInternal mLocalPowerManager;
1056
1057    /**
1058     * We want to hold a wake lock while running a voice interaction session, since
1059     * this may happen with the screen off and we need to keep the CPU running to
1060     * be able to continue to interact with the user.
1061     */
1062    PowerManager.WakeLock mVoiceWakeLock;
1063
1064    /**
1065     * State of external calls telling us if the device is awake or asleep.
1066     */
1067    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1068
1069    /**
1070     * A list of tokens that cause the top activity to be put to sleep.
1071     * They are used by components that may hide and block interaction with underlying
1072     * activities.
1073     */
1074    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1075
1076    static final int LOCK_SCREEN_HIDDEN = 0;
1077    static final int LOCK_SCREEN_LEAVING = 1;
1078    static final int LOCK_SCREEN_SHOWN = 2;
1079    /**
1080     * State of external call telling us if the lock screen is shown.
1081     */
1082    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1083
1084    /**
1085     * Set if we are shutting down the system, similar to sleeping.
1086     */
1087    boolean mShuttingDown = false;
1088
1089    /**
1090     * Current sequence id for oom_adj computation traversal.
1091     */
1092    int mAdjSeq = 0;
1093
1094    /**
1095     * Current sequence id for process LRU updating.
1096     */
1097    int mLruSeq = 0;
1098
1099    /**
1100     * Keep track of the non-cached/empty process we last found, to help
1101     * determine how to distribute cached/empty processes next time.
1102     */
1103    int mNumNonCachedProcs = 0;
1104
1105    /**
1106     * Keep track of the number of cached hidden procs, to balance oom adj
1107     * distribution between those and empty procs.
1108     */
1109    int mNumCachedHiddenProcs = 0;
1110
1111    /**
1112     * Keep track of the number of service processes we last found, to
1113     * determine on the next iteration which should be B services.
1114     */
1115    int mNumServiceProcs = 0;
1116    int mNewNumAServiceProcs = 0;
1117    int mNewNumServiceProcs = 0;
1118
1119    /**
1120     * Allow the current computed overall memory level of the system to go down?
1121     * This is set to false when we are killing processes for reasons other than
1122     * memory management, so that the now smaller process list will not be taken as
1123     * an indication that memory is tighter.
1124     */
1125    boolean mAllowLowerMemLevel = false;
1126
1127    /**
1128     * The last computed memory level, for holding when we are in a state that
1129     * processes are going away for other reasons.
1130     */
1131    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1132
1133    /**
1134     * The last total number of process we have, to determine if changes actually look
1135     * like a shrinking number of process due to lower RAM.
1136     */
1137    int mLastNumProcesses;
1138
1139    /**
1140     * The uptime of the last time we performed idle maintenance.
1141     */
1142    long mLastIdleTime = SystemClock.uptimeMillis();
1143
1144    /**
1145     * Total time spent with RAM that has been added in the past since the last idle time.
1146     */
1147    long mLowRamTimeSinceLastIdle = 0;
1148
1149    /**
1150     * If RAM is currently low, when that horrible situation started.
1151     */
1152    long mLowRamStartTime = 0;
1153
1154    /**
1155     * For reporting to battery stats the current top application.
1156     */
1157    private String mCurResumedPackage = null;
1158    private int mCurResumedUid = -1;
1159
1160    /**
1161     * For reporting to battery stats the apps currently running foreground
1162     * service.  The ProcessMap is package/uid tuples; each of these contain
1163     * an array of the currently foreground processes.
1164     */
1165    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1166            = new ProcessMap<ArrayList<ProcessRecord>>();
1167
1168    /**
1169     * This is set if we had to do a delayed dexopt of an app before launching
1170     * it, to increase the ANR timeouts in that case.
1171     */
1172    boolean mDidDexOpt;
1173
1174    /**
1175     * Set if the systemServer made a call to enterSafeMode.
1176     */
1177    boolean mSafeMode;
1178
1179    /**
1180     * If true, we are running under a test environment so will sample PSS from processes
1181     * much more rapidly to try to collect better data when the tests are rapidly
1182     * running through apps.
1183     */
1184    boolean mTestPssMode = false;
1185
1186    String mDebugApp = null;
1187    boolean mWaitForDebugger = false;
1188    boolean mDebugTransient = false;
1189    String mOrigDebugApp = null;
1190    boolean mOrigWaitForDebugger = false;
1191    boolean mAlwaysFinishActivities = false;
1192    IActivityController mController = null;
1193    String mProfileApp = null;
1194    ProcessRecord mProfileProc = null;
1195    String mProfileFile;
1196    ParcelFileDescriptor mProfileFd;
1197    int mSamplingInterval = 0;
1198    boolean mAutoStopProfiler = false;
1199    int mProfileType = 0;
1200    String mOpenGlTraceApp = null;
1201    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1202    String mMemWatchDumpProcName;
1203    String mMemWatchDumpFile;
1204    int mMemWatchDumpPid;
1205    int mMemWatchDumpUid;
1206
1207    final long[] mTmpLong = new long[1];
1208
1209    static final class ProcessChangeItem {
1210        static final int CHANGE_ACTIVITIES = 1<<0;
1211        static final int CHANGE_PROCESS_STATE = 1<<1;
1212        int changes;
1213        int uid;
1214        int pid;
1215        int processState;
1216        boolean foregroundActivities;
1217    }
1218
1219    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1220    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1221
1222    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1223    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1224
1225    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1226    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1227
1228    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1229    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1230
1231    /**
1232     * Runtime CPU use collection thread.  This object's lock is used to
1233     * perform synchronization with the thread (notifying it to run).
1234     */
1235    final Thread mProcessCpuThread;
1236
1237    /**
1238     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1239     * Must acquire this object's lock when accessing it.
1240     * NOTE: this lock will be held while doing long operations (trawling
1241     * through all processes in /proc), so it should never be acquired by
1242     * any critical paths such as when holding the main activity manager lock.
1243     */
1244    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1245            MONITOR_THREAD_CPU_USAGE);
1246    final AtomicLong mLastCpuTime = new AtomicLong(0);
1247    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1248
1249    long mLastWriteTime = 0;
1250
1251    /**
1252     * Used to retain an update lock when the foreground activity is in
1253     * immersive mode.
1254     */
1255    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1256
1257    /**
1258     * Set to true after the system has finished booting.
1259     */
1260    boolean mBooted = false;
1261
1262    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1263    int mProcessLimitOverride = -1;
1264
1265    WindowManagerService mWindowManager;
1266
1267    final ActivityThread mSystemThread;
1268
1269    // Holds the current foreground user's id
1270    int mCurrentUserId = 0;
1271    // Holds the target user's id during a user switch
1272    int mTargetUserId = UserHandle.USER_NULL;
1273    // If there are multiple profiles for the current user, their ids are here
1274    // Currently only the primary user can have managed profiles
1275    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1276
1277    /**
1278     * Mapping from each known user ID to the profile group ID it is associated with.
1279     */
1280    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1281
1282    private UserManagerService mUserManager;
1283
1284    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1285        final ProcessRecord mApp;
1286        final int mPid;
1287        final IApplicationThread mAppThread;
1288
1289        AppDeathRecipient(ProcessRecord app, int pid,
1290                IApplicationThread thread) {
1291            if (DEBUG_ALL) Slog.v(
1292                TAG, "New death recipient " + this
1293                + " for thread " + thread.asBinder());
1294            mApp = app;
1295            mPid = pid;
1296            mAppThread = thread;
1297        }
1298
1299        @Override
1300        public void binderDied() {
1301            if (DEBUG_ALL) Slog.v(
1302                TAG, "Death received in " + this
1303                + " for thread " + mAppThread.asBinder());
1304            synchronized(ActivityManagerService.this) {
1305                appDiedLocked(mApp, mPid, mAppThread, true);
1306            }
1307        }
1308    }
1309
1310    static final int SHOW_ERROR_MSG = 1;
1311    static final int SHOW_NOT_RESPONDING_MSG = 2;
1312    static final int SHOW_FACTORY_ERROR_MSG = 3;
1313    static final int UPDATE_CONFIGURATION_MSG = 4;
1314    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1315    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1316    static final int SERVICE_TIMEOUT_MSG = 12;
1317    static final int UPDATE_TIME_ZONE = 13;
1318    static final int SHOW_UID_ERROR_MSG = 14;
1319    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1320    static final int PROC_START_TIMEOUT_MSG = 20;
1321    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1322    static final int KILL_APPLICATION_MSG = 22;
1323    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1324    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1325    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1326    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1327    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1328    static final int CLEAR_DNS_CACHE_MSG = 28;
1329    static final int UPDATE_HTTP_PROXY_MSG = 29;
1330    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1331    static final int DISPATCH_PROCESSES_CHANGED = 31;
1332    static final int DISPATCH_PROCESS_DIED = 32;
1333    static final int REPORT_MEM_USAGE_MSG = 33;
1334    static final int REPORT_USER_SWITCH_MSG = 34;
1335    static final int CONTINUE_USER_SWITCH_MSG = 35;
1336    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1337    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1338    static final int PERSIST_URI_GRANTS_MSG = 38;
1339    static final int REQUEST_ALL_PSS_MSG = 39;
1340    static final int START_PROFILES_MSG = 40;
1341    static final int UPDATE_TIME = 41;
1342    static final int SYSTEM_USER_START_MSG = 42;
1343    static final int SYSTEM_USER_CURRENT_MSG = 43;
1344    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1345    static final int FINISH_BOOTING_MSG = 45;
1346    static final int START_USER_SWITCH_MSG = 46;
1347    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1348    static final int DISMISS_DIALOG_MSG = 48;
1349    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1350    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1351    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1352    static final int DELETE_DUMPHEAP_MSG = 52;
1353    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1354    static final int DISPATCH_UIDS_CHANGED_MSG = 54;
1355    static final int REPORT_TIME_TRACKER_MSG = 55;
1356
1357    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1358    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1359    static final int FIRST_COMPAT_MODE_MSG = 300;
1360    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1361
1362    CompatModeDialog mCompatModeDialog;
1363    long mLastMemUsageReportTime = 0;
1364
1365    /**
1366     * Flag whether the current user is a "monkey", i.e. whether
1367     * the UI is driven by a UI automation tool.
1368     */
1369    private boolean mUserIsMonkey;
1370
1371    /** Flag whether the device has a Recents UI */
1372    boolean mHasRecents;
1373
1374    /** The dimensions of the thumbnails in the Recents UI. */
1375    int mThumbnailWidth;
1376    int mThumbnailHeight;
1377
1378    final ServiceThread mHandlerThread;
1379    final MainHandler mHandler;
1380    final UiHandler mUiHandler;
1381
1382    final class UiHandler extends Handler {
1383        public UiHandler() {
1384            super(com.android.server.UiThread.get().getLooper(), null, true);
1385        }
1386
1387        @Override
1388        public void handleMessage(Message msg) {
1389            switch (msg.what) {
1390            case SHOW_ERROR_MSG: {
1391                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1392                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1393                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1394                synchronized (ActivityManagerService.this) {
1395                    ProcessRecord proc = (ProcessRecord)data.get("app");
1396                    AppErrorResult res = (AppErrorResult) data.get("result");
1397                    if (proc != null && proc.crashDialog != null) {
1398                        Slog.e(TAG, "App already has crash dialog: " + proc);
1399                        if (res != null) {
1400                            res.set(0);
1401                        }
1402                        return;
1403                    }
1404                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1405                            >= Process.FIRST_APPLICATION_UID
1406                            && proc.pid != MY_PID);
1407                    for (int userId : mCurrentProfileIds) {
1408                        isBackground &= (proc.userId != userId);
1409                    }
1410                    if (isBackground && !showBackground) {
1411                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1412                        if (res != null) {
1413                            res.set(0);
1414                        }
1415                        return;
1416                    }
1417                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1418                        Dialog d = new AppErrorDialog(mContext,
1419                                ActivityManagerService.this, res, proc);
1420                        d.show();
1421                        proc.crashDialog = d;
1422                    } else {
1423                        // The device is asleep, so just pretend that the user
1424                        // saw a crash dialog and hit "force quit".
1425                        if (res != null) {
1426                            res.set(0);
1427                        }
1428                    }
1429                }
1430
1431                ensureBootCompleted();
1432            } break;
1433            case SHOW_NOT_RESPONDING_MSG: {
1434                synchronized (ActivityManagerService.this) {
1435                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1436                    ProcessRecord proc = (ProcessRecord)data.get("app");
1437                    if (proc != null && proc.anrDialog != null) {
1438                        Slog.e(TAG, "App already has anr dialog: " + proc);
1439                        return;
1440                    }
1441
1442                    Intent intent = new Intent("android.intent.action.ANR");
1443                    if (!mProcessesReady) {
1444                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1445                                | Intent.FLAG_RECEIVER_FOREGROUND);
1446                    }
1447                    broadcastIntentLocked(null, null, intent,
1448                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1449                            null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1450
1451                    if (mShowDialogs) {
1452                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1453                                mContext, proc, (ActivityRecord)data.get("activity"),
1454                                msg.arg1 != 0);
1455                        d.show();
1456                        proc.anrDialog = d;
1457                    } else {
1458                        // Just kill the app if there is no dialog to be shown.
1459                        killAppAtUsersRequest(proc, null);
1460                    }
1461                }
1462
1463                ensureBootCompleted();
1464            } break;
1465            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1466                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1467                synchronized (ActivityManagerService.this) {
1468                    ProcessRecord proc = (ProcessRecord) data.get("app");
1469                    if (proc == null) {
1470                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1471                        break;
1472                    }
1473                    if (proc.crashDialog != null) {
1474                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1475                        return;
1476                    }
1477                    AppErrorResult res = (AppErrorResult) data.get("result");
1478                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1479                        Dialog d = new StrictModeViolationDialog(mContext,
1480                                ActivityManagerService.this, res, proc);
1481                        d.show();
1482                        proc.crashDialog = d;
1483                    } else {
1484                        // The device is asleep, so just pretend that the user
1485                        // saw a crash dialog and hit "force quit".
1486                        res.set(0);
1487                    }
1488                }
1489                ensureBootCompleted();
1490            } break;
1491            case SHOW_FACTORY_ERROR_MSG: {
1492                Dialog d = new FactoryErrorDialog(
1493                    mContext, msg.getData().getCharSequence("msg"));
1494                d.show();
1495                ensureBootCompleted();
1496            } break;
1497            case WAIT_FOR_DEBUGGER_MSG: {
1498                synchronized (ActivityManagerService.this) {
1499                    ProcessRecord app = (ProcessRecord)msg.obj;
1500                    if (msg.arg1 != 0) {
1501                        if (!app.waitedForDebugger) {
1502                            Dialog d = new AppWaitingForDebuggerDialog(
1503                                    ActivityManagerService.this,
1504                                    mContext, app);
1505                            app.waitDialog = d;
1506                            app.waitedForDebugger = true;
1507                            d.show();
1508                        }
1509                    } else {
1510                        if (app.waitDialog != null) {
1511                            app.waitDialog.dismiss();
1512                            app.waitDialog = null;
1513                        }
1514                    }
1515                }
1516            } break;
1517            case SHOW_UID_ERROR_MSG: {
1518                if (mShowDialogs) {
1519                    AlertDialog d = new BaseErrorDialog(mContext);
1520                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1521                    d.setCancelable(false);
1522                    d.setTitle(mContext.getText(R.string.android_system_label));
1523                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1524                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1525                            obtainMessage(DISMISS_DIALOG_MSG, d));
1526                    d.show();
1527                }
1528            } break;
1529            case SHOW_FINGERPRINT_ERROR_MSG: {
1530                if (mShowDialogs) {
1531                    AlertDialog d = new BaseErrorDialog(mContext);
1532                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1533                    d.setCancelable(false);
1534                    d.setTitle(mContext.getText(R.string.android_system_label));
1535                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1536                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1537                            obtainMessage(DISMISS_DIALOG_MSG, d));
1538                    d.show();
1539                }
1540            } break;
1541            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1542                synchronized (ActivityManagerService.this) {
1543                    ActivityRecord ar = (ActivityRecord) msg.obj;
1544                    if (mCompatModeDialog != null) {
1545                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1546                                ar.info.applicationInfo.packageName)) {
1547                            return;
1548                        }
1549                        mCompatModeDialog.dismiss();
1550                        mCompatModeDialog = null;
1551                    }
1552                    if (ar != null && false) {
1553                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1554                                ar.packageName)) {
1555                            int mode = mCompatModePackages.computeCompatModeLocked(
1556                                    ar.info.applicationInfo);
1557                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1558                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1559                                mCompatModeDialog = new CompatModeDialog(
1560                                        ActivityManagerService.this, mContext,
1561                                        ar.info.applicationInfo);
1562                                mCompatModeDialog.show();
1563                            }
1564                        }
1565                    }
1566                }
1567                break;
1568            }
1569            case START_USER_SWITCH_MSG: {
1570                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1571                break;
1572            }
1573            case DISMISS_DIALOG_MSG: {
1574                final Dialog d = (Dialog) msg.obj;
1575                d.dismiss();
1576                break;
1577            }
1578            case DISPATCH_PROCESSES_CHANGED: {
1579                dispatchProcessesChanged();
1580                break;
1581            }
1582            case DISPATCH_PROCESS_DIED: {
1583                final int pid = msg.arg1;
1584                final int uid = msg.arg2;
1585                dispatchProcessDied(pid, uid);
1586                break;
1587            }
1588            case DISPATCH_UIDS_CHANGED_MSG: {
1589                dispatchUidsChanged();
1590            } break;
1591            }
1592        }
1593    }
1594
1595    final class MainHandler extends Handler {
1596        public MainHandler(Looper looper) {
1597            super(looper, null, true);
1598        }
1599
1600        @Override
1601        public void handleMessage(Message msg) {
1602            switch (msg.what) {
1603            case UPDATE_CONFIGURATION_MSG: {
1604                final ContentResolver resolver = mContext.getContentResolver();
1605                Settings.System.putConfiguration(resolver, (Configuration) msg.obj);
1606            } break;
1607            case GC_BACKGROUND_PROCESSES_MSG: {
1608                synchronized (ActivityManagerService.this) {
1609                    performAppGcsIfAppropriateLocked();
1610                }
1611            } break;
1612            case SERVICE_TIMEOUT_MSG: {
1613                if (mDidDexOpt) {
1614                    mDidDexOpt = false;
1615                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1616                    nmsg.obj = msg.obj;
1617                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1618                    return;
1619                }
1620                mServices.serviceTimeout((ProcessRecord)msg.obj);
1621            } break;
1622            case UPDATE_TIME_ZONE: {
1623                synchronized (ActivityManagerService.this) {
1624                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1625                        ProcessRecord r = mLruProcesses.get(i);
1626                        if (r.thread != null) {
1627                            try {
1628                                r.thread.updateTimeZone();
1629                            } catch (RemoteException ex) {
1630                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1631                            }
1632                        }
1633                    }
1634                }
1635            } break;
1636            case CLEAR_DNS_CACHE_MSG: {
1637                synchronized (ActivityManagerService.this) {
1638                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1639                        ProcessRecord r = mLruProcesses.get(i);
1640                        if (r.thread != null) {
1641                            try {
1642                                r.thread.clearDnsCache();
1643                            } catch (RemoteException ex) {
1644                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1645                            }
1646                        }
1647                    }
1648                }
1649            } break;
1650            case UPDATE_HTTP_PROXY_MSG: {
1651                ProxyInfo proxy = (ProxyInfo)msg.obj;
1652                String host = "";
1653                String port = "";
1654                String exclList = "";
1655                Uri pacFileUrl = Uri.EMPTY;
1656                if (proxy != null) {
1657                    host = proxy.getHost();
1658                    port = Integer.toString(proxy.getPort());
1659                    exclList = proxy.getExclusionListAsString();
1660                    pacFileUrl = proxy.getPacFileUrl();
1661                }
1662                synchronized (ActivityManagerService.this) {
1663                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1664                        ProcessRecord r = mLruProcesses.get(i);
1665                        if (r.thread != null) {
1666                            try {
1667                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1668                            } catch (RemoteException ex) {
1669                                Slog.w(TAG, "Failed to update http proxy for: " +
1670                                        r.info.processName);
1671                            }
1672                        }
1673                    }
1674                }
1675            } break;
1676            case PROC_START_TIMEOUT_MSG: {
1677                if (mDidDexOpt) {
1678                    mDidDexOpt = false;
1679                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1680                    nmsg.obj = msg.obj;
1681                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1682                    return;
1683                }
1684                ProcessRecord app = (ProcessRecord)msg.obj;
1685                synchronized (ActivityManagerService.this) {
1686                    processStartTimedOutLocked(app);
1687                }
1688            } break;
1689            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1690                synchronized (ActivityManagerService.this) {
1691                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1692                }
1693            } break;
1694            case KILL_APPLICATION_MSG: {
1695                synchronized (ActivityManagerService.this) {
1696                    int appid = msg.arg1;
1697                    boolean restart = (msg.arg2 == 1);
1698                    Bundle bundle = (Bundle)msg.obj;
1699                    String pkg = bundle.getString("pkg");
1700                    String reason = bundle.getString("reason");
1701                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1702                            false, UserHandle.USER_ALL, reason);
1703                }
1704            } break;
1705            case FINALIZE_PENDING_INTENT_MSG: {
1706                ((PendingIntentRecord)msg.obj).completeFinalize();
1707            } break;
1708            case POST_HEAVY_NOTIFICATION_MSG: {
1709                INotificationManager inm = NotificationManager.getService();
1710                if (inm == null) {
1711                    return;
1712                }
1713
1714                ActivityRecord root = (ActivityRecord)msg.obj;
1715                ProcessRecord process = root.app;
1716                if (process == null) {
1717                    return;
1718                }
1719
1720                try {
1721                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1722                    String text = mContext.getString(R.string.heavy_weight_notification,
1723                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1724                    Notification notification = new Notification.Builder(context)
1725                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1726                            .setWhen(0)
1727                            .setOngoing(true)
1728                            .setTicker(text)
1729                            .setColor(mContext.getColor(
1730                                    com.android.internal.R.color.system_notification_accent_color))
1731                            .setContentTitle(text)
1732                            .setContentText(
1733                                    mContext.getText(R.string.heavy_weight_notification_detail))
1734                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1735                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1736                                    new UserHandle(root.userId)))
1737                            .build();
1738                    try {
1739                        int[] outId = new int[1];
1740                        inm.enqueueNotificationWithTag("android", "android", null,
1741                                R.string.heavy_weight_notification,
1742                                notification, outId, root.userId);
1743                    } catch (RuntimeException e) {
1744                        Slog.w(ActivityManagerService.TAG,
1745                                "Error showing notification for heavy-weight app", e);
1746                    } catch (RemoteException e) {
1747                    }
1748                } catch (NameNotFoundException e) {
1749                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1750                }
1751            } break;
1752            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1753                INotificationManager inm = NotificationManager.getService();
1754                if (inm == null) {
1755                    return;
1756                }
1757                try {
1758                    inm.cancelNotificationWithTag("android", null,
1759                            R.string.heavy_weight_notification,  msg.arg1);
1760                } catch (RuntimeException e) {
1761                    Slog.w(ActivityManagerService.TAG,
1762                            "Error canceling notification for service", e);
1763                } catch (RemoteException e) {
1764                }
1765            } break;
1766            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1767                synchronized (ActivityManagerService.this) {
1768                    checkExcessivePowerUsageLocked(true);
1769                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1770                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1771                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1772                }
1773            } break;
1774            case REPORT_MEM_USAGE_MSG: {
1775                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1776                Thread thread = new Thread() {
1777                    @Override public void run() {
1778                        reportMemUsage(memInfos);
1779                    }
1780                };
1781                thread.start();
1782                break;
1783            }
1784            case REPORT_USER_SWITCH_MSG: {
1785                dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1786                break;
1787            }
1788            case CONTINUE_USER_SWITCH_MSG: {
1789                continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1790                break;
1791            }
1792            case USER_SWITCH_TIMEOUT_MSG: {
1793                timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1794                break;
1795            }
1796            case IMMERSIVE_MODE_LOCK_MSG: {
1797                final boolean nextState = (msg.arg1 != 0);
1798                if (mUpdateLock.isHeld() != nextState) {
1799                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1800                            "Applying new update lock state '" + nextState
1801                            + "' for " + (ActivityRecord)msg.obj);
1802                    if (nextState) {
1803                        mUpdateLock.acquire();
1804                    } else {
1805                        mUpdateLock.release();
1806                    }
1807                }
1808                break;
1809            }
1810            case PERSIST_URI_GRANTS_MSG: {
1811                writeGrantedUriPermissions();
1812                break;
1813            }
1814            case REQUEST_ALL_PSS_MSG: {
1815                synchronized (ActivityManagerService.this) {
1816                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1817                }
1818                break;
1819            }
1820            case START_PROFILES_MSG: {
1821                synchronized (ActivityManagerService.this) {
1822                    startProfilesLocked();
1823                }
1824                break;
1825            }
1826            case UPDATE_TIME: {
1827                synchronized (ActivityManagerService.this) {
1828                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1829                        ProcessRecord r = mLruProcesses.get(i);
1830                        if (r.thread != null) {
1831                            try {
1832                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1833                            } catch (RemoteException ex) {
1834                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1835                            }
1836                        }
1837                    }
1838                }
1839                break;
1840            }
1841            case SYSTEM_USER_START_MSG: {
1842                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1843                        Integer.toString(msg.arg1), msg.arg1);
1844                mSystemServiceManager.startUser(msg.arg1);
1845                break;
1846            }
1847            case SYSTEM_USER_CURRENT_MSG: {
1848                mBatteryStatsService.noteEvent(
1849                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1850                        Integer.toString(msg.arg2), msg.arg2);
1851                mBatteryStatsService.noteEvent(
1852                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1853                        Integer.toString(msg.arg1), msg.arg1);
1854                mSystemServiceManager.switchUser(msg.arg1);
1855                break;
1856            }
1857            case ENTER_ANIMATION_COMPLETE_MSG: {
1858                synchronized (ActivityManagerService.this) {
1859                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1860                    if (r != null && r.app != null && r.app.thread != null) {
1861                        try {
1862                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1863                        } catch (RemoteException e) {
1864                        }
1865                    }
1866                }
1867                break;
1868            }
1869            case FINISH_BOOTING_MSG: {
1870                if (msg.arg1 != 0) {
1871                    finishBooting();
1872                }
1873                if (msg.arg2 != 0) {
1874                    enableScreenAfterBoot();
1875                }
1876                break;
1877            }
1878            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1879                try {
1880                    Locale l = (Locale) msg.obj;
1881                    IBinder service = ServiceManager.getService("mount");
1882                    IMountService mountService = IMountService.Stub.asInterface(service);
1883                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1884                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1885                } catch (RemoteException e) {
1886                    Log.e(TAG, "Error storing locale for decryption UI", e);
1887                }
1888                break;
1889            }
1890            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1891                synchronized (ActivityManagerService.this) {
1892                    int i = mTaskStackListeners.beginBroadcast();
1893                    while (i > 0) {
1894                        i--;
1895                        try {
1896                            // Make a one-way callback to the listener
1897                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1898                        } catch (RemoteException e){
1899                            // Handled by the RemoteCallbackList
1900                        }
1901                    }
1902                    mTaskStackListeners.finishBroadcast();
1903                }
1904                break;
1905            }
1906            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1907                final int uid = msg.arg1;
1908                final byte[] firstPacket = (byte[]) msg.obj;
1909
1910                synchronized (mPidsSelfLocked) {
1911                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
1912                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
1913                        if (p.uid == uid) {
1914                            try {
1915                                p.thread.notifyCleartextNetwork(firstPacket);
1916                            } catch (RemoteException ignored) {
1917                            }
1918                        }
1919                    }
1920                }
1921                break;
1922            }
1923            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
1924                final String procName;
1925                final int uid;
1926                final long memLimit;
1927                final String reportPackage;
1928                synchronized (ActivityManagerService.this) {
1929                    procName = mMemWatchDumpProcName;
1930                    uid = mMemWatchDumpUid;
1931                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
1932                    if (val == null) {
1933                        val = mMemWatchProcesses.get(procName, 0);
1934                    }
1935                    if (val != null) {
1936                        memLimit = val.first;
1937                        reportPackage = val.second;
1938                    } else {
1939                        memLimit = 0;
1940                        reportPackage = null;
1941                    }
1942                }
1943                if (procName == null) {
1944                    return;
1945                }
1946
1947                if (DEBUG_PSS) Slog.d(TAG_PSS,
1948                        "Showing dump heap notification from " + procName + "/" + uid);
1949
1950                INotificationManager inm = NotificationManager.getService();
1951                if (inm == null) {
1952                    return;
1953                }
1954
1955                String text = mContext.getString(R.string.dump_heap_notification, procName);
1956
1957
1958                Intent deleteIntent = new Intent();
1959                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
1960                Intent intent = new Intent();
1961                intent.setClassName("android", DumpHeapActivity.class.getName());
1962                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
1963                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
1964                if (reportPackage != null) {
1965                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
1966                }
1967                int userId = UserHandle.getUserId(uid);
1968                Notification notification = new Notification.Builder(mContext)
1969                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1970                        .setWhen(0)
1971                        .setOngoing(true)
1972                        .setAutoCancel(true)
1973                        .setTicker(text)
1974                        .setColor(mContext.getColor(
1975                                com.android.internal.R.color.system_notification_accent_color))
1976                        .setContentTitle(text)
1977                        .setContentText(
1978                                mContext.getText(R.string.dump_heap_notification_detail))
1979                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1980                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1981                                new UserHandle(userId)))
1982                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
1983                                deleteIntent, 0, UserHandle.OWNER))
1984                        .build();
1985
1986                try {
1987                    int[] outId = new int[1];
1988                    inm.enqueueNotificationWithTag("android", "android", null,
1989                            R.string.dump_heap_notification,
1990                            notification, outId, userId);
1991                } catch (RuntimeException e) {
1992                    Slog.w(ActivityManagerService.TAG,
1993                            "Error showing notification for dump heap", e);
1994                } catch (RemoteException e) {
1995                }
1996            } break;
1997            case DELETE_DUMPHEAP_MSG: {
1998                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
1999                        DumpHeapActivity.JAVA_URI,
2000                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2001                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2002                        UserHandle.myUserId());
2003                synchronized (ActivityManagerService.this) {
2004                    mMemWatchDumpFile = null;
2005                    mMemWatchDumpProcName = null;
2006                    mMemWatchDumpPid = -1;
2007                    mMemWatchDumpUid = -1;
2008                }
2009            } break;
2010            case FOREGROUND_PROFILE_CHANGED_MSG: {
2011                dispatchForegroundProfileChanged(msg.arg1);
2012            } break;
2013            case REPORT_TIME_TRACKER_MSG: {
2014                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2015                tracker.deliverResult(mContext);
2016            } break;
2017            }
2018        }
2019    };
2020
2021    static final int COLLECT_PSS_BG_MSG = 1;
2022
2023    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2024        @Override
2025        public void handleMessage(Message msg) {
2026            switch (msg.what) {
2027            case COLLECT_PSS_BG_MSG: {
2028                long start = SystemClock.uptimeMillis();
2029                MemInfoReader memInfo = null;
2030                synchronized (ActivityManagerService.this) {
2031                    if (mFullPssPending) {
2032                        mFullPssPending = false;
2033                        memInfo = new MemInfoReader();
2034                    }
2035                }
2036                if (memInfo != null) {
2037                    updateCpuStatsNow();
2038                    long nativeTotalPss = 0;
2039                    synchronized (mProcessCpuTracker) {
2040                        final int N = mProcessCpuTracker.countStats();
2041                        for (int j=0; j<N; j++) {
2042                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2043                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2044                                // This is definitely an application process; skip it.
2045                                continue;
2046                            }
2047                            synchronized (mPidsSelfLocked) {
2048                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2049                                    // This is one of our own processes; skip it.
2050                                    continue;
2051                                }
2052                            }
2053                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2054                        }
2055                    }
2056                    memInfo.readMemInfo();
2057                    synchronized (ActivityManagerService.this) {
2058                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2059                                + (SystemClock.uptimeMillis()-start) + "ms");
2060                        final long cachedKb = memInfo.getCachedSizeKb();
2061                        final long freeKb = memInfo.getFreeSizeKb();
2062                        final long zramKb = memInfo.getZramTotalSizeKb();
2063                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2064                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2065                                kernelKb*1024, nativeTotalPss*1024);
2066                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2067                                nativeTotalPss);
2068                    }
2069                }
2070
2071                int num = 0;
2072                long[] tmp = new long[1];
2073                do {
2074                    ProcessRecord proc;
2075                    int procState;
2076                    int pid;
2077                    long lastPssTime;
2078                    synchronized (ActivityManagerService.this) {
2079                        if (mPendingPssProcesses.size() <= 0) {
2080                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2081                                    "Collected PSS of " + num + " processes in "
2082                                    + (SystemClock.uptimeMillis() - start) + "ms");
2083                            mPendingPssProcesses.clear();
2084                            return;
2085                        }
2086                        proc = mPendingPssProcesses.remove(0);
2087                        procState = proc.pssProcState;
2088                        lastPssTime = proc.lastPssTime;
2089                        if (proc.thread != null && procState == proc.setProcState
2090                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2091                                        < SystemClock.uptimeMillis()) {
2092                            pid = proc.pid;
2093                        } else {
2094                            proc = null;
2095                            pid = 0;
2096                        }
2097                    }
2098                    if (proc != null) {
2099                        long pss = Debug.getPss(pid, tmp, null);
2100                        synchronized (ActivityManagerService.this) {
2101                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2102                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2103                                num++;
2104                                recordPssSampleLocked(proc, procState, pss, tmp[0],
2105                                        SystemClock.uptimeMillis());
2106                            }
2107                        }
2108                    }
2109                } while (true);
2110            }
2111            }
2112        }
2113    };
2114
2115    public void setSystemProcess() {
2116        try {
2117            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2118            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2119            ServiceManager.addService("meminfo", new MemBinder(this));
2120            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2121            ServiceManager.addService("dbinfo", new DbBinder(this));
2122            if (MONITOR_CPU_USAGE) {
2123                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2124            }
2125            ServiceManager.addService("permission", new PermissionController(this));
2126            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2127
2128            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2129                    "android", STOCK_PM_FLAGS);
2130            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2131
2132            synchronized (this) {
2133                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2134                app.persistent = true;
2135                app.pid = MY_PID;
2136                app.maxAdj = ProcessList.SYSTEM_ADJ;
2137                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2138                synchronized (mPidsSelfLocked) {
2139                    mPidsSelfLocked.put(app.pid, app);
2140                }
2141                updateLruProcessLocked(app, false, null);
2142                updateOomAdjLocked();
2143            }
2144        } catch (PackageManager.NameNotFoundException e) {
2145            throw new RuntimeException(
2146                    "Unable to find android system package", e);
2147        }
2148    }
2149
2150    public void setWindowManager(WindowManagerService wm) {
2151        mWindowManager = wm;
2152        mStackSupervisor.setWindowManager(wm);
2153    }
2154
2155    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2156        mUsageStatsService = usageStatsManager;
2157    }
2158
2159    public void startObservingNativeCrashes() {
2160        final NativeCrashListener ncl = new NativeCrashListener(this);
2161        ncl.start();
2162    }
2163
2164    public IAppOpsService getAppOpsService() {
2165        return mAppOpsService;
2166    }
2167
2168    static class MemBinder extends Binder {
2169        ActivityManagerService mActivityManagerService;
2170        MemBinder(ActivityManagerService activityManagerService) {
2171            mActivityManagerService = activityManagerService;
2172        }
2173
2174        @Override
2175        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2176            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2177                    != PackageManager.PERMISSION_GRANTED) {
2178                pw.println("Permission Denial: can't dump meminfo from from pid="
2179                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2180                        + " without permission " + android.Manifest.permission.DUMP);
2181                return;
2182            }
2183
2184            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2185        }
2186    }
2187
2188    static class GraphicsBinder extends Binder {
2189        ActivityManagerService mActivityManagerService;
2190        GraphicsBinder(ActivityManagerService activityManagerService) {
2191            mActivityManagerService = activityManagerService;
2192        }
2193
2194        @Override
2195        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2196            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2197                    != PackageManager.PERMISSION_GRANTED) {
2198                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2199                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2200                        + " without permission " + android.Manifest.permission.DUMP);
2201                return;
2202            }
2203
2204            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2205        }
2206    }
2207
2208    static class DbBinder extends Binder {
2209        ActivityManagerService mActivityManagerService;
2210        DbBinder(ActivityManagerService activityManagerService) {
2211            mActivityManagerService = activityManagerService;
2212        }
2213
2214        @Override
2215        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2216            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2217                    != PackageManager.PERMISSION_GRANTED) {
2218                pw.println("Permission Denial: can't dump dbinfo from from pid="
2219                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2220                        + " without permission " + android.Manifest.permission.DUMP);
2221                return;
2222            }
2223
2224            mActivityManagerService.dumpDbInfo(fd, pw, args);
2225        }
2226    }
2227
2228    static class CpuBinder extends Binder {
2229        ActivityManagerService mActivityManagerService;
2230        CpuBinder(ActivityManagerService activityManagerService) {
2231            mActivityManagerService = activityManagerService;
2232        }
2233
2234        @Override
2235        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2236            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2237                    != PackageManager.PERMISSION_GRANTED) {
2238                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2239                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2240                        + " without permission " + android.Manifest.permission.DUMP);
2241                return;
2242            }
2243
2244            synchronized (mActivityManagerService.mProcessCpuTracker) {
2245                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2246                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2247                        SystemClock.uptimeMillis()));
2248            }
2249        }
2250    }
2251
2252    public static final class Lifecycle extends SystemService {
2253        private final ActivityManagerService mService;
2254
2255        public Lifecycle(Context context) {
2256            super(context);
2257            mService = new ActivityManagerService(context);
2258        }
2259
2260        @Override
2261        public void onStart() {
2262            mService.start();
2263        }
2264
2265        public ActivityManagerService getService() {
2266            return mService;
2267        }
2268    }
2269
2270    // Note: This method is invoked on the main thread but may need to attach various
2271    // handlers to other threads.  So take care to be explicit about the looper.
2272    public ActivityManagerService(Context systemContext) {
2273        mContext = systemContext;
2274        mFactoryTest = FactoryTest.getMode();
2275        mSystemThread = ActivityThread.currentActivityThread();
2276
2277        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2278
2279        mHandlerThread = new ServiceThread(TAG,
2280                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2281        mHandlerThread.start();
2282        mHandler = new MainHandler(mHandlerThread.getLooper());
2283        mUiHandler = new UiHandler();
2284
2285        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2286                "foreground", BROADCAST_FG_TIMEOUT, false);
2287        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2288                "background", BROADCAST_BG_TIMEOUT, true);
2289        mBroadcastQueues[0] = mFgBroadcastQueue;
2290        mBroadcastQueues[1] = mBgBroadcastQueue;
2291
2292        mServices = new ActiveServices(this);
2293        mProviderMap = new ProviderMap(this);
2294
2295        // TODO: Move creation of battery stats service outside of activity manager service.
2296        File dataDir = Environment.getDataDirectory();
2297        File systemDir = new File(dataDir, "system");
2298        systemDir.mkdirs();
2299        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2300        mBatteryStatsService.getActiveStatistics().readLocked();
2301        mBatteryStatsService.scheduleWriteToDisk();
2302        mOnBattery = DEBUG_POWER ? true
2303                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2304        mBatteryStatsService.getActiveStatistics().setCallback(this);
2305
2306        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2307
2308        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2309
2310        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2311
2312        // User 0 is the first and only user that runs at boot.
2313        mStartedUsers.put(UserHandle.USER_OWNER, new UserState(UserHandle.OWNER, true));
2314        mUserLru.add(UserHandle.USER_OWNER);
2315        updateStartedUserArrayLocked();
2316
2317        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2318            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2319
2320        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2321
2322        mConfiguration.setToDefaults();
2323        mConfiguration.setLocale(Locale.getDefault());
2324
2325        mConfigurationSeq = mConfiguration.seq = 1;
2326        mProcessCpuTracker.init();
2327
2328        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2329        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2330        mRecentTasks = new RecentTasks(this);
2331        mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
2332        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
2333
2334        mProcessCpuThread = new Thread("CpuTracker") {
2335            @Override
2336            public void run() {
2337                while (true) {
2338                    try {
2339                        try {
2340                            synchronized(this) {
2341                                final long now = SystemClock.uptimeMillis();
2342                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2343                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2344                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2345                                //        + ", write delay=" + nextWriteDelay);
2346                                if (nextWriteDelay < nextCpuDelay) {
2347                                    nextCpuDelay = nextWriteDelay;
2348                                }
2349                                if (nextCpuDelay > 0) {
2350                                    mProcessCpuMutexFree.set(true);
2351                                    this.wait(nextCpuDelay);
2352                                }
2353                            }
2354                        } catch (InterruptedException e) {
2355                        }
2356                        updateCpuStatsNow();
2357                    } catch (Exception e) {
2358                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2359                    }
2360                }
2361            }
2362        };
2363
2364        Watchdog.getInstance().addMonitor(this);
2365        Watchdog.getInstance().addThread(mHandler);
2366    }
2367
2368    public void setSystemServiceManager(SystemServiceManager mgr) {
2369        mSystemServiceManager = mgr;
2370    }
2371
2372    public void setInstaller(Installer installer) {
2373        mInstaller = installer;
2374    }
2375
2376    private void start() {
2377        Process.removeAllProcessGroups();
2378        mProcessCpuThread.start();
2379
2380        mBatteryStatsService.publish(mContext);
2381        mAppOpsService.publish(mContext);
2382        Slog.d("AppOps", "AppOpsService published");
2383        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2384    }
2385
2386    public void initPowerManagement() {
2387        mStackSupervisor.initPowerManagement();
2388        mBatteryStatsService.initPowerManagement();
2389        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2390        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2391        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2392        mVoiceWakeLock.setReferenceCounted(false);
2393    }
2394
2395    @Override
2396    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2397            throws RemoteException {
2398        if (code == SYSPROPS_TRANSACTION) {
2399            // We need to tell all apps about the system property change.
2400            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2401            synchronized(this) {
2402                final int NP = mProcessNames.getMap().size();
2403                for (int ip=0; ip<NP; ip++) {
2404                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2405                    final int NA = apps.size();
2406                    for (int ia=0; ia<NA; ia++) {
2407                        ProcessRecord app = apps.valueAt(ia);
2408                        if (app.thread != null) {
2409                            procs.add(app.thread.asBinder());
2410                        }
2411                    }
2412                }
2413            }
2414
2415            int N = procs.size();
2416            for (int i=0; i<N; i++) {
2417                Parcel data2 = Parcel.obtain();
2418                try {
2419                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2420                } catch (RemoteException e) {
2421                }
2422                data2.recycle();
2423            }
2424        }
2425        try {
2426            return super.onTransact(code, data, reply, flags);
2427        } catch (RuntimeException e) {
2428            // The activity manager only throws security exceptions, so let's
2429            // log all others.
2430            if (!(e instanceof SecurityException)) {
2431                Slog.wtf(TAG, "Activity Manager Crash", e);
2432            }
2433            throw e;
2434        }
2435    }
2436
2437    void updateCpuStats() {
2438        final long now = SystemClock.uptimeMillis();
2439        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2440            return;
2441        }
2442        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2443            synchronized (mProcessCpuThread) {
2444                mProcessCpuThread.notify();
2445            }
2446        }
2447    }
2448
2449    void updateCpuStatsNow() {
2450        synchronized (mProcessCpuTracker) {
2451            mProcessCpuMutexFree.set(false);
2452            final long now = SystemClock.uptimeMillis();
2453            boolean haveNewCpuStats = false;
2454
2455            if (MONITOR_CPU_USAGE &&
2456                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2457                mLastCpuTime.set(now);
2458                mProcessCpuTracker.update();
2459                if (mProcessCpuTracker.hasGoodLastStats()) {
2460                    haveNewCpuStats = true;
2461                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2462                    //Slog.i(TAG, "Total CPU usage: "
2463                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2464
2465                    // Slog the cpu usage if the property is set.
2466                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2467                        int user = mProcessCpuTracker.getLastUserTime();
2468                        int system = mProcessCpuTracker.getLastSystemTime();
2469                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2470                        int irq = mProcessCpuTracker.getLastIrqTime();
2471                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2472                        int idle = mProcessCpuTracker.getLastIdleTime();
2473
2474                        int total = user + system + iowait + irq + softIrq + idle;
2475                        if (total == 0) total = 1;
2476
2477                        EventLog.writeEvent(EventLogTags.CPU,
2478                                ((user+system+iowait+irq+softIrq) * 100) / total,
2479                                (user * 100) / total,
2480                                (system * 100) / total,
2481                                (iowait * 100) / total,
2482                                (irq * 100) / total,
2483                                (softIrq * 100) / total);
2484                    }
2485                }
2486            }
2487
2488            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2489            synchronized(bstats) {
2490                synchronized(mPidsSelfLocked) {
2491                    if (haveNewCpuStats) {
2492                        if (bstats.startAddingCpuLocked()) {
2493                            int totalUTime = 0;
2494                            int totalSTime = 0;
2495                            final int N = mProcessCpuTracker.countStats();
2496                            for (int i=0; i<N; i++) {
2497                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2498                                if (!st.working) {
2499                                    continue;
2500                                }
2501                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2502                                totalUTime += st.rel_utime;
2503                                totalSTime += st.rel_stime;
2504                                if (pr != null) {
2505                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2506                                    if (ps == null || !ps.isActive()) {
2507                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2508                                                pr.info.uid, pr.processName);
2509                                    }
2510                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2511                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2512                                } else {
2513                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2514                                    if (ps == null || !ps.isActive()) {
2515                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2516                                                bstats.mapUid(st.uid), st.name);
2517                                    }
2518                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2519                                }
2520                            }
2521                            final int userTime = mProcessCpuTracker.getLastUserTime();
2522                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2523                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2524                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2525                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2526                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2527                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2528                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2529                        }
2530                    }
2531                }
2532
2533                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2534                    mLastWriteTime = now;
2535                    mBatteryStatsService.scheduleWriteToDisk();
2536                }
2537            }
2538        }
2539    }
2540
2541    @Override
2542    public void batteryNeedsCpuUpdate() {
2543        updateCpuStatsNow();
2544    }
2545
2546    @Override
2547    public void batteryPowerChanged(boolean onBattery) {
2548        // When plugging in, update the CPU stats first before changing
2549        // the plug state.
2550        updateCpuStatsNow();
2551        synchronized (this) {
2552            synchronized(mPidsSelfLocked) {
2553                mOnBattery = DEBUG_POWER ? true : onBattery;
2554            }
2555        }
2556    }
2557
2558    @Override
2559    public void batterySendBroadcast(Intent intent) {
2560        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2561                AppOpsManager.OP_NONE, null, false, false,
2562                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2563    }
2564
2565    /**
2566     * Initialize the application bind args. These are passed to each
2567     * process when the bindApplication() IPC is sent to the process. They're
2568     * lazily setup to make sure the services are running when they're asked for.
2569     */
2570    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2571        if (mAppBindArgs == null) {
2572            mAppBindArgs = new HashMap<>();
2573
2574            // Isolated processes won't get this optimization, so that we don't
2575            // violate the rules about which services they have access to.
2576            if (!isolated) {
2577                // Setup the application init args
2578                mAppBindArgs.put("package", ServiceManager.getService("package"));
2579                mAppBindArgs.put("window", ServiceManager.getService("window"));
2580                mAppBindArgs.put(Context.ALARM_SERVICE,
2581                        ServiceManager.getService(Context.ALARM_SERVICE));
2582            }
2583        }
2584        return mAppBindArgs;
2585    }
2586
2587    final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2588        if (r != null && mFocusedActivity != r) {
2589            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2590            ActivityRecord last = mFocusedActivity;
2591            mFocusedActivity = r;
2592            if (r.task.taskType != ActivityRecord.HOME_ACTIVITY_TYPE
2593                    && r.task.taskType != ActivityRecord.RECENTS_ACTIVITY_TYPE) {
2594                if (mCurAppTimeTracker != r.appTimeTracker) {
2595                    // We are switching app tracking.  Complete the current one.
2596                    if (mCurAppTimeTracker != null) {
2597                        mCurAppTimeTracker.stop();
2598                        mHandler.obtainMessage(REPORT_TIME_TRACKER_MSG,
2599                                mCurAppTimeTracker).sendToTarget();
2600                        mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2601                        mCurAppTimeTracker = null;
2602                    }
2603                    if (r.appTimeTracker != null) {
2604                        mCurAppTimeTracker = r.appTimeTracker;
2605                        startTimeTrackingFocusedActivityLocked();
2606                    }
2607                } else {
2608                    startTimeTrackingFocusedActivityLocked();
2609                }
2610            } else {
2611                r.appTimeTracker = null;
2612            }
2613            if (r.task != null && r.task.voiceInteractor != null) {
2614                startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2615            } else {
2616                finishRunningVoiceLocked();
2617                if (last != null && last.task.voiceSession != null) {
2618                    // We had been in a voice interaction session, but now focused has
2619                    // move to something different.  Just finish the session, we can't
2620                    // return to it and retain the proper state and synchronization with
2621                    // the voice interaction service.
2622                    finishVoiceTask(last.task.voiceSession);
2623                }
2624            }
2625            if (mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
2626                mWindowManager.setFocusedApp(r.appToken, true);
2627            }
2628            applyUpdateLockStateLocked(r);
2629            if (mFocusedActivity.userId != mLastFocusedUserId) {
2630                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2631                mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2632                        mFocusedActivity.userId, 0));
2633                mLastFocusedUserId = mFocusedActivity.userId;
2634            }
2635        }
2636        EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY,
2637                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2638                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2639    }
2640
2641    final void clearFocusedActivity(ActivityRecord r) {
2642        if (mFocusedActivity == r) {
2643            ActivityStack stack = mStackSupervisor.getFocusedStack();
2644            if (stack != null) {
2645                ActivityRecord top = stack.topActivity();
2646                if (top != null && top.userId != mLastFocusedUserId) {
2647                    mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2648                    mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2649                                    top.userId, 0));
2650                    mLastFocusedUserId = top.userId;
2651                }
2652            }
2653            mFocusedActivity = null;
2654            EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, -1, "NULL");
2655        }
2656    }
2657
2658    @Override
2659    public void setFocusedStack(int stackId) {
2660        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2661        synchronized (ActivityManagerService.this) {
2662            ActivityStack stack = mStackSupervisor.getStack(stackId);
2663            if (stack != null) {
2664                ActivityRecord r = stack.topRunningActivityLocked(null);
2665                if (r != null) {
2666                    setFocusedActivityLocked(r, "setFocusedStack");
2667                    mStackSupervisor.resumeTopActivitiesLocked(stack, null, null);
2668                }
2669            }
2670        }
2671    }
2672
2673    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2674    @Override
2675    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2676        synchronized (ActivityManagerService.this) {
2677            if (listener != null) {
2678                mTaskStackListeners.register(listener);
2679            }
2680        }
2681    }
2682
2683    @Override
2684    public void notifyActivityDrawn(IBinder token) {
2685        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2686        synchronized (this) {
2687            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2688            if (r != null) {
2689                r.task.stack.notifyActivityDrawnLocked(r);
2690            }
2691        }
2692    }
2693
2694    final void applyUpdateLockStateLocked(ActivityRecord r) {
2695        // Modifications to the UpdateLock state are done on our handler, outside
2696        // the activity manager's locks.  The new state is determined based on the
2697        // state *now* of the relevant activity record.  The object is passed to
2698        // the handler solely for logging detail, not to be consulted/modified.
2699        final boolean nextState = r != null && r.immersive;
2700        mHandler.sendMessage(
2701                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2702    }
2703
2704    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2705        Message msg = Message.obtain();
2706        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2707        msg.obj = r.task.askedCompatMode ? null : r;
2708        mUiHandler.sendMessage(msg);
2709    }
2710
2711    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2712            String what, Object obj, ProcessRecord srcApp) {
2713        app.lastActivityTime = now;
2714
2715        if (app.activities.size() > 0) {
2716            // Don't want to touch dependent processes that are hosting activities.
2717            return index;
2718        }
2719
2720        int lrui = mLruProcesses.lastIndexOf(app);
2721        if (lrui < 0) {
2722            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2723                    + what + " " + obj + " from " + srcApp);
2724            return index;
2725        }
2726
2727        if (lrui >= index) {
2728            // Don't want to cause this to move dependent processes *back* in the
2729            // list as if they were less frequently used.
2730            return index;
2731        }
2732
2733        if (lrui >= mLruProcessActivityStart) {
2734            // Don't want to touch dependent processes that are hosting activities.
2735            return index;
2736        }
2737
2738        mLruProcesses.remove(lrui);
2739        if (index > 0) {
2740            index--;
2741        }
2742        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2743                + " in LRU list: " + app);
2744        mLruProcesses.add(index, app);
2745        return index;
2746    }
2747
2748    private static void killProcessGroup(int uid, int pid) {
2749        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
2750        Process.killProcessGroup(uid, pid);
2751        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2752    }
2753
2754    final void removeLruProcessLocked(ProcessRecord app) {
2755        int lrui = mLruProcesses.lastIndexOf(app);
2756        if (lrui >= 0) {
2757            if (!app.killed) {
2758                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2759                Process.killProcessQuiet(app.pid);
2760                killProcessGroup(app.info.uid, app.pid);
2761            }
2762            if (lrui <= mLruProcessActivityStart) {
2763                mLruProcessActivityStart--;
2764            }
2765            if (lrui <= mLruProcessServiceStart) {
2766                mLruProcessServiceStart--;
2767            }
2768            mLruProcesses.remove(lrui);
2769        }
2770    }
2771
2772    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2773            ProcessRecord client) {
2774        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2775                || app.treatLikeActivity;
2776        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2777        if (!activityChange && hasActivity) {
2778            // The process has activities, so we are only allowing activity-based adjustments
2779            // to move it.  It should be kept in the front of the list with other
2780            // processes that have activities, and we don't want those to change their
2781            // order except due to activity operations.
2782            return;
2783        }
2784
2785        mLruSeq++;
2786        final long now = SystemClock.uptimeMillis();
2787        app.lastActivityTime = now;
2788
2789        // First a quick reject: if the app is already at the position we will
2790        // put it, then there is nothing to do.
2791        if (hasActivity) {
2792            final int N = mLruProcesses.size();
2793            if (N > 0 && mLruProcesses.get(N-1) == app) {
2794                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
2795                return;
2796            }
2797        } else {
2798            if (mLruProcessServiceStart > 0
2799                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2800                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
2801                return;
2802            }
2803        }
2804
2805        int lrui = mLruProcesses.lastIndexOf(app);
2806
2807        if (app.persistent && lrui >= 0) {
2808            // We don't care about the position of persistent processes, as long as
2809            // they are in the list.
2810            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
2811            return;
2812        }
2813
2814        /* In progress: compute new position first, so we can avoid doing work
2815           if the process is not actually going to move.  Not yet working.
2816        int addIndex;
2817        int nextIndex;
2818        boolean inActivity = false, inService = false;
2819        if (hasActivity) {
2820            // Process has activities, put it at the very tipsy-top.
2821            addIndex = mLruProcesses.size();
2822            nextIndex = mLruProcessServiceStart;
2823            inActivity = true;
2824        } else if (hasService) {
2825            // Process has services, put it at the top of the service list.
2826            addIndex = mLruProcessActivityStart;
2827            nextIndex = mLruProcessServiceStart;
2828            inActivity = true;
2829            inService = true;
2830        } else  {
2831            // Process not otherwise of interest, it goes to the top of the non-service area.
2832            addIndex = mLruProcessServiceStart;
2833            if (client != null) {
2834                int clientIndex = mLruProcesses.lastIndexOf(client);
2835                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2836                        + app);
2837                if (clientIndex >= 0 && addIndex > clientIndex) {
2838                    addIndex = clientIndex;
2839                }
2840            }
2841            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2842        }
2843
2844        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2845                + mLruProcessActivityStart + "): " + app);
2846        */
2847
2848        if (lrui >= 0) {
2849            if (lrui < mLruProcessActivityStart) {
2850                mLruProcessActivityStart--;
2851            }
2852            if (lrui < mLruProcessServiceStart) {
2853                mLruProcessServiceStart--;
2854            }
2855            /*
2856            if (addIndex > lrui) {
2857                addIndex--;
2858            }
2859            if (nextIndex > lrui) {
2860                nextIndex--;
2861            }
2862            */
2863            mLruProcesses.remove(lrui);
2864        }
2865
2866        /*
2867        mLruProcesses.add(addIndex, app);
2868        if (inActivity) {
2869            mLruProcessActivityStart++;
2870        }
2871        if (inService) {
2872            mLruProcessActivityStart++;
2873        }
2874        */
2875
2876        int nextIndex;
2877        if (hasActivity) {
2878            final int N = mLruProcesses.size();
2879            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
2880                // Process doesn't have activities, but has clients with
2881                // activities...  move it up, but one below the top (the top
2882                // should always have a real activity).
2883                if (DEBUG_LRU) Slog.d(TAG_LRU,
2884                        "Adding to second-top of LRU activity list: " + app);
2885                mLruProcesses.add(N - 1, app);
2886                // To keep it from spamming the LRU list (by making a bunch of clients),
2887                // we will push down any other entries owned by the app.
2888                final int uid = app.info.uid;
2889                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
2890                    ProcessRecord subProc = mLruProcesses.get(i);
2891                    if (subProc.info.uid == uid) {
2892                        // We want to push this one down the list.  If the process after
2893                        // it is for the same uid, however, don't do so, because we don't
2894                        // want them internally to be re-ordered.
2895                        if (mLruProcesses.get(i - 1).info.uid != uid) {
2896                            if (DEBUG_LRU) Slog.d(TAG_LRU,
2897                                    "Pushing uid " + uid + " swapping at " + i + ": "
2898                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
2899                            ProcessRecord tmp = mLruProcesses.get(i);
2900                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
2901                            mLruProcesses.set(i - 1, tmp);
2902                            i--;
2903                        }
2904                    } else {
2905                        // A gap, we can stop here.
2906                        break;
2907                    }
2908                }
2909            } else {
2910                // Process has activities, put it at the very tipsy-top.
2911                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
2912                mLruProcesses.add(app);
2913            }
2914            nextIndex = mLruProcessServiceStart;
2915        } else if (hasService) {
2916            // Process has services, put it at the top of the service list.
2917            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
2918            mLruProcesses.add(mLruProcessActivityStart, app);
2919            nextIndex = mLruProcessServiceStart;
2920            mLruProcessActivityStart++;
2921        } else  {
2922            // Process not otherwise of interest, it goes to the top of the non-service area.
2923            int index = mLruProcessServiceStart;
2924            if (client != null) {
2925                // If there is a client, don't allow the process to be moved up higher
2926                // in the list than that client.
2927                int clientIndex = mLruProcesses.lastIndexOf(client);
2928                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
2929                        + " when updating " + app);
2930                if (clientIndex <= lrui) {
2931                    // Don't allow the client index restriction to push it down farther in the
2932                    // list than it already is.
2933                    clientIndex = lrui;
2934                }
2935                if (clientIndex >= 0 && index > clientIndex) {
2936                    index = clientIndex;
2937                }
2938            }
2939            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
2940            mLruProcesses.add(index, app);
2941            nextIndex = index-1;
2942            mLruProcessActivityStart++;
2943            mLruProcessServiceStart++;
2944        }
2945
2946        // If the app is currently using a content provider or service,
2947        // bump those processes as well.
2948        for (int j=app.connections.size()-1; j>=0; j--) {
2949            ConnectionRecord cr = app.connections.valueAt(j);
2950            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2951                    && cr.binding.service.app != null
2952                    && cr.binding.service.app.lruSeq != mLruSeq
2953                    && !cr.binding.service.app.persistent) {
2954                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2955                        "service connection", cr, app);
2956            }
2957        }
2958        for (int j=app.conProviders.size()-1; j>=0; j--) {
2959            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2960            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2961                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2962                        "provider reference", cpr, app);
2963            }
2964        }
2965    }
2966
2967    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2968        if (uid == Process.SYSTEM_UID) {
2969            // The system gets to run in any process.  If there are multiple
2970            // processes with the same uid, just pick the first (this
2971            // should never happen).
2972            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2973            if (procs == null) return null;
2974            final int procCount = procs.size();
2975            for (int i = 0; i < procCount; i++) {
2976                final int procUid = procs.keyAt(i);
2977                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
2978                    // Don't use an app process or different user process for system component.
2979                    continue;
2980                }
2981                return procs.valueAt(i);
2982            }
2983        }
2984        ProcessRecord proc = mProcessNames.get(processName, uid);
2985        if (false && proc != null && !keepIfLarge
2986                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2987                && proc.lastCachedPss >= 4000) {
2988            // Turn this condition on to cause killing to happen regularly, for testing.
2989            if (proc.baseProcessTracker != null) {
2990                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2991            }
2992            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2993        } else if (proc != null && !keepIfLarge
2994                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2995                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2996            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2997            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2998                if (proc.baseProcessTracker != null) {
2999                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3000                }
3001                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3002            }
3003        }
3004        return proc;
3005    }
3006
3007    void ensurePackageDexOpt(String packageName) {
3008        IPackageManager pm = AppGlobals.getPackageManager();
3009        try {
3010            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
3011                mDidDexOpt = true;
3012            }
3013        } catch (RemoteException e) {
3014        }
3015    }
3016
3017    boolean isNextTransitionForward() {
3018        int transit = mWindowManager.getPendingAppTransition();
3019        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
3020                || transit == AppTransition.TRANSIT_TASK_OPEN
3021                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
3022    }
3023
3024    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3025            String processName, String abiOverride, int uid, Runnable crashHandler) {
3026        synchronized(this) {
3027            ApplicationInfo info = new ApplicationInfo();
3028            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3029            // For isolated processes, the former contains the parent's uid and the latter the
3030            // actual uid of the isolated process.
3031            // In the special case introduced by this method (which is, starting an isolated
3032            // process directly from the SystemServer without an actual parent app process) the
3033            // closest thing to a parent's uid is SYSTEM_UID.
3034            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3035            // the |isolated| logic in the ProcessRecord constructor.
3036            info.uid = Process.SYSTEM_UID;
3037            info.processName = processName;
3038            info.className = entryPoint;
3039            info.packageName = "android";
3040            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3041                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3042                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3043                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3044                    crashHandler);
3045            return proc != null ? proc.pid : 0;
3046        }
3047    }
3048
3049    final ProcessRecord startProcessLocked(String processName,
3050            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3051            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3052            boolean isolated, boolean keepIfLarge) {
3053        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3054                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3055                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3056                null /* crashHandler */);
3057    }
3058
3059    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3060            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3061            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3062            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3063        long startTime = SystemClock.elapsedRealtime();
3064        ProcessRecord app;
3065        if (!isolated) {
3066            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3067            checkTime(startTime, "startProcess: after getProcessRecord");
3068
3069            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3070                // If we are in the background, then check to see if this process
3071                // is bad.  If so, we will just silently fail.
3072                if (mBadProcesses.get(info.processName, info.uid) != null) {
3073                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3074                            + "/" + info.processName);
3075                    return null;
3076                }
3077            } else {
3078                // When the user is explicitly starting a process, then clear its
3079                // crash count so that we won't make it bad until they see at
3080                // least one crash dialog again, and make the process good again
3081                // if it had been bad.
3082                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3083                        + "/" + info.processName);
3084                mProcessCrashTimes.remove(info.processName, info.uid);
3085                if (mBadProcesses.get(info.processName, info.uid) != null) {
3086                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3087                            UserHandle.getUserId(info.uid), info.uid,
3088                            info.processName);
3089                    mBadProcesses.remove(info.processName, info.uid);
3090                    if (app != null) {
3091                        app.bad = false;
3092                    }
3093                }
3094            }
3095        } else {
3096            // If this is an isolated process, it can't re-use an existing process.
3097            app = null;
3098        }
3099
3100        // We don't have to do anything more if:
3101        // (1) There is an existing application record; and
3102        // (2) The caller doesn't think it is dead, OR there is no thread
3103        //     object attached to it so we know it couldn't have crashed; and
3104        // (3) There is a pid assigned to it, so it is either starting or
3105        //     already running.
3106        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3107                + " app=" + app + " knownToBeDead=" + knownToBeDead
3108                + " thread=" + (app != null ? app.thread : null)
3109                + " pid=" + (app != null ? app.pid : -1));
3110        if (app != null && app.pid > 0) {
3111            if (!knownToBeDead || app.thread == null) {
3112                // We already have the app running, or are waiting for it to
3113                // come up (we have a pid but not yet its thread), so keep it.
3114                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3115                // If this is a new package in the process, add the package to the list
3116                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3117                checkTime(startTime, "startProcess: done, added package to proc");
3118                return app;
3119            }
3120
3121            // An application record is attached to a previous process,
3122            // clean it up now.
3123            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3124            checkTime(startTime, "startProcess: bad proc running, killing");
3125            killProcessGroup(app.info.uid, app.pid);
3126            handleAppDiedLocked(app, true, true);
3127            checkTime(startTime, "startProcess: done killing old proc");
3128        }
3129
3130        String hostingNameStr = hostingName != null
3131                ? hostingName.flattenToShortString() : null;
3132
3133        if (app == null) {
3134            checkTime(startTime, "startProcess: creating new process record");
3135            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3136            if (app == null) {
3137                Slog.w(TAG, "Failed making new process record for "
3138                        + processName + "/" + info.uid + " isolated=" + isolated);
3139                return null;
3140            }
3141            app.crashHandler = crashHandler;
3142            checkTime(startTime, "startProcess: done creating new process record");
3143        } else {
3144            // If this is a new package in the process, add the package to the list
3145            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3146            checkTime(startTime, "startProcess: added package to existing proc");
3147        }
3148
3149        // If the system is not ready yet, then hold off on starting this
3150        // process until it is.
3151        if (!mProcessesReady
3152                && !isAllowedWhileBooting(info)
3153                && !allowWhileBooting) {
3154            if (!mProcessesOnHold.contains(app)) {
3155                mProcessesOnHold.add(app);
3156            }
3157            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3158                    "System not ready, putting on hold: " + app);
3159            checkTime(startTime, "startProcess: returning with proc on hold");
3160            return app;
3161        }
3162
3163        checkTime(startTime, "startProcess: stepping in to startProcess");
3164        startProcessLocked(
3165                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3166        checkTime(startTime, "startProcess: done starting proc!");
3167        return (app.pid != 0) ? app : null;
3168    }
3169
3170    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3171        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3172    }
3173
3174    private final void startProcessLocked(ProcessRecord app,
3175            String hostingType, String hostingNameStr) {
3176        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3177                null /* entryPoint */, null /* entryPointArgs */);
3178    }
3179
3180    private final void startProcessLocked(ProcessRecord app, String hostingType,
3181            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3182        long startTime = SystemClock.elapsedRealtime();
3183        if (app.pid > 0 && app.pid != MY_PID) {
3184            checkTime(startTime, "startProcess: removing from pids map");
3185            synchronized (mPidsSelfLocked) {
3186                mPidsSelfLocked.remove(app.pid);
3187                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3188            }
3189            checkTime(startTime, "startProcess: done removing from pids map");
3190            app.setPid(0);
3191        }
3192
3193        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3194                "startProcessLocked removing on hold: " + app);
3195        mProcessesOnHold.remove(app);
3196
3197        checkTime(startTime, "startProcess: starting to update cpu stats");
3198        updateCpuStats();
3199        checkTime(startTime, "startProcess: done updating cpu stats");
3200
3201        try {
3202            try {
3203                if (AppGlobals.getPackageManager().isPackageFrozen(app.info.packageName)) {
3204                    // This is caught below as if we had failed to fork zygote
3205                    throw new RuntimeException("Package " + app.info.packageName + " is frozen!");
3206                }
3207            } catch (RemoteException e) {
3208                throw e.rethrowAsRuntimeException();
3209            }
3210
3211            int uid = app.uid;
3212            int[] gids = null;
3213            int mountExternal = Zygote.MOUNT_EXTERNAL_DEFAULT;
3214            if (!app.isolated) {
3215                int[] permGids = null;
3216                try {
3217                    checkTime(startTime, "startProcess: getting gids from package manager");
3218                    permGids = AppGlobals.getPackageManager().getPackageGids(app.info.packageName,
3219                            app.userId);
3220                } catch (RemoteException e) {
3221                    throw e.rethrowAsRuntimeException();
3222                }
3223
3224                /*
3225                 * Add shared application and profile GIDs so applications can share some
3226                 * resources like shared libraries and access user-wide resources
3227                 */
3228                if (ArrayUtils.isEmpty(permGids)) {
3229                    gids = new int[2];
3230                } else {
3231                    gids = new int[permGids.length + 2];
3232                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3233                }
3234                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3235                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3236            }
3237            checkTime(startTime, "startProcess: building args");
3238            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3239                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3240                        && mTopComponent != null
3241                        && app.processName.equals(mTopComponent.getPackageName())) {
3242                    uid = 0;
3243                }
3244                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3245                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3246                    uid = 0;
3247                }
3248            }
3249            int debugFlags = 0;
3250            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3251                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3252                // Also turn on CheckJNI for debuggable apps. It's quite
3253                // awkward to turn on otherwise.
3254                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3255            }
3256            // Run the app in safe mode if its manifest requests so or the
3257            // system is booted in safe mode.
3258            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3259                mSafeMode == true) {
3260                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3261            }
3262            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3263                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3264            }
3265            String jitDebugProperty = SystemProperties.get("debug.usejit");
3266            if ("true".equals(jitDebugProperty)) {
3267                debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3268            } else if (!"false".equals(jitDebugProperty)) {
3269                // If we didn't force disable by setting false, defer to the dalvik vm options.
3270                if ("true".equals(SystemProperties.get("dalvik.vm.usejit"))) {
3271                    debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3272                }
3273            }
3274            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3275            if ("true".equals(genDebugInfoProperty)) {
3276                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3277            }
3278            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3279                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3280            }
3281            if ("1".equals(SystemProperties.get("debug.assert"))) {
3282                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3283            }
3284
3285            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3286            if (requiredAbi == null) {
3287                requiredAbi = Build.SUPPORTED_ABIS[0];
3288            }
3289
3290            String instructionSet = null;
3291            if (app.info.primaryCpuAbi != null) {
3292                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3293            }
3294
3295            app.gids = gids;
3296            app.requiredAbi = requiredAbi;
3297            app.instructionSet = instructionSet;
3298
3299            // Start the process.  It will either succeed and return a result containing
3300            // the PID of the new process, or else throw a RuntimeException.
3301            boolean isActivityProcess = (entryPoint == null);
3302            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3303            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3304                    app.processName);
3305            checkTime(startTime, "startProcess: asking zygote to start proc");
3306            Process.ProcessStartResult startResult = Process.start(entryPoint,
3307                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3308                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3309                    app.info.dataDir, entryPointArgs);
3310            checkTime(startTime, "startProcess: returned from zygote!");
3311            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3312
3313            if (app.isolated) {
3314                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3315            }
3316            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3317            checkTime(startTime, "startProcess: done updating battery stats");
3318
3319            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3320                    UserHandle.getUserId(uid), startResult.pid, uid,
3321                    app.processName, hostingType,
3322                    hostingNameStr != null ? hostingNameStr : "");
3323
3324            if (app.persistent) {
3325                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3326            }
3327
3328            checkTime(startTime, "startProcess: building log message");
3329            StringBuilder buf = mStringBuilder;
3330            buf.setLength(0);
3331            buf.append("Start proc ");
3332            buf.append(startResult.pid);
3333            buf.append(':');
3334            buf.append(app.processName);
3335            buf.append('/');
3336            UserHandle.formatUid(buf, uid);
3337            if (!isActivityProcess) {
3338                buf.append(" [");
3339                buf.append(entryPoint);
3340                buf.append("]");
3341            }
3342            buf.append(" for ");
3343            buf.append(hostingType);
3344            if (hostingNameStr != null) {
3345                buf.append(" ");
3346                buf.append(hostingNameStr);
3347            }
3348            Slog.i(TAG, buf.toString());
3349            app.setPid(startResult.pid);
3350            app.usingWrapper = startResult.usingWrapper;
3351            app.removed = false;
3352            app.killed = false;
3353            app.killedByAm = false;
3354            checkTime(startTime, "startProcess: starting to update pids map");
3355            synchronized (mPidsSelfLocked) {
3356                this.mPidsSelfLocked.put(startResult.pid, app);
3357                if (isActivityProcess) {
3358                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3359                    msg.obj = app;
3360                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3361                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3362                }
3363            }
3364            checkTime(startTime, "startProcess: done updating pids map");
3365        } catch (RuntimeException e) {
3366            // XXX do better error recovery.
3367            app.setPid(0);
3368            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3369            if (app.isolated) {
3370                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3371            }
3372            Slog.e(TAG, "Failure starting process " + app.processName, e);
3373        }
3374    }
3375
3376    void updateUsageStats(ActivityRecord component, boolean resumed) {
3377        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3378                "updateUsageStats: comp=" + component + "res=" + resumed);
3379        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3380        if (resumed) {
3381            if (mUsageStatsService != null) {
3382                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3383                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3384            }
3385            synchronized (stats) {
3386                stats.noteActivityResumedLocked(component.app.uid);
3387            }
3388        } else {
3389            if (mUsageStatsService != null) {
3390                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3391                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3392            }
3393            synchronized (stats) {
3394                stats.noteActivityPausedLocked(component.app.uid);
3395            }
3396        }
3397    }
3398
3399    Intent getHomeIntent() {
3400        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3401        intent.setComponent(mTopComponent);
3402        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3403            intent.addCategory(Intent.CATEGORY_HOME);
3404        }
3405        return intent;
3406    }
3407
3408    boolean startHomeActivityLocked(int userId, String reason) {
3409        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3410                && mTopAction == null) {
3411            // We are running in factory test mode, but unable to find
3412            // the factory test app, so just sit around displaying the
3413            // error message and don't try to start anything.
3414            return false;
3415        }
3416        Intent intent = getHomeIntent();
3417        ActivityInfo aInfo =
3418            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3419        if (aInfo != null) {
3420            intent.setComponent(new ComponentName(
3421                    aInfo.applicationInfo.packageName, aInfo.name));
3422            // Don't do this if the home app is currently being
3423            // instrumented.
3424            aInfo = new ActivityInfo(aInfo);
3425            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3426            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3427                    aInfo.applicationInfo.uid, true);
3428            if (app == null || app.instrumentationClass == null) {
3429                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3430                mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3431            }
3432        }
3433
3434        return true;
3435    }
3436
3437    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3438        ActivityInfo ai = null;
3439        ComponentName comp = intent.getComponent();
3440        try {
3441            if (comp != null) {
3442                // Factory test.
3443                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3444            } else {
3445                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3446                        intent,
3447                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3448                        flags, userId);
3449
3450                if (info != null) {
3451                    ai = info.activityInfo;
3452                }
3453            }
3454        } catch (RemoteException e) {
3455            // ignore
3456        }
3457
3458        return ai;
3459    }
3460
3461    /**
3462     * Starts the "new version setup screen" if appropriate.
3463     */
3464    void startSetupActivityLocked() {
3465        // Only do this once per boot.
3466        if (mCheckedForSetup) {
3467            return;
3468        }
3469
3470        // We will show this screen if the current one is a different
3471        // version than the last one shown, and we are not running in
3472        // low-level factory test mode.
3473        final ContentResolver resolver = mContext.getContentResolver();
3474        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3475                Settings.Global.getInt(resolver,
3476                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3477            mCheckedForSetup = true;
3478
3479            // See if we should be showing the platform update setup UI.
3480            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3481            List<ResolveInfo> ris = mContext.getPackageManager()
3482                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3483
3484            // We don't allow third party apps to replace this.
3485            ResolveInfo ri = null;
3486            for (int i=0; ris != null && i<ris.size(); i++) {
3487                if ((ris.get(i).activityInfo.applicationInfo.flags
3488                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3489                    ri = ris.get(i);
3490                    break;
3491                }
3492            }
3493
3494            if (ri != null) {
3495                String vers = ri.activityInfo.metaData != null
3496                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3497                        : null;
3498                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3499                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3500                            Intent.METADATA_SETUP_VERSION);
3501                }
3502                String lastVers = Settings.Secure.getString(
3503                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3504                if (vers != null && !vers.equals(lastVers)) {
3505                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3506                    intent.setComponent(new ComponentName(
3507                            ri.activityInfo.packageName, ri.activityInfo.name));
3508                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3509                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3510                            null);
3511                }
3512            }
3513        }
3514    }
3515
3516    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3517        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3518    }
3519
3520    void enforceNotIsolatedCaller(String caller) {
3521        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3522            throw new SecurityException("Isolated process not allowed to call " + caller);
3523        }
3524    }
3525
3526    void enforceShellRestriction(String restriction, int userHandle) {
3527        if (Binder.getCallingUid() == Process.SHELL_UID) {
3528            if (userHandle < 0
3529                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3530                throw new SecurityException("Shell does not have permission to access user "
3531                        + userHandle);
3532            }
3533        }
3534    }
3535
3536    @Override
3537    public int getFrontActivityScreenCompatMode() {
3538        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3539        synchronized (this) {
3540            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3541        }
3542    }
3543
3544    @Override
3545    public void setFrontActivityScreenCompatMode(int mode) {
3546        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3547                "setFrontActivityScreenCompatMode");
3548        synchronized (this) {
3549            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3550        }
3551    }
3552
3553    @Override
3554    public int getPackageScreenCompatMode(String packageName) {
3555        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3556        synchronized (this) {
3557            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3558        }
3559    }
3560
3561    @Override
3562    public void setPackageScreenCompatMode(String packageName, int mode) {
3563        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3564                "setPackageScreenCompatMode");
3565        synchronized (this) {
3566            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3567        }
3568    }
3569
3570    @Override
3571    public boolean getPackageAskScreenCompat(String packageName) {
3572        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3573        synchronized (this) {
3574            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3575        }
3576    }
3577
3578    @Override
3579    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3580        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3581                "setPackageAskScreenCompat");
3582        synchronized (this) {
3583            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3584        }
3585    }
3586
3587    private boolean hasUsageStatsPermission(String callingPackage) {
3588        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3589                Binder.getCallingUid(), callingPackage);
3590        if (mode == AppOpsManager.MODE_DEFAULT) {
3591            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3592                    == PackageManager.PERMISSION_GRANTED;
3593        }
3594        return mode == AppOpsManager.MODE_ALLOWED;
3595    }
3596
3597    @Override
3598    public int getPackageProcessState(String packageName, String callingPackage) {
3599        if (!hasUsageStatsPermission(callingPackage)) {
3600            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3601                    "getPackageProcessState");
3602        }
3603
3604        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3605        synchronized (this) {
3606            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3607                final ProcessRecord proc = mLruProcesses.get(i);
3608                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3609                        || procState > proc.setProcState) {
3610                    boolean found = false;
3611                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3612                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3613                            procState = proc.setProcState;
3614                            found = true;
3615                        }
3616                    }
3617                    if (proc.pkgDeps != null && !found) {
3618                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3619                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3620                                procState = proc.setProcState;
3621                                break;
3622                            }
3623                        }
3624                    }
3625                }
3626            }
3627        }
3628        return procState;
3629    }
3630
3631    @Override
3632    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3633        synchronized (this) {
3634            final ProcessRecord app = getProcessRecordLocked(process, userId, true);
3635            if (app == null) {
3636                return false;
3637            }
3638            if (app.trimMemoryLevel < level && app.thread != null &&
3639                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3640                            app.trimMemoryLevel >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN)) {
3641                try {
3642                    app.thread.scheduleTrimMemory(level);
3643                    app.trimMemoryLevel = level;
3644                    return true;
3645                } catch (RemoteException e) {
3646                    // Fallthrough to failure case.
3647                }
3648            }
3649        }
3650        return false;
3651    }
3652
3653    private void dispatchProcessesChanged() {
3654        int N;
3655        synchronized (this) {
3656            N = mPendingProcessChanges.size();
3657            if (mActiveProcessChanges.length < N) {
3658                mActiveProcessChanges = new ProcessChangeItem[N];
3659            }
3660            mPendingProcessChanges.toArray(mActiveProcessChanges);
3661            mPendingProcessChanges.clear();
3662            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3663                    "*** Delivering " + N + " process changes");
3664        }
3665
3666        int i = mProcessObservers.beginBroadcast();
3667        while (i > 0) {
3668            i--;
3669            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3670            if (observer != null) {
3671                try {
3672                    for (int j=0; j<N; j++) {
3673                        ProcessChangeItem item = mActiveProcessChanges[j];
3674                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3675                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3676                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3677                                    + item.uid + ": " + item.foregroundActivities);
3678                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3679                                    item.foregroundActivities);
3680                        }
3681                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3682                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3683                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3684                                    + ": " + item.processState);
3685                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3686                        }
3687                    }
3688                } catch (RemoteException e) {
3689                }
3690            }
3691        }
3692        mProcessObservers.finishBroadcast();
3693
3694        synchronized (this) {
3695            for (int j=0; j<N; j++) {
3696                mAvailProcessChanges.add(mActiveProcessChanges[j]);
3697            }
3698        }
3699    }
3700
3701    private void dispatchProcessDied(int pid, int uid) {
3702        int i = mProcessObservers.beginBroadcast();
3703        while (i > 0) {
3704            i--;
3705            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3706            if (observer != null) {
3707                try {
3708                    observer.onProcessDied(pid, uid);
3709                } catch (RemoteException e) {
3710                }
3711            }
3712        }
3713        mProcessObservers.finishBroadcast();
3714    }
3715
3716    private void dispatchUidsChanged() {
3717        int N;
3718        synchronized (this) {
3719            N = mPendingUidChanges.size();
3720            if (mActiveUidChanges.length < N) {
3721                mActiveUidChanges = new UidRecord.ChangeItem[N];
3722            }
3723            for (int i=0; i<N; i++) {
3724                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3725                mActiveUidChanges[i] = change;
3726                change.uidRecord.pendingChange = null;
3727                change.uidRecord = null;
3728            }
3729            mPendingUidChanges.clear();
3730            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3731                    "*** Delivering " + N + " uid changes");
3732        }
3733
3734        if (mLocalPowerManager != null) {
3735            for (int j=0; j<N; j++) {
3736                UidRecord.ChangeItem item = mActiveUidChanges[j];
3737                if (item.gone) {
3738                    mLocalPowerManager.uidGone(item.uid);
3739                } else {
3740                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
3741                }
3742            }
3743        }
3744
3745        int i = mUidObservers.beginBroadcast();
3746        while (i > 0) {
3747            i--;
3748            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
3749            if (observer != null) {
3750                try {
3751                    for (int j=0; j<N; j++) {
3752                        UidRecord.ChangeItem item = mActiveUidChanges[j];
3753                        if (item.gone) {
3754                            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3755                                    "UID gone uid=" + item.uid);
3756                            observer.onUidGone(item.uid);
3757                        } else {
3758                            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3759                                    "UID CHANGED uid=" + item.uid
3760                                    + ": " + item.processState);
3761                            observer.onUidStateChanged(item.uid, item.processState);
3762                        }
3763                    }
3764                } catch (RemoteException e) {
3765                }
3766            }
3767        }
3768        mUidObservers.finishBroadcast();
3769
3770        synchronized (this) {
3771            for (int j=0; j<N; j++) {
3772                mAvailUidChanges.add(mActiveUidChanges[j]);
3773            }
3774        }
3775    }
3776
3777    @Override
3778    public final int startActivity(IApplicationThread caller, String callingPackage,
3779            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3780            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3781        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3782            resultWho, requestCode, startFlags, profilerInfo, options,
3783            UserHandle.getCallingUserId());
3784    }
3785
3786    @Override
3787    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3788            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3789            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3790        enforceNotIsolatedCaller("startActivity");
3791        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3792                false, ALLOW_FULL_ONLY, "startActivity", null);
3793        // TODO: Switch to user app stacks here.
3794        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3795                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3796                profilerInfo, null, null, options, userId, null, null);
3797    }
3798
3799    @Override
3800    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3801            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3802            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3803
3804        // This is very dangerous -- it allows you to perform a start activity (including
3805        // permission grants) as any app that may launch one of your own activities.  So
3806        // we will only allow this to be done from activities that are part of the core framework,
3807        // and then only when they are running as the system.
3808        final ActivityRecord sourceRecord;
3809        final int targetUid;
3810        final String targetPackage;
3811        synchronized (this) {
3812            if (resultTo == null) {
3813                throw new SecurityException("Must be called from an activity");
3814            }
3815            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3816            if (sourceRecord == null) {
3817                throw new SecurityException("Called with bad activity token: " + resultTo);
3818            }
3819            if (!sourceRecord.info.packageName.equals("android")) {
3820                throw new SecurityException(
3821                        "Must be called from an activity that is declared in the android package");
3822            }
3823            if (sourceRecord.app == null) {
3824                throw new SecurityException("Called without a process attached to activity");
3825            }
3826            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3827                // This is still okay, as long as this activity is running under the
3828                // uid of the original calling activity.
3829                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3830                    throw new SecurityException(
3831                            "Calling activity in uid " + sourceRecord.app.uid
3832                                    + " must be system uid or original calling uid "
3833                                    + sourceRecord.launchedFromUid);
3834                }
3835            }
3836            targetUid = sourceRecord.launchedFromUid;
3837            targetPackage = sourceRecord.launchedFromPackage;
3838        }
3839
3840        if (userId == UserHandle.USER_NULL) {
3841            userId = UserHandle.getUserId(sourceRecord.app.uid);
3842        }
3843
3844        // TODO: Switch to user app stacks here.
3845        try {
3846            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3847                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3848                    null, null, options, userId, null, null);
3849            return ret;
3850        } catch (SecurityException e) {
3851            // XXX need to figure out how to propagate to original app.
3852            // A SecurityException here is generally actually a fault of the original
3853            // calling activity (such as a fairly granting permissions), so propagate it
3854            // back to them.
3855            /*
3856            StringBuilder msg = new StringBuilder();
3857            msg.append("While launching");
3858            msg.append(intent.toString());
3859            msg.append(": ");
3860            msg.append(e.getMessage());
3861            */
3862            throw e;
3863        }
3864    }
3865
3866    @Override
3867    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3868            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3869            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3870        enforceNotIsolatedCaller("startActivityAndWait");
3871        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3872                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3873        WaitResult res = new WaitResult();
3874        // TODO: Switch to user app stacks here.
3875        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3876                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3877                options, userId, null, null);
3878        return res;
3879    }
3880
3881    @Override
3882    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3883            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3884            int startFlags, Configuration config, Bundle options, int userId) {
3885        enforceNotIsolatedCaller("startActivityWithConfig");
3886        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3887                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3888        // TODO: Switch to user app stacks here.
3889        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3890                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3891                null, null, config, options, userId, null, null);
3892        return ret;
3893    }
3894
3895    @Override
3896    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
3897            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
3898            int requestCode, int flagsMask, int flagsValues, Bundle options)
3899            throws TransactionTooLargeException {
3900        enforceNotIsolatedCaller("startActivityIntentSender");
3901        // Refuse possible leaked file descriptors
3902        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3903            throw new IllegalArgumentException("File descriptors passed in Intent");
3904        }
3905
3906        IIntentSender sender = intent.getTarget();
3907        if (!(sender instanceof PendingIntentRecord)) {
3908            throw new IllegalArgumentException("Bad PendingIntent object");
3909        }
3910
3911        PendingIntentRecord pir = (PendingIntentRecord)sender;
3912
3913        synchronized (this) {
3914            // If this is coming from the currently resumed activity, it is
3915            // effectively saying that app switches are allowed at this point.
3916            final ActivityStack stack = getFocusedStack();
3917            if (stack.mResumedActivity != null &&
3918                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3919                mAppSwitchesAllowedTime = 0;
3920            }
3921        }
3922        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3923                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3924        return ret;
3925    }
3926
3927    @Override
3928    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3929            Intent intent, String resolvedType, IVoiceInteractionSession session,
3930            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3931            Bundle options, int userId) {
3932        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3933                != PackageManager.PERMISSION_GRANTED) {
3934            String msg = "Permission Denial: startVoiceActivity() from pid="
3935                    + Binder.getCallingPid()
3936                    + ", uid=" + Binder.getCallingUid()
3937                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3938            Slog.w(TAG, msg);
3939            throw new SecurityException(msg);
3940        }
3941        if (session == null || interactor == null) {
3942            throw new NullPointerException("null session or interactor");
3943        }
3944        userId = handleIncomingUser(callingPid, callingUid, userId,
3945                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3946        // TODO: Switch to user app stacks here.
3947        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3948                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3949                null, options, userId, null, null);
3950    }
3951
3952    @Override
3953    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
3954        synchronized (this) {
3955            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
3956                if (keepAwake) {
3957                    mVoiceWakeLock.acquire();
3958                } else {
3959                    mVoiceWakeLock.release();
3960                }
3961            }
3962        }
3963    }
3964
3965    @Override
3966    public boolean startNextMatchingActivity(IBinder callingActivity,
3967            Intent intent, Bundle options) {
3968        // Refuse possible leaked file descriptors
3969        if (intent != null && intent.hasFileDescriptors() == true) {
3970            throw new IllegalArgumentException("File descriptors passed in Intent");
3971        }
3972
3973        synchronized (this) {
3974            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3975            if (r == null) {
3976                ActivityOptions.abort(options);
3977                return false;
3978            }
3979            if (r.app == null || r.app.thread == null) {
3980                // The caller is not running...  d'oh!
3981                ActivityOptions.abort(options);
3982                return false;
3983            }
3984            intent = new Intent(intent);
3985            // The caller is not allowed to change the data.
3986            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3987            // And we are resetting to find the next component...
3988            intent.setComponent(null);
3989
3990            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3991
3992            ActivityInfo aInfo = null;
3993            try {
3994                List<ResolveInfo> resolves =
3995                    AppGlobals.getPackageManager().queryIntentActivities(
3996                            intent, r.resolvedType,
3997                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3998                            UserHandle.getCallingUserId());
3999
4000                // Look for the original activity in the list...
4001                final int N = resolves != null ? resolves.size() : 0;
4002                for (int i=0; i<N; i++) {
4003                    ResolveInfo rInfo = resolves.get(i);
4004                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4005                            && rInfo.activityInfo.name.equals(r.info.name)) {
4006                        // We found the current one...  the next matching is
4007                        // after it.
4008                        i++;
4009                        if (i<N) {
4010                            aInfo = resolves.get(i).activityInfo;
4011                        }
4012                        if (debug) {
4013                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4014                                    + "/" + r.info.name);
4015                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
4016                                    + "/" + aInfo.name);
4017                        }
4018                        break;
4019                    }
4020                }
4021            } catch (RemoteException e) {
4022            }
4023
4024            if (aInfo == null) {
4025                // Nobody who is next!
4026                ActivityOptions.abort(options);
4027                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4028                return false;
4029            }
4030
4031            intent.setComponent(new ComponentName(
4032                    aInfo.applicationInfo.packageName, aInfo.name));
4033            intent.setFlags(intent.getFlags()&~(
4034                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4035                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4036                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4037                    Intent.FLAG_ACTIVITY_NEW_TASK));
4038
4039            // Okay now we need to start the new activity, replacing the
4040            // currently running activity.  This is a little tricky because
4041            // we want to start the new one as if the current one is finished,
4042            // but not finish the current one first so that there is no flicker.
4043            // And thus...
4044            final boolean wasFinishing = r.finishing;
4045            r.finishing = true;
4046
4047            // Propagate reply information over to the new activity.
4048            final ActivityRecord resultTo = r.resultTo;
4049            final String resultWho = r.resultWho;
4050            final int requestCode = r.requestCode;
4051            r.resultTo = null;
4052            if (resultTo != null) {
4053                resultTo.removeResultsLocked(r, resultWho, requestCode);
4054            }
4055
4056            final long origId = Binder.clearCallingIdentity();
4057            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
4058                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
4059                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
4060                    -1, r.launchedFromUid, 0, options, false, null, null, null);
4061            Binder.restoreCallingIdentity(origId);
4062
4063            r.finishing = wasFinishing;
4064            if (res != ActivityManager.START_SUCCESS) {
4065                return false;
4066            }
4067            return true;
4068        }
4069    }
4070
4071    @Override
4072    public final int startActivityFromRecents(int taskId, Bundle options) {
4073        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4074            String msg = "Permission Denial: startActivityFromRecents called without " +
4075                    START_TASKS_FROM_RECENTS;
4076            Slog.w(TAG, msg);
4077            throw new SecurityException(msg);
4078        }
4079        return startActivityFromRecentsInner(taskId, options);
4080    }
4081
4082    final int startActivityFromRecentsInner(int taskId, Bundle options) {
4083        final TaskRecord task;
4084        final int callingUid;
4085        final String callingPackage;
4086        final Intent intent;
4087        final int userId;
4088        synchronized (this) {
4089            task = mRecentTasks.taskForIdLocked(taskId);
4090            if (task == null) {
4091                throw new IllegalArgumentException("Task " + taskId + " not found.");
4092            }
4093            if (task.getRootActivity() != null) {
4094                moveTaskToFrontLocked(task.taskId, 0, null);
4095                return ActivityManager.START_TASK_TO_FRONT;
4096            }
4097            callingUid = task.mCallingUid;
4098            callingPackage = task.mCallingPackage;
4099            intent = task.intent;
4100            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4101            userId = task.userId;
4102        }
4103        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4104                options, userId, null, task);
4105    }
4106
4107    final int startActivityInPackage(int uid, String callingPackage,
4108            Intent intent, String resolvedType, IBinder resultTo,
4109            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
4110            IActivityContainer container, TaskRecord inTask) {
4111
4112        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4113                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4114
4115        // TODO: Switch to user app stacks here.
4116        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
4117                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4118                null, null, null, options, userId, container, inTask);
4119        return ret;
4120    }
4121
4122    @Override
4123    public final int startActivities(IApplicationThread caller, String callingPackage,
4124            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
4125            int userId) {
4126        enforceNotIsolatedCaller("startActivities");
4127        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4128                false, ALLOW_FULL_ONLY, "startActivity", null);
4129        // TODO: Switch to user app stacks here.
4130        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
4131                resolvedTypes, resultTo, options, userId);
4132        return ret;
4133    }
4134
4135    final int startActivitiesInPackage(int uid, String callingPackage,
4136            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4137            Bundle options, int userId) {
4138
4139        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4140                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4141        // TODO: Switch to user app stacks here.
4142        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4143                resultTo, options, userId);
4144        return ret;
4145    }
4146
4147    @Override
4148    public void reportActivityFullyDrawn(IBinder token) {
4149        synchronized (this) {
4150            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4151            if (r == null) {
4152                return;
4153            }
4154            r.reportFullyDrawnLocked();
4155        }
4156    }
4157
4158    @Override
4159    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4160        synchronized (this) {
4161            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4162            if (r == null) {
4163                return;
4164            }
4165            if (r.task != null && r.task.mResizeable) {
4166                // Fixed screen orientation isn't supported with resizeable activities.
4167                return;
4168            }
4169            final long origId = Binder.clearCallingIdentity();
4170            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4171            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4172                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4173            if (config != null) {
4174                r.frozenBeforeDestroy = true;
4175                if (!updateConfigurationLocked(config, r, false, false)) {
4176                    mStackSupervisor.resumeTopActivitiesLocked();
4177                }
4178            }
4179            Binder.restoreCallingIdentity(origId);
4180        }
4181    }
4182
4183    @Override
4184    public int getRequestedOrientation(IBinder token) {
4185        synchronized (this) {
4186            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4187            if (r == null) {
4188                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4189            }
4190            return mWindowManager.getAppOrientation(r.appToken);
4191        }
4192    }
4193
4194    /**
4195     * This is the internal entry point for handling Activity.finish().
4196     *
4197     * @param token The Binder token referencing the Activity we want to finish.
4198     * @param resultCode Result code, if any, from this Activity.
4199     * @param resultData Result data (Intent), if any, from this Activity.
4200     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4201     *            the root Activity in the task.
4202     *
4203     * @return Returns true if the activity successfully finished, or false if it is still running.
4204     */
4205    @Override
4206    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4207            boolean finishTask) {
4208        // Refuse possible leaked file descriptors
4209        if (resultData != null && resultData.hasFileDescriptors() == true) {
4210            throw new IllegalArgumentException("File descriptors passed in Intent");
4211        }
4212
4213        synchronized(this) {
4214            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4215            if (r == null) {
4216                return true;
4217            }
4218            // Keep track of the root activity of the task before we finish it
4219            TaskRecord tr = r.task;
4220            ActivityRecord rootR = tr.getRootActivity();
4221            if (rootR == null) {
4222                Slog.w(TAG, "Finishing task with all activities already finished");
4223            }
4224            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4225            // finish.
4226            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4227                    mStackSupervisor.isLastLockedTask(tr)) {
4228                Slog.i(TAG, "Not finishing task in lock task mode");
4229                mStackSupervisor.showLockTaskToast();
4230                return false;
4231            }
4232            if (mController != null) {
4233                // Find the first activity that is not finishing.
4234                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4235                if (next != null) {
4236                    // ask watcher if this is allowed
4237                    boolean resumeOK = true;
4238                    try {
4239                        resumeOK = mController.activityResuming(next.packageName);
4240                    } catch (RemoteException e) {
4241                        mController = null;
4242                        Watchdog.getInstance().setActivityController(null);
4243                    }
4244
4245                    if (!resumeOK) {
4246                        Slog.i(TAG, "Not finishing activity because controller resumed");
4247                        return false;
4248                    }
4249                }
4250            }
4251            final long origId = Binder.clearCallingIdentity();
4252            try {
4253                boolean res;
4254                if (finishTask && r == rootR) {
4255                    // If requested, remove the task that is associated to this activity only if it
4256                    // was the root activity in the task. The result code and data is ignored
4257                    // because we don't support returning them across task boundaries.
4258                    res = removeTaskByIdLocked(tr.taskId, false);
4259                    if (!res) {
4260                        Slog.i(TAG, "Removing task failed to finish activity");
4261                    }
4262                } else {
4263                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4264                            resultData, "app-request", true);
4265                    if (!res) {
4266                        Slog.i(TAG, "Failed to finish by app-request");
4267                    }
4268                }
4269                return res;
4270            } finally {
4271                Binder.restoreCallingIdentity(origId);
4272            }
4273        }
4274    }
4275
4276    @Override
4277    public final void finishHeavyWeightApp() {
4278        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4279                != PackageManager.PERMISSION_GRANTED) {
4280            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4281                    + Binder.getCallingPid()
4282                    + ", uid=" + Binder.getCallingUid()
4283                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4284            Slog.w(TAG, msg);
4285            throw new SecurityException(msg);
4286        }
4287
4288        synchronized(this) {
4289            if (mHeavyWeightProcess == null) {
4290                return;
4291            }
4292
4293            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4294            for (int i = 0; i < activities.size(); i++) {
4295                ActivityRecord r = activities.get(i);
4296                if (!r.finishing && r.isInStackLocked()) {
4297                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4298                            null, "finish-heavy", true);
4299                }
4300            }
4301
4302            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4303                    mHeavyWeightProcess.userId, 0));
4304            mHeavyWeightProcess = null;
4305        }
4306    }
4307
4308    @Override
4309    public void crashApplication(int uid, int initialPid, String packageName,
4310            String message) {
4311        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4312                != PackageManager.PERMISSION_GRANTED) {
4313            String msg = "Permission Denial: crashApplication() from pid="
4314                    + Binder.getCallingPid()
4315                    + ", uid=" + Binder.getCallingUid()
4316                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4317            Slog.w(TAG, msg);
4318            throw new SecurityException(msg);
4319        }
4320
4321        synchronized(this) {
4322            ProcessRecord proc = null;
4323
4324            // Figure out which process to kill.  We don't trust that initialPid
4325            // still has any relation to current pids, so must scan through the
4326            // list.
4327            synchronized (mPidsSelfLocked) {
4328                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4329                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4330                    if (p.uid != uid) {
4331                        continue;
4332                    }
4333                    if (p.pid == initialPid) {
4334                        proc = p;
4335                        break;
4336                    }
4337                    if (p.pkgList.containsKey(packageName)) {
4338                        proc = p;
4339                    }
4340                }
4341            }
4342
4343            if (proc == null) {
4344                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4345                        + " initialPid=" + initialPid
4346                        + " packageName=" + packageName);
4347                return;
4348            }
4349
4350            if (proc.thread != null) {
4351                if (proc.pid == Process.myPid()) {
4352                    Log.w(TAG, "crashApplication: trying to crash self!");
4353                    return;
4354                }
4355                long ident = Binder.clearCallingIdentity();
4356                try {
4357                    proc.thread.scheduleCrash(message);
4358                } catch (RemoteException e) {
4359                }
4360                Binder.restoreCallingIdentity(ident);
4361            }
4362        }
4363    }
4364
4365    @Override
4366    public final void finishSubActivity(IBinder token, String resultWho,
4367            int requestCode) {
4368        synchronized(this) {
4369            final long origId = Binder.clearCallingIdentity();
4370            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4371            if (r != null) {
4372                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4373            }
4374            Binder.restoreCallingIdentity(origId);
4375        }
4376    }
4377
4378    @Override
4379    public boolean finishActivityAffinity(IBinder token) {
4380        synchronized(this) {
4381            final long origId = Binder.clearCallingIdentity();
4382            try {
4383                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4384                if (r == null) {
4385                    return false;
4386                }
4387
4388                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4389                // can finish.
4390                final TaskRecord task = r.task;
4391                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4392                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4393                    mStackSupervisor.showLockTaskToast();
4394                    return false;
4395                }
4396                return task.stack.finishActivityAffinityLocked(r);
4397            } finally {
4398                Binder.restoreCallingIdentity(origId);
4399            }
4400        }
4401    }
4402
4403    @Override
4404    public void finishVoiceTask(IVoiceInteractionSession session) {
4405        synchronized(this) {
4406            final long origId = Binder.clearCallingIdentity();
4407            try {
4408                mStackSupervisor.finishVoiceTask(session);
4409            } finally {
4410                Binder.restoreCallingIdentity(origId);
4411            }
4412        }
4413
4414    }
4415
4416    @Override
4417    public boolean releaseActivityInstance(IBinder token) {
4418        synchronized(this) {
4419            final long origId = Binder.clearCallingIdentity();
4420            try {
4421                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4422                if (r == null) {
4423                    return false;
4424                }
4425                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4426            } finally {
4427                Binder.restoreCallingIdentity(origId);
4428            }
4429        }
4430    }
4431
4432    @Override
4433    public void releaseSomeActivities(IApplicationThread appInt) {
4434        synchronized(this) {
4435            final long origId = Binder.clearCallingIdentity();
4436            try {
4437                ProcessRecord app = getRecordForAppLocked(appInt);
4438                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4439            } finally {
4440                Binder.restoreCallingIdentity(origId);
4441            }
4442        }
4443    }
4444
4445    @Override
4446    public boolean willActivityBeVisible(IBinder token) {
4447        synchronized(this) {
4448            ActivityStack stack = ActivityRecord.getStackLocked(token);
4449            if (stack != null) {
4450                return stack.willActivityBeVisibleLocked(token);
4451            }
4452            return false;
4453        }
4454    }
4455
4456    @Override
4457    public void overridePendingTransition(IBinder token, String packageName,
4458            int enterAnim, int exitAnim) {
4459        synchronized(this) {
4460            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4461            if (self == null) {
4462                return;
4463            }
4464
4465            final long origId = Binder.clearCallingIdentity();
4466
4467            if (self.state == ActivityState.RESUMED
4468                    || self.state == ActivityState.PAUSING) {
4469                mWindowManager.overridePendingAppTransition(packageName,
4470                        enterAnim, exitAnim, null);
4471            }
4472
4473            Binder.restoreCallingIdentity(origId);
4474        }
4475    }
4476
4477    /**
4478     * Main function for removing an existing process from the activity manager
4479     * as a result of that process going away.  Clears out all connections
4480     * to the process.
4481     */
4482    private final void handleAppDiedLocked(ProcessRecord app,
4483            boolean restarting, boolean allowRestart) {
4484        int pid = app.pid;
4485        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4486        if (!kept && !restarting) {
4487            removeLruProcessLocked(app);
4488            if (pid > 0) {
4489                ProcessList.remove(pid);
4490            }
4491        }
4492
4493        if (mProfileProc == app) {
4494            clearProfilerLocked();
4495        }
4496
4497        // Remove this application's activities from active lists.
4498        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4499
4500        app.activities.clear();
4501
4502        if (app.instrumentationClass != null) {
4503            Slog.w(TAG, "Crash of app " + app.processName
4504                  + " running instrumentation " + app.instrumentationClass);
4505            Bundle info = new Bundle();
4506            info.putString("shortMsg", "Process crashed.");
4507            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4508        }
4509
4510        if (!restarting && hasVisibleActivities && !mStackSupervisor.resumeTopActivitiesLocked()) {
4511            // If there was nothing to resume, and we are not already
4512            // restarting this process, but there is a visible activity that
4513            // is hosted by the process...  then make sure all visible
4514            // activities are running, taking care of restarting this
4515            // process.
4516            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4517        }
4518    }
4519
4520    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4521        IBinder threadBinder = thread.asBinder();
4522        // Find the application record.
4523        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4524            ProcessRecord rec = mLruProcesses.get(i);
4525            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4526                return i;
4527            }
4528        }
4529        return -1;
4530    }
4531
4532    final ProcessRecord getRecordForAppLocked(
4533            IApplicationThread thread) {
4534        if (thread == null) {
4535            return null;
4536        }
4537
4538        int appIndex = getLRURecordIndexForAppLocked(thread);
4539        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4540    }
4541
4542    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4543        // If there are no longer any background processes running,
4544        // and the app that died was not running instrumentation,
4545        // then tell everyone we are now low on memory.
4546        boolean haveBg = false;
4547        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4548            ProcessRecord rec = mLruProcesses.get(i);
4549            if (rec.thread != null
4550                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4551                haveBg = true;
4552                break;
4553            }
4554        }
4555
4556        if (!haveBg) {
4557            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4558            if (doReport) {
4559                long now = SystemClock.uptimeMillis();
4560                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4561                    doReport = false;
4562                } else {
4563                    mLastMemUsageReportTime = now;
4564                }
4565            }
4566            final ArrayList<ProcessMemInfo> memInfos
4567                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4568            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4569            long now = SystemClock.uptimeMillis();
4570            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4571                ProcessRecord rec = mLruProcesses.get(i);
4572                if (rec == dyingProc || rec.thread == null) {
4573                    continue;
4574                }
4575                if (doReport) {
4576                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4577                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4578                }
4579                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4580                    // The low memory report is overriding any current
4581                    // state for a GC request.  Make sure to do
4582                    // heavy/important/visible/foreground processes first.
4583                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4584                        rec.lastRequestedGc = 0;
4585                    } else {
4586                        rec.lastRequestedGc = rec.lastLowMemory;
4587                    }
4588                    rec.reportLowMemory = true;
4589                    rec.lastLowMemory = now;
4590                    mProcessesToGc.remove(rec);
4591                    addProcessToGcListLocked(rec);
4592                }
4593            }
4594            if (doReport) {
4595                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4596                mHandler.sendMessage(msg);
4597            }
4598            scheduleAppGcsLocked();
4599        }
4600    }
4601
4602    final void appDiedLocked(ProcessRecord app) {
4603       appDiedLocked(app, app.pid, app.thread, false);
4604    }
4605
4606    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4607            boolean fromBinderDied) {
4608        // First check if this ProcessRecord is actually active for the pid.
4609        synchronized (mPidsSelfLocked) {
4610            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4611            if (curProc != app) {
4612                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4613                return;
4614            }
4615        }
4616
4617        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4618        synchronized (stats) {
4619            stats.noteProcessDiedLocked(app.info.uid, pid);
4620        }
4621
4622        if (!app.killed) {
4623            if (!fromBinderDied) {
4624                Process.killProcessQuiet(pid);
4625            }
4626            killProcessGroup(app.info.uid, pid);
4627            app.killed = true;
4628        }
4629
4630        // Clean up already done if the process has been re-started.
4631        if (app.pid == pid && app.thread != null &&
4632                app.thread.asBinder() == thread.asBinder()) {
4633            boolean doLowMem = app.instrumentationClass == null;
4634            boolean doOomAdj = doLowMem;
4635            if (!app.killedByAm) {
4636                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4637                        + ") has died");
4638                mAllowLowerMemLevel = true;
4639            } else {
4640                // Note that we always want to do oom adj to update our state with the
4641                // new number of procs.
4642                mAllowLowerMemLevel = false;
4643                doLowMem = false;
4644            }
4645            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4646            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4647                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
4648            handleAppDiedLocked(app, false, true);
4649
4650            if (doOomAdj) {
4651                updateOomAdjLocked();
4652            }
4653            if (doLowMem) {
4654                doLowMemReportIfNeededLocked(app);
4655            }
4656        } else if (app.pid != pid) {
4657            // A new process has already been started.
4658            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4659                    + ") has died and restarted (pid " + app.pid + ").");
4660            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4661        } else if (DEBUG_PROCESSES) {
4662            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
4663                    + thread.asBinder());
4664        }
4665    }
4666
4667    /**
4668     * If a stack trace dump file is configured, dump process stack traces.
4669     * @param clearTraces causes the dump file to be erased prior to the new
4670     *    traces being written, if true; when false, the new traces will be
4671     *    appended to any existing file content.
4672     * @param firstPids of dalvik VM processes to dump stack traces for first
4673     * @param lastPids of dalvik VM processes to dump stack traces for last
4674     * @param nativeProcs optional list of native process names to dump stack crawls
4675     * @return file containing stack traces, or null if no dump file is configured
4676     */
4677    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4678            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4679        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4680        if (tracesPath == null || tracesPath.length() == 0) {
4681            return null;
4682        }
4683
4684        File tracesFile = new File(tracesPath);
4685        try {
4686            File tracesDir = tracesFile.getParentFile();
4687            if (!tracesDir.exists()) {
4688                tracesDir.mkdirs();
4689                if (!SELinux.restorecon(tracesDir)) {
4690                    return null;
4691                }
4692            }
4693            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4694
4695            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4696            tracesFile.createNewFile();
4697            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4698        } catch (IOException e) {
4699            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4700            return null;
4701        }
4702
4703        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4704        return tracesFile;
4705    }
4706
4707    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4708            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4709        // Use a FileObserver to detect when traces finish writing.
4710        // The order of traces is considered important to maintain for legibility.
4711        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4712            @Override
4713            public synchronized void onEvent(int event, String path) { notify(); }
4714        };
4715
4716        try {
4717            observer.startWatching();
4718
4719            // First collect all of the stacks of the most important pids.
4720            if (firstPids != null) {
4721                try {
4722                    int num = firstPids.size();
4723                    for (int i = 0; i < num; i++) {
4724                        synchronized (observer) {
4725                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4726                            observer.wait(200);  // Wait for write-close, give up after 200msec
4727                        }
4728                    }
4729                } catch (InterruptedException e) {
4730                    Slog.wtf(TAG, e);
4731                }
4732            }
4733
4734            // Next collect the stacks of the native pids
4735            if (nativeProcs != null) {
4736                int[] pids = Process.getPidsForCommands(nativeProcs);
4737                if (pids != null) {
4738                    for (int pid : pids) {
4739                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4740                    }
4741                }
4742            }
4743
4744            // Lastly, measure CPU usage.
4745            if (processCpuTracker != null) {
4746                processCpuTracker.init();
4747                System.gc();
4748                processCpuTracker.update();
4749                try {
4750                    synchronized (processCpuTracker) {
4751                        processCpuTracker.wait(500); // measure over 1/2 second.
4752                    }
4753                } catch (InterruptedException e) {
4754                }
4755                processCpuTracker.update();
4756
4757                // We'll take the stack crawls of just the top apps using CPU.
4758                final int N = processCpuTracker.countWorkingStats();
4759                int numProcs = 0;
4760                for (int i=0; i<N && numProcs<5; i++) {
4761                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4762                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4763                        numProcs++;
4764                        try {
4765                            synchronized (observer) {
4766                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4767                                observer.wait(200);  // Wait for write-close, give up after 200msec
4768                            }
4769                        } catch (InterruptedException e) {
4770                            Slog.wtf(TAG, e);
4771                        }
4772
4773                    }
4774                }
4775            }
4776        } finally {
4777            observer.stopWatching();
4778        }
4779    }
4780
4781    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4782        if (true || IS_USER_BUILD) {
4783            return;
4784        }
4785        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4786        if (tracesPath == null || tracesPath.length() == 0) {
4787            return;
4788        }
4789
4790        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4791        StrictMode.allowThreadDiskWrites();
4792        try {
4793            final File tracesFile = new File(tracesPath);
4794            final File tracesDir = tracesFile.getParentFile();
4795            final File tracesTmp = new File(tracesDir, "__tmp__");
4796            try {
4797                if (!tracesDir.exists()) {
4798                    tracesDir.mkdirs();
4799                    if (!SELinux.restorecon(tracesDir.getPath())) {
4800                        return;
4801                    }
4802                }
4803                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4804
4805                if (tracesFile.exists()) {
4806                    tracesTmp.delete();
4807                    tracesFile.renameTo(tracesTmp);
4808                }
4809                StringBuilder sb = new StringBuilder();
4810                Time tobj = new Time();
4811                tobj.set(System.currentTimeMillis());
4812                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4813                sb.append(": ");
4814                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4815                sb.append(" since ");
4816                sb.append(msg);
4817                FileOutputStream fos = new FileOutputStream(tracesFile);
4818                fos.write(sb.toString().getBytes());
4819                if (app == null) {
4820                    fos.write("\n*** No application process!".getBytes());
4821                }
4822                fos.close();
4823                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4824            } catch (IOException e) {
4825                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4826                return;
4827            }
4828
4829            if (app != null) {
4830                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4831                firstPids.add(app.pid);
4832                dumpStackTraces(tracesPath, firstPids, null, null, null);
4833            }
4834
4835            File lastTracesFile = null;
4836            File curTracesFile = null;
4837            for (int i=9; i>=0; i--) {
4838                String name = String.format(Locale.US, "slow%02d.txt", i);
4839                curTracesFile = new File(tracesDir, name);
4840                if (curTracesFile.exists()) {
4841                    if (lastTracesFile != null) {
4842                        curTracesFile.renameTo(lastTracesFile);
4843                    } else {
4844                        curTracesFile.delete();
4845                    }
4846                }
4847                lastTracesFile = curTracesFile;
4848            }
4849            tracesFile.renameTo(curTracesFile);
4850            if (tracesTmp.exists()) {
4851                tracesTmp.renameTo(tracesFile);
4852            }
4853        } finally {
4854            StrictMode.setThreadPolicy(oldPolicy);
4855        }
4856    }
4857
4858    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4859            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4860        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4861        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4862
4863        if (mController != null) {
4864            try {
4865                // 0 == continue, -1 = kill process immediately
4866                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4867                if (res < 0 && app.pid != MY_PID) {
4868                    app.kill("anr", true);
4869                }
4870            } catch (RemoteException e) {
4871                mController = null;
4872                Watchdog.getInstance().setActivityController(null);
4873            }
4874        }
4875
4876        long anrTime = SystemClock.uptimeMillis();
4877        if (MONITOR_CPU_USAGE) {
4878            updateCpuStatsNow();
4879        }
4880
4881        synchronized (this) {
4882            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4883            if (mShuttingDown) {
4884                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4885                return;
4886            } else if (app.notResponding) {
4887                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4888                return;
4889            } else if (app.crashing) {
4890                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4891                return;
4892            }
4893
4894            // In case we come through here for the same app before completing
4895            // this one, mark as anring now so we will bail out.
4896            app.notResponding = true;
4897
4898            // Log the ANR to the event log.
4899            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4900                    app.processName, app.info.flags, annotation);
4901
4902            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4903            firstPids.add(app.pid);
4904
4905            int parentPid = app.pid;
4906            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4907            if (parentPid != app.pid) firstPids.add(parentPid);
4908
4909            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4910
4911            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4912                ProcessRecord r = mLruProcesses.get(i);
4913                if (r != null && r.thread != null) {
4914                    int pid = r.pid;
4915                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4916                        if (r.persistent) {
4917                            firstPids.add(pid);
4918                        } else {
4919                            lastPids.put(pid, Boolean.TRUE);
4920                        }
4921                    }
4922                }
4923            }
4924        }
4925
4926        // Log the ANR to the main log.
4927        StringBuilder info = new StringBuilder();
4928        info.setLength(0);
4929        info.append("ANR in ").append(app.processName);
4930        if (activity != null && activity.shortComponentName != null) {
4931            info.append(" (").append(activity.shortComponentName).append(")");
4932        }
4933        info.append("\n");
4934        info.append("PID: ").append(app.pid).append("\n");
4935        if (annotation != null) {
4936            info.append("Reason: ").append(annotation).append("\n");
4937        }
4938        if (parent != null && parent != activity) {
4939            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4940        }
4941
4942        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4943
4944        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4945                NATIVE_STACKS_OF_INTEREST);
4946
4947        String cpuInfo = null;
4948        if (MONITOR_CPU_USAGE) {
4949            updateCpuStatsNow();
4950            synchronized (mProcessCpuTracker) {
4951                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4952            }
4953            info.append(processCpuTracker.printCurrentLoad());
4954            info.append(cpuInfo);
4955        }
4956
4957        info.append(processCpuTracker.printCurrentState(anrTime));
4958
4959        Slog.e(TAG, info.toString());
4960        if (tracesFile == null) {
4961            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4962            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4963        }
4964
4965        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4966                cpuInfo, tracesFile, null);
4967
4968        if (mController != null) {
4969            try {
4970                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4971                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4972                if (res != 0) {
4973                    if (res < 0 && app.pid != MY_PID) {
4974                        app.kill("anr", true);
4975                    } else {
4976                        synchronized (this) {
4977                            mServices.scheduleServiceTimeoutLocked(app);
4978                        }
4979                    }
4980                    return;
4981                }
4982            } catch (RemoteException e) {
4983                mController = null;
4984                Watchdog.getInstance().setActivityController(null);
4985            }
4986        }
4987
4988        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4989        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4990                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4991
4992        synchronized (this) {
4993            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
4994
4995            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4996                app.kill("bg anr", true);
4997                return;
4998            }
4999
5000            // Set the app's notResponding state, and look up the errorReportReceiver
5001            makeAppNotRespondingLocked(app,
5002                    activity != null ? activity.shortComponentName : null,
5003                    annotation != null ? "ANR " + annotation : "ANR",
5004                    info.toString());
5005
5006            // Bring up the infamous App Not Responding dialog
5007            Message msg = Message.obtain();
5008            HashMap<String, Object> map = new HashMap<String, Object>();
5009            msg.what = SHOW_NOT_RESPONDING_MSG;
5010            msg.obj = map;
5011            msg.arg1 = aboveSystem ? 1 : 0;
5012            map.put("app", app);
5013            if (activity != null) {
5014                map.put("activity", activity);
5015            }
5016
5017            mUiHandler.sendMessage(msg);
5018        }
5019    }
5020
5021    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5022        if (!mLaunchWarningShown) {
5023            mLaunchWarningShown = true;
5024            mUiHandler.post(new Runnable() {
5025                @Override
5026                public void run() {
5027                    synchronized (ActivityManagerService.this) {
5028                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5029                        d.show();
5030                        mUiHandler.postDelayed(new Runnable() {
5031                            @Override
5032                            public void run() {
5033                                synchronized (ActivityManagerService.this) {
5034                                    d.dismiss();
5035                                    mLaunchWarningShown = false;
5036                                }
5037                            }
5038                        }, 4000);
5039                    }
5040                }
5041            });
5042        }
5043    }
5044
5045    @Override
5046    public boolean clearApplicationUserData(final String packageName,
5047            final IPackageDataObserver observer, int userId) {
5048        enforceNotIsolatedCaller("clearApplicationUserData");
5049        if (packageName != null && packageName.equals(mDeviceOwnerName)) {
5050            throw new SecurityException("Clearing DeviceOwner data is forbidden.");
5051        }
5052        int uid = Binder.getCallingUid();
5053        int pid = Binder.getCallingPid();
5054        userId = handleIncomingUser(pid, uid,
5055                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5056        long callingId = Binder.clearCallingIdentity();
5057        try {
5058            IPackageManager pm = AppGlobals.getPackageManager();
5059            int pkgUid = -1;
5060            synchronized(this) {
5061                try {
5062                    pkgUid = pm.getPackageUid(packageName, userId);
5063                } catch (RemoteException e) {
5064                }
5065                if (pkgUid == -1) {
5066                    Slog.w(TAG, "Invalid packageName: " + packageName);
5067                    if (observer != null) {
5068                        try {
5069                            observer.onRemoveCompleted(packageName, false);
5070                        } catch (RemoteException e) {
5071                            Slog.i(TAG, "Observer no longer exists.");
5072                        }
5073                    }
5074                    return false;
5075                }
5076                if (uid == pkgUid || checkComponentPermission(
5077                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5078                        pid, uid, -1, true)
5079                        == PackageManager.PERMISSION_GRANTED) {
5080                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5081                } else {
5082                    throw new SecurityException("PID " + pid + " does not have permission "
5083                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5084                                    + " of package " + packageName);
5085                }
5086
5087                // Remove all tasks match the cleared application package and user
5088                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5089                    final TaskRecord tr = mRecentTasks.get(i);
5090                    final String taskPackageName =
5091                            tr.getBaseIntent().getComponent().getPackageName();
5092                    if (tr.userId != userId) continue;
5093                    if (!taskPackageName.equals(packageName)) continue;
5094                    removeTaskByIdLocked(tr.taskId, false);
5095                }
5096            }
5097
5098            try {
5099                // Clear application user data
5100                pm.clearApplicationUserData(packageName, observer, userId);
5101
5102                synchronized(this) {
5103                    // Remove all permissions granted from/to this package
5104                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5105                }
5106
5107                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5108                        Uri.fromParts("package", packageName, null));
5109                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5110                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5111                        null, null, 0, null, null, null, null, false, false, userId);
5112            } catch (RemoteException e) {
5113            }
5114        } finally {
5115            Binder.restoreCallingIdentity(callingId);
5116        }
5117        return true;
5118    }
5119
5120    @Override
5121    public void killBackgroundProcesses(final String packageName, int userId) {
5122        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5123                != PackageManager.PERMISSION_GRANTED &&
5124                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5125                        != PackageManager.PERMISSION_GRANTED) {
5126            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5127                    + Binder.getCallingPid()
5128                    + ", uid=" + Binder.getCallingUid()
5129                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5130            Slog.w(TAG, msg);
5131            throw new SecurityException(msg);
5132        }
5133
5134        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5135                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5136        long callingId = Binder.clearCallingIdentity();
5137        try {
5138            IPackageManager pm = AppGlobals.getPackageManager();
5139            synchronized(this) {
5140                int appId = -1;
5141                try {
5142                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5143                } catch (RemoteException e) {
5144                }
5145                if (appId == -1) {
5146                    Slog.w(TAG, "Invalid packageName: " + packageName);
5147                    return;
5148                }
5149                killPackageProcessesLocked(packageName, appId, userId,
5150                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5151            }
5152        } finally {
5153            Binder.restoreCallingIdentity(callingId);
5154        }
5155    }
5156
5157    @Override
5158    public void killAllBackgroundProcesses() {
5159        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5160                != PackageManager.PERMISSION_GRANTED) {
5161            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5162                    + Binder.getCallingPid()
5163                    + ", uid=" + Binder.getCallingUid()
5164                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5165            Slog.w(TAG, msg);
5166            throw new SecurityException(msg);
5167        }
5168
5169        long callingId = Binder.clearCallingIdentity();
5170        try {
5171            synchronized(this) {
5172                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5173                final int NP = mProcessNames.getMap().size();
5174                for (int ip=0; ip<NP; ip++) {
5175                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5176                    final int NA = apps.size();
5177                    for (int ia=0; ia<NA; ia++) {
5178                        ProcessRecord app = apps.valueAt(ia);
5179                        if (app.persistent) {
5180                            // we don't kill persistent processes
5181                            continue;
5182                        }
5183                        if (app.removed) {
5184                            procs.add(app);
5185                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5186                            app.removed = true;
5187                            procs.add(app);
5188                        }
5189                    }
5190                }
5191
5192                int N = procs.size();
5193                for (int i=0; i<N; i++) {
5194                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5195                }
5196                mAllowLowerMemLevel = true;
5197                updateOomAdjLocked();
5198                doLowMemReportIfNeededLocked(null);
5199            }
5200        } finally {
5201            Binder.restoreCallingIdentity(callingId);
5202        }
5203    }
5204
5205    @Override
5206    public void forceStopPackage(final String packageName, int userId) {
5207        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5208                != PackageManager.PERMISSION_GRANTED) {
5209            String msg = "Permission Denial: forceStopPackage() from pid="
5210                    + Binder.getCallingPid()
5211                    + ", uid=" + Binder.getCallingUid()
5212                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5213            Slog.w(TAG, msg);
5214            throw new SecurityException(msg);
5215        }
5216        final int callingPid = Binder.getCallingPid();
5217        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5218                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5219        long callingId = Binder.clearCallingIdentity();
5220        try {
5221            IPackageManager pm = AppGlobals.getPackageManager();
5222            synchronized(this) {
5223                int[] users = userId == UserHandle.USER_ALL
5224                        ? getUsersLocked() : new int[] { userId };
5225                for (int user : users) {
5226                    int pkgUid = -1;
5227                    try {
5228                        pkgUid = pm.getPackageUid(packageName, user);
5229                    } catch (RemoteException e) {
5230                    }
5231                    if (pkgUid == -1) {
5232                        Slog.w(TAG, "Invalid packageName: " + packageName);
5233                        continue;
5234                    }
5235                    try {
5236                        pm.setPackageStoppedState(packageName, true, user);
5237                    } catch (RemoteException e) {
5238                    } catch (IllegalArgumentException e) {
5239                        Slog.w(TAG, "Failed trying to unstop package "
5240                                + packageName + ": " + e);
5241                    }
5242                    if (isUserRunningLocked(user, false)) {
5243                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5244                    }
5245                }
5246            }
5247        } finally {
5248            Binder.restoreCallingIdentity(callingId);
5249        }
5250    }
5251
5252    @Override
5253    public void addPackageDependency(String packageName) {
5254        synchronized (this) {
5255            int callingPid = Binder.getCallingPid();
5256            if (callingPid == Process.myPid()) {
5257                //  Yeah, um, no.
5258                return;
5259            }
5260            ProcessRecord proc;
5261            synchronized (mPidsSelfLocked) {
5262                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5263            }
5264            if (proc != null) {
5265                if (proc.pkgDeps == null) {
5266                    proc.pkgDeps = new ArraySet<String>(1);
5267                }
5268                proc.pkgDeps.add(packageName);
5269            }
5270        }
5271    }
5272
5273    /*
5274     * The pkg name and app id have to be specified.
5275     */
5276    @Override
5277    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5278        if (pkg == null) {
5279            return;
5280        }
5281        // Make sure the uid is valid.
5282        if (appid < 0) {
5283            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5284            return;
5285        }
5286        int callerUid = Binder.getCallingUid();
5287        // Only the system server can kill an application
5288        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5289            // Post an aysnc message to kill the application
5290            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5291            msg.arg1 = appid;
5292            msg.arg2 = 0;
5293            Bundle bundle = new Bundle();
5294            bundle.putString("pkg", pkg);
5295            bundle.putString("reason", reason);
5296            msg.obj = bundle;
5297            mHandler.sendMessage(msg);
5298        } else {
5299            throw new SecurityException(callerUid + " cannot kill pkg: " +
5300                    pkg);
5301        }
5302    }
5303
5304    @Override
5305    public void closeSystemDialogs(String reason) {
5306        enforceNotIsolatedCaller("closeSystemDialogs");
5307
5308        final int pid = Binder.getCallingPid();
5309        final int uid = Binder.getCallingUid();
5310        final long origId = Binder.clearCallingIdentity();
5311        try {
5312            synchronized (this) {
5313                // Only allow this from foreground processes, so that background
5314                // applications can't abuse it to prevent system UI from being shown.
5315                if (uid >= Process.FIRST_APPLICATION_UID) {
5316                    ProcessRecord proc;
5317                    synchronized (mPidsSelfLocked) {
5318                        proc = mPidsSelfLocked.get(pid);
5319                    }
5320                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5321                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5322                                + " from background process " + proc);
5323                        return;
5324                    }
5325                }
5326                closeSystemDialogsLocked(reason);
5327            }
5328        } finally {
5329            Binder.restoreCallingIdentity(origId);
5330        }
5331    }
5332
5333    void closeSystemDialogsLocked(String reason) {
5334        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5335        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5336                | Intent.FLAG_RECEIVER_FOREGROUND);
5337        if (reason != null) {
5338            intent.putExtra("reason", reason);
5339        }
5340        mWindowManager.closeSystemDialogs(reason);
5341
5342        mStackSupervisor.closeSystemDialogsLocked();
5343
5344        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5345                AppOpsManager.OP_NONE, null, false, false,
5346                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5347    }
5348
5349    @Override
5350    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5351        enforceNotIsolatedCaller("getProcessMemoryInfo");
5352        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5353        for (int i=pids.length-1; i>=0; i--) {
5354            ProcessRecord proc;
5355            int oomAdj;
5356            synchronized (this) {
5357                synchronized (mPidsSelfLocked) {
5358                    proc = mPidsSelfLocked.get(pids[i]);
5359                    oomAdj = proc != null ? proc.setAdj : 0;
5360                }
5361            }
5362            infos[i] = new Debug.MemoryInfo();
5363            Debug.getMemoryInfo(pids[i], infos[i]);
5364            if (proc != null) {
5365                synchronized (this) {
5366                    if (proc.thread != null && proc.setAdj == oomAdj) {
5367                        // Record this for posterity if the process has been stable.
5368                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5369                                infos[i].getTotalUss(), false, proc.pkgList);
5370                    }
5371                }
5372            }
5373        }
5374        return infos;
5375    }
5376
5377    @Override
5378    public long[] getProcessPss(int[] pids) {
5379        enforceNotIsolatedCaller("getProcessPss");
5380        long[] pss = new long[pids.length];
5381        for (int i=pids.length-1; i>=0; i--) {
5382            ProcessRecord proc;
5383            int oomAdj;
5384            synchronized (this) {
5385                synchronized (mPidsSelfLocked) {
5386                    proc = mPidsSelfLocked.get(pids[i]);
5387                    oomAdj = proc != null ? proc.setAdj : 0;
5388                }
5389            }
5390            long[] tmpUss = new long[1];
5391            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5392            if (proc != null) {
5393                synchronized (this) {
5394                    if (proc.thread != null && proc.setAdj == oomAdj) {
5395                        // Record this for posterity if the process has been stable.
5396                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5397                    }
5398                }
5399            }
5400        }
5401        return pss;
5402    }
5403
5404    @Override
5405    public void killApplicationProcess(String processName, int uid) {
5406        if (processName == null) {
5407            return;
5408        }
5409
5410        int callerUid = Binder.getCallingUid();
5411        // Only the system server can kill an application
5412        if (callerUid == Process.SYSTEM_UID) {
5413            synchronized (this) {
5414                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5415                if (app != null && app.thread != null) {
5416                    try {
5417                        app.thread.scheduleSuicide();
5418                    } catch (RemoteException e) {
5419                        // If the other end already died, then our work here is done.
5420                    }
5421                } else {
5422                    Slog.w(TAG, "Process/uid not found attempting kill of "
5423                            + processName + " / " + uid);
5424                }
5425            }
5426        } else {
5427            throw new SecurityException(callerUid + " cannot kill app process: " +
5428                    processName);
5429        }
5430    }
5431
5432    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5433        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5434                false, true, false, false, UserHandle.getUserId(uid), reason);
5435        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5436                Uri.fromParts("package", packageName, null));
5437        if (!mProcessesReady) {
5438            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5439                    | Intent.FLAG_RECEIVER_FOREGROUND);
5440        }
5441        intent.putExtra(Intent.EXTRA_UID, uid);
5442        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5443        broadcastIntentLocked(null, null, intent,
5444                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5445                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5446    }
5447
5448    private void forceStopUserLocked(int userId, String reason) {
5449        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5450        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5451        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5452                | Intent.FLAG_RECEIVER_FOREGROUND);
5453        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5454        broadcastIntentLocked(null, null, intent,
5455                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5456                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5457    }
5458
5459    private final boolean killPackageProcessesLocked(String packageName, int appId,
5460            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5461            boolean doit, boolean evenPersistent, String reason) {
5462        ArrayList<ProcessRecord> procs = new ArrayList<>();
5463
5464        // Remove all processes this package may have touched: all with the
5465        // same UID (except for the system or root user), and all whose name
5466        // matches the package name.
5467        final int NP = mProcessNames.getMap().size();
5468        for (int ip=0; ip<NP; ip++) {
5469            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5470            final int NA = apps.size();
5471            for (int ia=0; ia<NA; ia++) {
5472                ProcessRecord app = apps.valueAt(ia);
5473                if (app.persistent && !evenPersistent) {
5474                    // we don't kill persistent processes
5475                    continue;
5476                }
5477                if (app.removed) {
5478                    if (doit) {
5479                        procs.add(app);
5480                    }
5481                    continue;
5482                }
5483
5484                // Skip process if it doesn't meet our oom adj requirement.
5485                if (app.setAdj < minOomAdj) {
5486                    continue;
5487                }
5488
5489                // If no package is specified, we call all processes under the
5490                // give user id.
5491                if (packageName == null) {
5492                    if (app.userId != userId) {
5493                        continue;
5494                    }
5495                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5496                        continue;
5497                    }
5498                // Package has been specified, we want to hit all processes
5499                // that match it.  We need to qualify this by the processes
5500                // that are running under the specified app and user ID.
5501                } else {
5502                    final boolean isDep = app.pkgDeps != null
5503                            && app.pkgDeps.contains(packageName);
5504                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5505                        continue;
5506                    }
5507                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5508                        continue;
5509                    }
5510                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5511                        continue;
5512                    }
5513                }
5514
5515                // Process has passed all conditions, kill it!
5516                if (!doit) {
5517                    return true;
5518                }
5519                app.removed = true;
5520                procs.add(app);
5521            }
5522        }
5523
5524        int N = procs.size();
5525        for (int i=0; i<N; i++) {
5526            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5527        }
5528        updateOomAdjLocked();
5529        return N > 0;
5530    }
5531
5532    private void cleanupDisabledPackageComponentsLocked(
5533            String packageName, int userId, String[] changedClasses) {
5534
5535        Set<String> disabledClasses = null;
5536        boolean packageDisabled = false;
5537        IPackageManager pm = AppGlobals.getPackageManager();
5538
5539        if (changedClasses == null) {
5540            // Nothing changed...
5541            return;
5542        }
5543
5544        // Determine enable/disable state of the package and its components.
5545        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5546        for (int i = changedClasses.length - 1; i >= 0; i--) {
5547            final String changedClass = changedClasses[i];
5548
5549            if (changedClass.equals(packageName)) {
5550                try {
5551                    // Entire package setting changed
5552                    enabled = pm.getApplicationEnabledSetting(packageName,
5553                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5554                } catch (Exception e) {
5555                    // No such package/component; probably racing with uninstall.  In any
5556                    // event it means we have nothing further to do here.
5557                    return;
5558                }
5559                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5560                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5561                if (packageDisabled) {
5562                    // Entire package is disabled.
5563                    // No need to continue to check component states.
5564                    disabledClasses = null;
5565                    break;
5566                }
5567            } else {
5568                try {
5569                    enabled = pm.getComponentEnabledSetting(
5570                            new ComponentName(packageName, changedClass),
5571                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5572                } catch (Exception e) {
5573                    // As above, probably racing with uninstall.
5574                    return;
5575                }
5576                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5577                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5578                    if (disabledClasses == null) {
5579                        disabledClasses = new ArraySet<>(changedClasses.length);
5580                    }
5581                    disabledClasses.add(changedClass);
5582                }
5583            }
5584        }
5585
5586        if (!packageDisabled && disabledClasses == null) {
5587            // Nothing to do here...
5588            return;
5589        }
5590
5591        // Clean-up disabled activities.
5592        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5593                packageName, disabledClasses, true, false, userId) && mBooted) {
5594            mStackSupervisor.resumeTopActivitiesLocked();
5595            mStackSupervisor.scheduleIdleLocked();
5596        }
5597
5598        // Clean-up disabled tasks
5599        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5600
5601        // Clean-up disabled services.
5602        mServices.bringDownDisabledPackageServicesLocked(
5603                packageName, disabledClasses, userId, false, true);
5604
5605        // Clean-up disabled providers.
5606        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5607        mProviderMap.collectPackageProvidersLocked(
5608                packageName, disabledClasses, true, false, userId, providers);
5609        for (int i = providers.size() - 1; i >= 0; i--) {
5610            removeDyingProviderLocked(null, providers.get(i), true);
5611        }
5612
5613        // Clean-up disabled broadcast receivers.
5614        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5615            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5616                    packageName, disabledClasses, userId, true);
5617        }
5618
5619    }
5620
5621    private final boolean forceStopPackageLocked(String packageName, int appId,
5622            boolean callerWillRestart, boolean purgeCache, boolean doit,
5623            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5624        int i;
5625
5626        if (userId == UserHandle.USER_ALL && packageName == null) {
5627            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5628        }
5629
5630        if (appId < 0 && packageName != null) {
5631            try {
5632                appId = UserHandle.getAppId(
5633                        AppGlobals.getPackageManager().getPackageUid(packageName, 0));
5634            } catch (RemoteException e) {
5635            }
5636        }
5637
5638        if (doit) {
5639            if (packageName != null) {
5640                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5641                        + " user=" + userId + ": " + reason);
5642            } else {
5643                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5644            }
5645
5646            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5647            for (int ip = pmap.size() - 1; ip >= 0; ip--) {
5648                SparseArray<Long> ba = pmap.valueAt(ip);
5649                for (i = ba.size() - 1; i >= 0; i--) {
5650                    boolean remove = false;
5651                    final int entUid = ba.keyAt(i);
5652                    if (packageName != null) {
5653                        if (userId == UserHandle.USER_ALL) {
5654                            if (UserHandle.getAppId(entUid) == appId) {
5655                                remove = true;
5656                            }
5657                        } else {
5658                            if (entUid == UserHandle.getUid(userId, appId)) {
5659                                remove = true;
5660                            }
5661                        }
5662                    } else if (UserHandle.getUserId(entUid) == userId) {
5663                        remove = true;
5664                    }
5665                    if (remove) {
5666                        ba.removeAt(i);
5667                    }
5668                }
5669                if (ba.size() == 0) {
5670                    pmap.removeAt(ip);
5671                }
5672            }
5673        }
5674
5675        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5676                -100, callerWillRestart, true, doit, evenPersistent,
5677                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5678
5679        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5680                packageName, null, doit, evenPersistent, userId)) {
5681            if (!doit) {
5682                return true;
5683            }
5684            didSomething = true;
5685        }
5686
5687        if (mServices.bringDownDisabledPackageServicesLocked(
5688                packageName, null, userId, evenPersistent, doit)) {
5689            if (!doit) {
5690                return true;
5691            }
5692            didSomething = true;
5693        }
5694
5695        if (packageName == null) {
5696            // Remove all sticky broadcasts from this user.
5697            mStickyBroadcasts.remove(userId);
5698        }
5699
5700        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5701        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5702                userId, providers)) {
5703            if (!doit) {
5704                return true;
5705            }
5706            didSomething = true;
5707        }
5708        for (i = providers.size() - 1; i >= 0; i--) {
5709            removeDyingProviderLocked(null, providers.get(i), true);
5710        }
5711
5712        // Remove transient permissions granted from/to this package/user
5713        removeUriPermissionsForPackageLocked(packageName, userId, false);
5714
5715        if (doit) {
5716            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
5717                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5718                        packageName, null, userId, doit);
5719            }
5720        }
5721
5722        if (packageName == null || uninstalling) {
5723            // Remove pending intents.  For now we only do this when force
5724            // stopping users, because we have some problems when doing this
5725            // for packages -- app widgets are not currently cleaned up for
5726            // such packages, so they can be left with bad pending intents.
5727            if (mIntentSenderRecords.size() > 0) {
5728                Iterator<WeakReference<PendingIntentRecord>> it
5729                        = mIntentSenderRecords.values().iterator();
5730                while (it.hasNext()) {
5731                    WeakReference<PendingIntentRecord> wpir = it.next();
5732                    if (wpir == null) {
5733                        it.remove();
5734                        continue;
5735                    }
5736                    PendingIntentRecord pir = wpir.get();
5737                    if (pir == null) {
5738                        it.remove();
5739                        continue;
5740                    }
5741                    if (packageName == null) {
5742                        // Stopping user, remove all objects for the user.
5743                        if (pir.key.userId != userId) {
5744                            // Not the same user, skip it.
5745                            continue;
5746                        }
5747                    } else {
5748                        if (UserHandle.getAppId(pir.uid) != appId) {
5749                            // Different app id, skip it.
5750                            continue;
5751                        }
5752                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5753                            // Different user, skip it.
5754                            continue;
5755                        }
5756                        if (!pir.key.packageName.equals(packageName)) {
5757                            // Different package, skip it.
5758                            continue;
5759                        }
5760                    }
5761                    if (!doit) {
5762                        return true;
5763                    }
5764                    didSomething = true;
5765                    it.remove();
5766                    pir.canceled = true;
5767                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5768                        pir.key.activity.pendingResults.remove(pir.ref);
5769                    }
5770                }
5771            }
5772        }
5773
5774        if (doit) {
5775            if (purgeCache && packageName != null) {
5776                AttributeCache ac = AttributeCache.instance();
5777                if (ac != null) {
5778                    ac.removePackage(packageName);
5779                }
5780            }
5781            if (mBooted) {
5782                mStackSupervisor.resumeTopActivitiesLocked();
5783                mStackSupervisor.scheduleIdleLocked();
5784            }
5785        }
5786
5787        return didSomething;
5788    }
5789
5790    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
5791        ProcessRecord old = mProcessNames.remove(name, uid);
5792        if (old != null) {
5793            old.uidRecord.numProcs--;
5794            if (old.uidRecord.numProcs == 0) {
5795                // No more processes using this uid, tell clients it is gone.
5796                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5797                        "No more processes in " + old.uidRecord);
5798                enqueueUidChangeLocked(old.uidRecord, true);
5799                mActiveUids.remove(uid);
5800            }
5801            old.uidRecord = null;
5802        }
5803        mIsolatedProcesses.remove(uid);
5804        return old;
5805    }
5806
5807    private final void addProcessNameLocked(ProcessRecord proc) {
5808        // We shouldn't already have a process under this name, but just in case we
5809        // need to clean up whatever may be there now.
5810        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
5811        if (old != null) {
5812            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
5813        }
5814        UidRecord uidRec = mActiveUids.get(proc.uid);
5815        if (uidRec == null) {
5816            uidRec = new UidRecord(proc.uid);
5817            // This is the first appearance of the uid, report it now!
5818            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5819                    "Creating new process uid: " + uidRec);
5820            mActiveUids.put(proc.uid, uidRec);
5821            enqueueUidChangeLocked(uidRec, false);
5822        }
5823        proc.uidRecord = uidRec;
5824        uidRec.numProcs++;
5825        mProcessNames.put(proc.processName, proc.uid, proc);
5826        if (proc.isolated) {
5827            mIsolatedProcesses.put(proc.uid, proc);
5828        }
5829    }
5830
5831    private final boolean removeProcessLocked(ProcessRecord app,
5832            boolean callerWillRestart, boolean allowRestart, String reason) {
5833        final String name = app.processName;
5834        final int uid = app.uid;
5835        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
5836            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
5837
5838        removeProcessNameLocked(name, uid);
5839        if (mHeavyWeightProcess == app) {
5840            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5841                    mHeavyWeightProcess.userId, 0));
5842            mHeavyWeightProcess = null;
5843        }
5844        boolean needRestart = false;
5845        if (app.pid > 0 && app.pid != MY_PID) {
5846            int pid = app.pid;
5847            synchronized (mPidsSelfLocked) {
5848                mPidsSelfLocked.remove(pid);
5849                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5850            }
5851            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5852            if (app.isolated) {
5853                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5854            }
5855            boolean willRestart = false;
5856            if (app.persistent && !app.isolated) {
5857                if (!callerWillRestart) {
5858                    willRestart = true;
5859                } else {
5860                    needRestart = true;
5861                }
5862            }
5863            app.kill(reason, true);
5864            handleAppDiedLocked(app, willRestart, allowRestart);
5865            if (willRestart) {
5866                removeLruProcessLocked(app);
5867                addAppLocked(app.info, false, null /* ABI override */);
5868            }
5869        } else {
5870            mRemovedProcesses.add(app);
5871        }
5872
5873        return needRestart;
5874    }
5875
5876    private final void processStartTimedOutLocked(ProcessRecord app) {
5877        final int pid = app.pid;
5878        boolean gone = false;
5879        synchronized (mPidsSelfLocked) {
5880            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5881            if (knownApp != null && knownApp.thread == null) {
5882                mPidsSelfLocked.remove(pid);
5883                gone = true;
5884            }
5885        }
5886
5887        if (gone) {
5888            Slog.w(TAG, "Process " + app + " failed to attach");
5889            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5890                    pid, app.uid, app.processName);
5891            removeProcessNameLocked(app.processName, app.uid);
5892            if (mHeavyWeightProcess == app) {
5893                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5894                        mHeavyWeightProcess.userId, 0));
5895                mHeavyWeightProcess = null;
5896            }
5897            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5898            if (app.isolated) {
5899                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5900            }
5901            // Take care of any launching providers waiting for this process.
5902            checkAppInLaunchingProvidersLocked(app, true);
5903            // Take care of any services that are waiting for the process.
5904            mServices.processStartTimedOutLocked(app);
5905            app.kill("start timeout", true);
5906            removeLruProcessLocked(app);
5907            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5908                Slog.w(TAG, "Unattached app died before backup, skipping");
5909                try {
5910                    IBackupManager bm = IBackupManager.Stub.asInterface(
5911                            ServiceManager.getService(Context.BACKUP_SERVICE));
5912                    bm.agentDisconnected(app.info.packageName);
5913                } catch (RemoteException e) {
5914                    // Can't happen; the backup manager is local
5915                }
5916            }
5917            if (isPendingBroadcastProcessLocked(pid)) {
5918                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5919                skipPendingBroadcastLocked(pid);
5920            }
5921        } else {
5922            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5923        }
5924    }
5925
5926    private final boolean attachApplicationLocked(IApplicationThread thread,
5927            int pid) {
5928
5929        // Find the application record that is being attached...  either via
5930        // the pid if we are running in multiple processes, or just pull the
5931        // next app record if we are emulating process with anonymous threads.
5932        ProcessRecord app;
5933        if (pid != MY_PID && pid >= 0) {
5934            synchronized (mPidsSelfLocked) {
5935                app = mPidsSelfLocked.get(pid);
5936            }
5937        } else {
5938            app = null;
5939        }
5940
5941        if (app == null) {
5942            Slog.w(TAG, "No pending application record for pid " + pid
5943                    + " (IApplicationThread " + thread + "); dropping process");
5944            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5945            if (pid > 0 && pid != MY_PID) {
5946                Process.killProcessQuiet(pid);
5947                //TODO: killProcessGroup(app.info.uid, pid);
5948            } else {
5949                try {
5950                    thread.scheduleExit();
5951                } catch (Exception e) {
5952                    // Ignore exceptions.
5953                }
5954            }
5955            return false;
5956        }
5957
5958        // If this application record is still attached to a previous
5959        // process, clean it up now.
5960        if (app.thread != null) {
5961            handleAppDiedLocked(app, true, true);
5962        }
5963
5964        // Tell the process all about itself.
5965
5966        if (DEBUG_ALL) Slog.v(
5967                TAG, "Binding process pid " + pid + " to record " + app);
5968
5969        final String processName = app.processName;
5970        try {
5971            AppDeathRecipient adr = new AppDeathRecipient(
5972                    app, pid, thread);
5973            thread.asBinder().linkToDeath(adr, 0);
5974            app.deathRecipient = adr;
5975        } catch (RemoteException e) {
5976            app.resetPackageList(mProcessStats);
5977            startProcessLocked(app, "link fail", processName);
5978            return false;
5979        }
5980
5981        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5982
5983        app.makeActive(thread, mProcessStats);
5984        app.curAdj = app.setAdj = -100;
5985        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5986        app.forcingToForeground = null;
5987        updateProcessForegroundLocked(app, false, false);
5988        app.hasShownUi = false;
5989        app.debugging = false;
5990        app.cached = false;
5991        app.killedByAm = false;
5992
5993        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5994
5995        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5996        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5997
5998        if (!normalMode) {
5999            Slog.i(TAG, "Launching preboot mode app: " + app);
6000        }
6001
6002        if (DEBUG_ALL) Slog.v(
6003            TAG, "New app record " + app
6004            + " thread=" + thread.asBinder() + " pid=" + pid);
6005        try {
6006            int testMode = IApplicationThread.DEBUG_OFF;
6007            if (mDebugApp != null && mDebugApp.equals(processName)) {
6008                testMode = mWaitForDebugger
6009                    ? IApplicationThread.DEBUG_WAIT
6010                    : IApplicationThread.DEBUG_ON;
6011                app.debugging = true;
6012                if (mDebugTransient) {
6013                    mDebugApp = mOrigDebugApp;
6014                    mWaitForDebugger = mOrigWaitForDebugger;
6015                }
6016            }
6017            String profileFile = app.instrumentationProfileFile;
6018            ParcelFileDescriptor profileFd = null;
6019            int samplingInterval = 0;
6020            boolean profileAutoStop = false;
6021            if (mProfileApp != null && mProfileApp.equals(processName)) {
6022                mProfileProc = app;
6023                profileFile = mProfileFile;
6024                profileFd = mProfileFd;
6025                samplingInterval = mSamplingInterval;
6026                profileAutoStop = mAutoStopProfiler;
6027            }
6028            boolean enableOpenGlTrace = false;
6029            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6030                enableOpenGlTrace = true;
6031                mOpenGlTraceApp = null;
6032            }
6033
6034            // If the app is being launched for restore or full backup, set it up specially
6035            boolean isRestrictedBackupMode = false;
6036            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6037                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6038                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6039                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6040            }
6041
6042            ensurePackageDexOpt(app.instrumentationInfo != null
6043                    ? app.instrumentationInfo.packageName
6044                    : app.info.packageName);
6045            if (app.instrumentationClass != null) {
6046                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6047            }
6048            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6049                    + processName + " with config " + mConfiguration);
6050            ApplicationInfo appInfo = app.instrumentationInfo != null
6051                    ? app.instrumentationInfo : app.info;
6052            app.compat = compatibilityInfoForPackageLocked(appInfo);
6053            if (profileFd != null) {
6054                profileFd = profileFd.dup();
6055            }
6056            ProfilerInfo profilerInfo = profileFile == null ? null
6057                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6058            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6059                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6060                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6061                    isRestrictedBackupMode || !normalMode, app.persistent,
6062                    new Configuration(mConfiguration), app.compat,
6063                    getCommonServicesLocked(app.isolated),
6064                    mCoreSettingsObserver.getCoreSettingsLocked());
6065            updateLruProcessLocked(app, false, null);
6066            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6067        } catch (Exception e) {
6068            // todo: Yikes!  What should we do?  For now we will try to
6069            // start another process, but that could easily get us in
6070            // an infinite loop of restarting processes...
6071            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6072
6073            app.resetPackageList(mProcessStats);
6074            app.unlinkDeathRecipient();
6075            startProcessLocked(app, "bind fail", processName);
6076            return false;
6077        }
6078
6079        // Remove this record from the list of starting applications.
6080        mPersistentStartingProcesses.remove(app);
6081        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6082                "Attach application locked removing on hold: " + app);
6083        mProcessesOnHold.remove(app);
6084
6085        boolean badApp = false;
6086        boolean didSomething = false;
6087
6088        // See if the top visible activity is waiting to run in this process...
6089        if (normalMode) {
6090            try {
6091                if (mStackSupervisor.attachApplicationLocked(app)) {
6092                    didSomething = true;
6093                }
6094            } catch (Exception e) {
6095                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6096                badApp = true;
6097            }
6098        }
6099
6100        // Find any services that should be running in this process...
6101        if (!badApp) {
6102            try {
6103                didSomething |= mServices.attachApplicationLocked(app, processName);
6104            } catch (Exception e) {
6105                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6106                badApp = true;
6107            }
6108        }
6109
6110        // Check if a next-broadcast receiver is in this process...
6111        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6112            try {
6113                didSomething |= sendPendingBroadcastsLocked(app);
6114            } catch (Exception e) {
6115                // If the app died trying to launch the receiver we declare it 'bad'
6116                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6117                badApp = true;
6118            }
6119        }
6120
6121        // Check whether the next backup agent is in this process...
6122        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6123            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6124                    "New app is backup target, launching agent for " + app);
6125            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6126            try {
6127                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6128                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6129                        mBackupTarget.backupMode);
6130            } catch (Exception e) {
6131                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6132                badApp = true;
6133            }
6134        }
6135
6136        if (badApp) {
6137            app.kill("error during init", true);
6138            handleAppDiedLocked(app, false, true);
6139            return false;
6140        }
6141
6142        if (!didSomething) {
6143            updateOomAdjLocked();
6144        }
6145
6146        return true;
6147    }
6148
6149    @Override
6150    public final void attachApplication(IApplicationThread thread) {
6151        synchronized (this) {
6152            int callingPid = Binder.getCallingPid();
6153            final long origId = Binder.clearCallingIdentity();
6154            attachApplicationLocked(thread, callingPid);
6155            Binder.restoreCallingIdentity(origId);
6156        }
6157    }
6158
6159    @Override
6160    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6161        final long origId = Binder.clearCallingIdentity();
6162        synchronized (this) {
6163            ActivityStack stack = ActivityRecord.getStackLocked(token);
6164            if (stack != null) {
6165                ActivityRecord r =
6166                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6167                if (stopProfiling) {
6168                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6169                        try {
6170                            mProfileFd.close();
6171                        } catch (IOException e) {
6172                        }
6173                        clearProfilerLocked();
6174                    }
6175                }
6176            }
6177        }
6178        Binder.restoreCallingIdentity(origId);
6179    }
6180
6181    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6182        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6183                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6184    }
6185
6186    void enableScreenAfterBoot() {
6187        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6188                SystemClock.uptimeMillis());
6189        mWindowManager.enableScreenAfterBoot();
6190
6191        synchronized (this) {
6192            updateEventDispatchingLocked();
6193        }
6194    }
6195
6196    @Override
6197    public void showBootMessage(final CharSequence msg, final boolean always) {
6198        if (Binder.getCallingUid() != Process.myUid()) {
6199            // These days only the core system can call this, so apps can't get in
6200            // the way of what we show about running them.
6201        }
6202        mWindowManager.showBootMessage(msg, always);
6203    }
6204
6205    @Override
6206    public void keyguardWaitingForActivityDrawn() {
6207        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6208        final long token = Binder.clearCallingIdentity();
6209        try {
6210            synchronized (this) {
6211                if (DEBUG_LOCKSCREEN) logLockScreen("");
6212                mWindowManager.keyguardWaitingForActivityDrawn();
6213                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6214                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6215                    updateSleepIfNeededLocked();
6216                }
6217            }
6218        } finally {
6219            Binder.restoreCallingIdentity(token);
6220        }
6221    }
6222
6223    @Override
6224    public void keyguardGoingAway(boolean disableWindowAnimations,
6225            boolean keyguardGoingToNotificationShade) {
6226        enforceNotIsolatedCaller("keyguardGoingAway");
6227        final long token = Binder.clearCallingIdentity();
6228        try {
6229            synchronized (this) {
6230                if (DEBUG_LOCKSCREEN) logLockScreen("");
6231                mWindowManager.keyguardGoingAway(disableWindowAnimations,
6232                        keyguardGoingToNotificationShade);
6233                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6234                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6235                    updateSleepIfNeededLocked();
6236                }
6237            }
6238        } finally {
6239            Binder.restoreCallingIdentity(token);
6240        }
6241    }
6242
6243    final void finishBooting() {
6244        synchronized (this) {
6245            if (!mBootAnimationComplete) {
6246                mCallFinishBooting = true;
6247                return;
6248            }
6249            mCallFinishBooting = false;
6250        }
6251
6252        ArraySet<String> completedIsas = new ArraySet<String>();
6253        for (String abi : Build.SUPPORTED_ABIS) {
6254            Process.establishZygoteConnectionForAbi(abi);
6255            final String instructionSet = VMRuntime.getInstructionSet(abi);
6256            if (!completedIsas.contains(instructionSet)) {
6257                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6258                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6259                }
6260                completedIsas.add(instructionSet);
6261            }
6262        }
6263
6264        IntentFilter pkgFilter = new IntentFilter();
6265        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6266        pkgFilter.addDataScheme("package");
6267        mContext.registerReceiver(new BroadcastReceiver() {
6268            @Override
6269            public void onReceive(Context context, Intent intent) {
6270                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6271                if (pkgs != null) {
6272                    for (String pkg : pkgs) {
6273                        synchronized (ActivityManagerService.this) {
6274                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6275                                    0, "query restart")) {
6276                                setResultCode(Activity.RESULT_OK);
6277                                return;
6278                            }
6279                        }
6280                    }
6281                }
6282            }
6283        }, pkgFilter);
6284
6285        IntentFilter dumpheapFilter = new IntentFilter();
6286        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6287        mContext.registerReceiver(new BroadcastReceiver() {
6288            @Override
6289            public void onReceive(Context context, Intent intent) {
6290                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6291                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6292                } else {
6293                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6294                }
6295            }
6296        }, dumpheapFilter);
6297
6298        // Let system services know.
6299        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6300
6301        synchronized (this) {
6302            // Ensure that any processes we had put on hold are now started
6303            // up.
6304            final int NP = mProcessesOnHold.size();
6305            if (NP > 0) {
6306                ArrayList<ProcessRecord> procs =
6307                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6308                for (int ip=0; ip<NP; ip++) {
6309                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6310                            + procs.get(ip));
6311                    startProcessLocked(procs.get(ip), "on-hold", null);
6312                }
6313            }
6314
6315            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6316                // Start looking for apps that are abusing wake locks.
6317                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6318                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6319                // Tell anyone interested that we are done booting!
6320                SystemProperties.set("sys.boot_completed", "1");
6321
6322                // And trigger dev.bootcomplete if we are not showing encryption progress
6323                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6324                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6325                    SystemProperties.set("dev.bootcomplete", "1");
6326                }
6327                for (int i=0; i<mStartedUsers.size(); i++) {
6328                    UserState uss = mStartedUsers.valueAt(i);
6329                    if (uss.mState == UserState.STATE_BOOTING) {
6330                        uss.mState = UserState.STATE_RUNNING;
6331                        final int userId = mStartedUsers.keyAt(i);
6332                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6333                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6334                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6335                        broadcastIntentLocked(null, null, intent, null,
6336                                new IIntentReceiver.Stub() {
6337                                    @Override
6338                                    public void performReceive(Intent intent, int resultCode,
6339                                            String data, Bundle extras, boolean ordered,
6340                                            boolean sticky, int sendingUser) {
6341                                        synchronized (ActivityManagerService.this) {
6342                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6343                                                    true, false);
6344                                        }
6345                                    }
6346                                },
6347                                0, null, null,
6348                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6349                                AppOpsManager.OP_NONE, null, true, false,
6350                                MY_PID, Process.SYSTEM_UID, userId);
6351                    }
6352                }
6353                scheduleStartProfilesLocked();
6354            }
6355        }
6356    }
6357
6358    @Override
6359    public void bootAnimationComplete() {
6360        final boolean callFinishBooting;
6361        synchronized (this) {
6362            callFinishBooting = mCallFinishBooting;
6363            mBootAnimationComplete = true;
6364        }
6365        if (callFinishBooting) {
6366            finishBooting();
6367        }
6368    }
6369
6370    final void ensureBootCompleted() {
6371        boolean booting;
6372        boolean enableScreen;
6373        synchronized (this) {
6374            booting = mBooting;
6375            mBooting = false;
6376            enableScreen = !mBooted;
6377            mBooted = true;
6378        }
6379
6380        if (booting) {
6381            finishBooting();
6382        }
6383
6384        if (enableScreen) {
6385            enableScreenAfterBoot();
6386        }
6387    }
6388
6389    @Override
6390    public final void activityResumed(IBinder token) {
6391        final long origId = Binder.clearCallingIdentity();
6392        synchronized(this) {
6393            ActivityStack stack = ActivityRecord.getStackLocked(token);
6394            if (stack != null) {
6395                ActivityRecord.activityResumedLocked(token);
6396            }
6397        }
6398        Binder.restoreCallingIdentity(origId);
6399    }
6400
6401    @Override
6402    public final void activityPaused(IBinder token) {
6403        final long origId = Binder.clearCallingIdentity();
6404        synchronized(this) {
6405            ActivityStack stack = ActivityRecord.getStackLocked(token);
6406            if (stack != null) {
6407                stack.activityPausedLocked(token, false);
6408            }
6409        }
6410        Binder.restoreCallingIdentity(origId);
6411    }
6412
6413    @Override
6414    public final void activityStopped(IBinder token, Bundle icicle,
6415            PersistableBundle persistentState, CharSequence description) {
6416        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6417
6418        // Refuse possible leaked file descriptors
6419        if (icicle != null && icicle.hasFileDescriptors()) {
6420            throw new IllegalArgumentException("File descriptors passed in Bundle");
6421        }
6422
6423        final long origId = Binder.clearCallingIdentity();
6424
6425        synchronized (this) {
6426            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6427            if (r != null) {
6428                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6429            }
6430        }
6431
6432        trimApplications();
6433
6434        Binder.restoreCallingIdentity(origId);
6435    }
6436
6437    @Override
6438    public final void activityDestroyed(IBinder token) {
6439        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6440        synchronized (this) {
6441            ActivityStack stack = ActivityRecord.getStackLocked(token);
6442            if (stack != null) {
6443                stack.activityDestroyedLocked(token, "activityDestroyed");
6444            }
6445        }
6446    }
6447
6448    @Override
6449    public final void backgroundResourcesReleased(IBinder token) {
6450        final long origId = Binder.clearCallingIdentity();
6451        try {
6452            synchronized (this) {
6453                ActivityStack stack = ActivityRecord.getStackLocked(token);
6454                if (stack != null) {
6455                    stack.backgroundResourcesReleased();
6456                }
6457            }
6458        } finally {
6459            Binder.restoreCallingIdentity(origId);
6460        }
6461    }
6462
6463    @Override
6464    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6465        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6466    }
6467
6468    @Override
6469    public final void notifyEnterAnimationComplete(IBinder token) {
6470        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6471    }
6472
6473    @Override
6474    public String getCallingPackage(IBinder token) {
6475        synchronized (this) {
6476            ActivityRecord r = getCallingRecordLocked(token);
6477            return r != null ? r.info.packageName : null;
6478        }
6479    }
6480
6481    @Override
6482    public ComponentName getCallingActivity(IBinder token) {
6483        synchronized (this) {
6484            ActivityRecord r = getCallingRecordLocked(token);
6485            return r != null ? r.intent.getComponent() : null;
6486        }
6487    }
6488
6489    private ActivityRecord getCallingRecordLocked(IBinder token) {
6490        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6491        if (r == null) {
6492            return null;
6493        }
6494        return r.resultTo;
6495    }
6496
6497    @Override
6498    public ComponentName getActivityClassForToken(IBinder token) {
6499        synchronized(this) {
6500            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6501            if (r == null) {
6502                return null;
6503            }
6504            return r.intent.getComponent();
6505        }
6506    }
6507
6508    @Override
6509    public String getPackageForToken(IBinder token) {
6510        synchronized(this) {
6511            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6512            if (r == null) {
6513                return null;
6514            }
6515            return r.packageName;
6516        }
6517    }
6518
6519    @Override
6520    public IIntentSender getIntentSender(int type,
6521            String packageName, IBinder token, String resultWho,
6522            int requestCode, Intent[] intents, String[] resolvedTypes,
6523            int flags, Bundle options, int userId) {
6524        enforceNotIsolatedCaller("getIntentSender");
6525        // Refuse possible leaked file descriptors
6526        if (intents != null) {
6527            if (intents.length < 1) {
6528                throw new IllegalArgumentException("Intents array length must be >= 1");
6529            }
6530            for (int i=0; i<intents.length; i++) {
6531                Intent intent = intents[i];
6532                if (intent != null) {
6533                    if (intent.hasFileDescriptors()) {
6534                        throw new IllegalArgumentException("File descriptors passed in Intent");
6535                    }
6536                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6537                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6538                        throw new IllegalArgumentException(
6539                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6540                    }
6541                    intents[i] = new Intent(intent);
6542                }
6543            }
6544            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6545                throw new IllegalArgumentException(
6546                        "Intent array length does not match resolvedTypes length");
6547            }
6548        }
6549        if (options != null) {
6550            if (options.hasFileDescriptors()) {
6551                throw new IllegalArgumentException("File descriptors passed in options");
6552            }
6553        }
6554
6555        synchronized(this) {
6556            int callingUid = Binder.getCallingUid();
6557            int origUserId = userId;
6558            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6559                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6560                    ALLOW_NON_FULL, "getIntentSender", null);
6561            if (origUserId == UserHandle.USER_CURRENT) {
6562                // We don't want to evaluate this until the pending intent is
6563                // actually executed.  However, we do want to always do the
6564                // security checking for it above.
6565                userId = UserHandle.USER_CURRENT;
6566            }
6567            try {
6568                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6569                    int uid = AppGlobals.getPackageManager()
6570                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6571                    if (!UserHandle.isSameApp(callingUid, uid)) {
6572                        String msg = "Permission Denial: getIntentSender() from pid="
6573                            + Binder.getCallingPid()
6574                            + ", uid=" + Binder.getCallingUid()
6575                            + ", (need uid=" + uid + ")"
6576                            + " is not allowed to send as package " + packageName;
6577                        Slog.w(TAG, msg);
6578                        throw new SecurityException(msg);
6579                    }
6580                }
6581
6582                return getIntentSenderLocked(type, packageName, callingUid, userId,
6583                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6584
6585            } catch (RemoteException e) {
6586                throw new SecurityException(e);
6587            }
6588        }
6589    }
6590
6591    IIntentSender getIntentSenderLocked(int type, String packageName,
6592            int callingUid, int userId, IBinder token, String resultWho,
6593            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6594            Bundle options) {
6595        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6596        ActivityRecord activity = null;
6597        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6598            activity = ActivityRecord.isInStackLocked(token);
6599            if (activity == null) {
6600                return null;
6601            }
6602            if (activity.finishing) {
6603                return null;
6604            }
6605        }
6606
6607        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6608        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6609        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6610        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6611                |PendingIntent.FLAG_UPDATE_CURRENT);
6612
6613        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6614                type, packageName, activity, resultWho,
6615                requestCode, intents, resolvedTypes, flags, options, userId);
6616        WeakReference<PendingIntentRecord> ref;
6617        ref = mIntentSenderRecords.get(key);
6618        PendingIntentRecord rec = ref != null ? ref.get() : null;
6619        if (rec != null) {
6620            if (!cancelCurrent) {
6621                if (updateCurrent) {
6622                    if (rec.key.requestIntent != null) {
6623                        rec.key.requestIntent.replaceExtras(intents != null ?
6624                                intents[intents.length - 1] : null);
6625                    }
6626                    if (intents != null) {
6627                        intents[intents.length-1] = rec.key.requestIntent;
6628                        rec.key.allIntents = intents;
6629                        rec.key.allResolvedTypes = resolvedTypes;
6630                    } else {
6631                        rec.key.allIntents = null;
6632                        rec.key.allResolvedTypes = null;
6633                    }
6634                }
6635                return rec;
6636            }
6637            rec.canceled = true;
6638            mIntentSenderRecords.remove(key);
6639        }
6640        if (noCreate) {
6641            return rec;
6642        }
6643        rec = new PendingIntentRecord(this, key, callingUid);
6644        mIntentSenderRecords.put(key, rec.ref);
6645        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6646            if (activity.pendingResults == null) {
6647                activity.pendingResults
6648                        = new HashSet<WeakReference<PendingIntentRecord>>();
6649            }
6650            activity.pendingResults.add(rec.ref);
6651        }
6652        return rec;
6653    }
6654
6655    @Override
6656    public void cancelIntentSender(IIntentSender sender) {
6657        if (!(sender instanceof PendingIntentRecord)) {
6658            return;
6659        }
6660        synchronized(this) {
6661            PendingIntentRecord rec = (PendingIntentRecord)sender;
6662            try {
6663                int uid = AppGlobals.getPackageManager()
6664                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6665                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6666                    String msg = "Permission Denial: cancelIntentSender() from pid="
6667                        + Binder.getCallingPid()
6668                        + ", uid=" + Binder.getCallingUid()
6669                        + " is not allowed to cancel packges "
6670                        + rec.key.packageName;
6671                    Slog.w(TAG, msg);
6672                    throw new SecurityException(msg);
6673                }
6674            } catch (RemoteException e) {
6675                throw new SecurityException(e);
6676            }
6677            cancelIntentSenderLocked(rec, true);
6678        }
6679    }
6680
6681    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6682        rec.canceled = true;
6683        mIntentSenderRecords.remove(rec.key);
6684        if (cleanActivity && rec.key.activity != null) {
6685            rec.key.activity.pendingResults.remove(rec.ref);
6686        }
6687    }
6688
6689    @Override
6690    public String getPackageForIntentSender(IIntentSender pendingResult) {
6691        if (!(pendingResult instanceof PendingIntentRecord)) {
6692            return null;
6693        }
6694        try {
6695            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6696            return res.key.packageName;
6697        } catch (ClassCastException e) {
6698        }
6699        return null;
6700    }
6701
6702    @Override
6703    public int getUidForIntentSender(IIntentSender sender) {
6704        if (sender instanceof PendingIntentRecord) {
6705            try {
6706                PendingIntentRecord res = (PendingIntentRecord)sender;
6707                return res.uid;
6708            } catch (ClassCastException e) {
6709            }
6710        }
6711        return -1;
6712    }
6713
6714    @Override
6715    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6716        if (!(pendingResult instanceof PendingIntentRecord)) {
6717            return false;
6718        }
6719        try {
6720            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6721            if (res.key.allIntents == null) {
6722                return false;
6723            }
6724            for (int i=0; i<res.key.allIntents.length; i++) {
6725                Intent intent = res.key.allIntents[i];
6726                if (intent.getPackage() != null && intent.getComponent() != null) {
6727                    return false;
6728                }
6729            }
6730            return true;
6731        } catch (ClassCastException e) {
6732        }
6733        return false;
6734    }
6735
6736    @Override
6737    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6738        if (!(pendingResult instanceof PendingIntentRecord)) {
6739            return false;
6740        }
6741        try {
6742            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6743            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6744                return true;
6745            }
6746            return false;
6747        } catch (ClassCastException e) {
6748        }
6749        return false;
6750    }
6751
6752    @Override
6753    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6754        if (!(pendingResult instanceof PendingIntentRecord)) {
6755            return null;
6756        }
6757        try {
6758            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6759            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6760        } catch (ClassCastException e) {
6761        }
6762        return null;
6763    }
6764
6765    @Override
6766    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6767        if (!(pendingResult instanceof PendingIntentRecord)) {
6768            return null;
6769        }
6770        try {
6771            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6772            synchronized (this) {
6773                return getTagForIntentSenderLocked(res, prefix);
6774            }
6775        } catch (ClassCastException e) {
6776        }
6777        return null;
6778    }
6779
6780    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
6781        final Intent intent = res.key.requestIntent;
6782        if (intent != null) {
6783            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6784                    || res.lastTagPrefix.equals(prefix))) {
6785                return res.lastTag;
6786            }
6787            res.lastTagPrefix = prefix;
6788            final StringBuilder sb = new StringBuilder(128);
6789            if (prefix != null) {
6790                sb.append(prefix);
6791            }
6792            if (intent.getAction() != null) {
6793                sb.append(intent.getAction());
6794            } else if (intent.getComponent() != null) {
6795                intent.getComponent().appendShortString(sb);
6796            } else {
6797                sb.append("?");
6798            }
6799            return res.lastTag = sb.toString();
6800        }
6801        return null;
6802    }
6803
6804    @Override
6805    public void setProcessLimit(int max) {
6806        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6807                "setProcessLimit()");
6808        synchronized (this) {
6809            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6810            mProcessLimitOverride = max;
6811        }
6812        trimApplications();
6813    }
6814
6815    @Override
6816    public int getProcessLimit() {
6817        synchronized (this) {
6818            return mProcessLimitOverride;
6819        }
6820    }
6821
6822    void foregroundTokenDied(ForegroundToken token) {
6823        synchronized (ActivityManagerService.this) {
6824            synchronized (mPidsSelfLocked) {
6825                ForegroundToken cur
6826                    = mForegroundProcesses.get(token.pid);
6827                if (cur != token) {
6828                    return;
6829                }
6830                mForegroundProcesses.remove(token.pid);
6831                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6832                if (pr == null) {
6833                    return;
6834                }
6835                pr.forcingToForeground = null;
6836                updateProcessForegroundLocked(pr, false, false);
6837            }
6838            updateOomAdjLocked();
6839        }
6840    }
6841
6842    @Override
6843    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6844        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6845                "setProcessForeground()");
6846        synchronized(this) {
6847            boolean changed = false;
6848
6849            synchronized (mPidsSelfLocked) {
6850                ProcessRecord pr = mPidsSelfLocked.get(pid);
6851                if (pr == null && isForeground) {
6852                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6853                    return;
6854                }
6855                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6856                if (oldToken != null) {
6857                    oldToken.token.unlinkToDeath(oldToken, 0);
6858                    mForegroundProcesses.remove(pid);
6859                    if (pr != null) {
6860                        pr.forcingToForeground = null;
6861                    }
6862                    changed = true;
6863                }
6864                if (isForeground && token != null) {
6865                    ForegroundToken newToken = new ForegroundToken() {
6866                        @Override
6867                        public void binderDied() {
6868                            foregroundTokenDied(this);
6869                        }
6870                    };
6871                    newToken.pid = pid;
6872                    newToken.token = token;
6873                    try {
6874                        token.linkToDeath(newToken, 0);
6875                        mForegroundProcesses.put(pid, newToken);
6876                        pr.forcingToForeground = token;
6877                        changed = true;
6878                    } catch (RemoteException e) {
6879                        // If the process died while doing this, we will later
6880                        // do the cleanup with the process death link.
6881                    }
6882                }
6883            }
6884
6885            if (changed) {
6886                updateOomAdjLocked();
6887            }
6888        }
6889    }
6890
6891    // =========================================================
6892    // PROCESS INFO
6893    // =========================================================
6894
6895    static class ProcessInfoService extends IProcessInfoService.Stub {
6896        final ActivityManagerService mActivityManagerService;
6897        ProcessInfoService(ActivityManagerService activityManagerService) {
6898            mActivityManagerService = activityManagerService;
6899        }
6900
6901        @Override
6902        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
6903            mActivityManagerService.getProcessStatesForPIDs(/*in*/ pids, /*out*/ states);
6904        }
6905    }
6906
6907    /**
6908     * For each PID in the given input array, write the current process state
6909     * for that process into the output array, or -1 to indicate that no
6910     * process with the given PID exists.
6911     */
6912    public void getProcessStatesForPIDs(/*in*/ int[] pids, /*out*/ int[] states) {
6913        if (pids == null) {
6914            throw new NullPointerException("pids");
6915        } else if (states == null) {
6916            throw new NullPointerException("states");
6917        } else if (pids.length != states.length) {
6918            throw new IllegalArgumentException("input and output arrays have different lengths!");
6919        }
6920
6921        synchronized (mPidsSelfLocked) {
6922            for (int i = 0; i < pids.length; i++) {
6923                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
6924                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
6925                        pr.curProcState;
6926            }
6927        }
6928    }
6929
6930    // =========================================================
6931    // PERMISSIONS
6932    // =========================================================
6933
6934    static class PermissionController extends IPermissionController.Stub {
6935        ActivityManagerService mActivityManagerService;
6936        PermissionController(ActivityManagerService activityManagerService) {
6937            mActivityManagerService = activityManagerService;
6938        }
6939
6940        @Override
6941        public boolean checkPermission(String permission, int pid, int uid) {
6942            return mActivityManagerService.checkPermission(permission, pid,
6943                    uid) == PackageManager.PERMISSION_GRANTED;
6944        }
6945
6946        @Override
6947        public String[] getPackagesForUid(int uid) {
6948            return mActivityManagerService.mContext.getPackageManager()
6949                    .getPackagesForUid(uid);
6950        }
6951
6952        @Override
6953        public boolean isRuntimePermission(String permission) {
6954            try {
6955                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
6956                        .getPermissionInfo(permission, 0);
6957                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
6958            } catch (NameNotFoundException nnfe) {
6959                Slog.e(TAG, "No such permission: "+ permission, nnfe);
6960            }
6961            return false;
6962        }
6963    }
6964
6965    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6966        @Override
6967        public int checkComponentPermission(String permission, int pid, int uid,
6968                int owningUid, boolean exported) {
6969            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6970                    owningUid, exported);
6971        }
6972
6973        @Override
6974        public Object getAMSLock() {
6975            return ActivityManagerService.this;
6976        }
6977    }
6978
6979    /**
6980     * This can be called with or without the global lock held.
6981     */
6982    int checkComponentPermission(String permission, int pid, int uid,
6983            int owningUid, boolean exported) {
6984        if (pid == MY_PID) {
6985            return PackageManager.PERMISSION_GRANTED;
6986        }
6987        return ActivityManager.checkComponentPermission(permission, uid,
6988                owningUid, exported);
6989    }
6990
6991    /**
6992     * As the only public entry point for permissions checking, this method
6993     * can enforce the semantic that requesting a check on a null global
6994     * permission is automatically denied.  (Internally a null permission
6995     * string is used when calling {@link #checkComponentPermission} in cases
6996     * when only uid-based security is needed.)
6997     *
6998     * This can be called with or without the global lock held.
6999     */
7000    @Override
7001    public int checkPermission(String permission, int pid, int uid) {
7002        if (permission == null) {
7003            return PackageManager.PERMISSION_DENIED;
7004        }
7005        return checkComponentPermission(permission, pid, uid, -1, true);
7006    }
7007
7008    @Override
7009    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7010        if (permission == null) {
7011            return PackageManager.PERMISSION_DENIED;
7012        }
7013
7014        // We might be performing an operation on behalf of an indirect binder
7015        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7016        // client identity accordingly before proceeding.
7017        Identity tlsIdentity = sCallerIdentity.get();
7018        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7019            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7020                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7021            uid = tlsIdentity.uid;
7022            pid = tlsIdentity.pid;
7023        }
7024
7025        return checkComponentPermission(permission, pid, uid, -1, true);
7026    }
7027
7028    /**
7029     * Binder IPC calls go through the public entry point.
7030     * This can be called with or without the global lock held.
7031     */
7032    int checkCallingPermission(String permission) {
7033        return checkPermission(permission,
7034                Binder.getCallingPid(),
7035                UserHandle.getAppId(Binder.getCallingUid()));
7036    }
7037
7038    /**
7039     * This can be called with or without the global lock held.
7040     */
7041    void enforceCallingPermission(String permission, String func) {
7042        if (checkCallingPermission(permission)
7043                == PackageManager.PERMISSION_GRANTED) {
7044            return;
7045        }
7046
7047        String msg = "Permission Denial: " + func + " from pid="
7048                + Binder.getCallingPid()
7049                + ", uid=" + Binder.getCallingUid()
7050                + " requires " + permission;
7051        Slog.w(TAG, msg);
7052        throw new SecurityException(msg);
7053    }
7054
7055    /**
7056     * Determine if UID is holding permissions required to access {@link Uri} in
7057     * the given {@link ProviderInfo}. Final permission checking is always done
7058     * in {@link ContentProvider}.
7059     */
7060    private final boolean checkHoldingPermissionsLocked(
7061            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7062        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7063                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7064        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7065            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7066                    != PERMISSION_GRANTED) {
7067                return false;
7068            }
7069        }
7070        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7071    }
7072
7073    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7074            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7075        if (pi.applicationInfo.uid == uid) {
7076            return true;
7077        } else if (!pi.exported) {
7078            return false;
7079        }
7080
7081        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7082        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7083        try {
7084            // check if target holds top-level <provider> permissions
7085            if (!readMet && pi.readPermission != null && considerUidPermissions
7086                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7087                readMet = true;
7088            }
7089            if (!writeMet && pi.writePermission != null && considerUidPermissions
7090                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7091                writeMet = true;
7092            }
7093
7094            // track if unprotected read/write is allowed; any denied
7095            // <path-permission> below removes this ability
7096            boolean allowDefaultRead = pi.readPermission == null;
7097            boolean allowDefaultWrite = pi.writePermission == null;
7098
7099            // check if target holds any <path-permission> that match uri
7100            final PathPermission[] pps = pi.pathPermissions;
7101            if (pps != null) {
7102                final String path = grantUri.uri.getPath();
7103                int i = pps.length;
7104                while (i > 0 && (!readMet || !writeMet)) {
7105                    i--;
7106                    PathPermission pp = pps[i];
7107                    if (pp.match(path)) {
7108                        if (!readMet) {
7109                            final String pprperm = pp.getReadPermission();
7110                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7111                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7112                                    + ": match=" + pp.match(path)
7113                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7114                            if (pprperm != null) {
7115                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7116                                        == PERMISSION_GRANTED) {
7117                                    readMet = true;
7118                                } else {
7119                                    allowDefaultRead = false;
7120                                }
7121                            }
7122                        }
7123                        if (!writeMet) {
7124                            final String ppwperm = pp.getWritePermission();
7125                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7126                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7127                                    + ": match=" + pp.match(path)
7128                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7129                            if (ppwperm != null) {
7130                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7131                                        == PERMISSION_GRANTED) {
7132                                    writeMet = true;
7133                                } else {
7134                                    allowDefaultWrite = false;
7135                                }
7136                            }
7137                        }
7138                    }
7139                }
7140            }
7141
7142            // grant unprotected <provider> read/write, if not blocked by
7143            // <path-permission> above
7144            if (allowDefaultRead) readMet = true;
7145            if (allowDefaultWrite) writeMet = true;
7146
7147        } catch (RemoteException e) {
7148            return false;
7149        }
7150
7151        return readMet && writeMet;
7152    }
7153
7154    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7155        ProviderInfo pi = null;
7156        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7157        if (cpr != null) {
7158            pi = cpr.info;
7159        } else {
7160            try {
7161                pi = AppGlobals.getPackageManager().resolveContentProvider(
7162                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7163            } catch (RemoteException ex) {
7164            }
7165        }
7166        return pi;
7167    }
7168
7169    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7170        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7171        if (targetUris != null) {
7172            return targetUris.get(grantUri);
7173        }
7174        return null;
7175    }
7176
7177    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7178            String targetPkg, int targetUid, GrantUri grantUri) {
7179        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7180        if (targetUris == null) {
7181            targetUris = Maps.newArrayMap();
7182            mGrantedUriPermissions.put(targetUid, targetUris);
7183        }
7184
7185        UriPermission perm = targetUris.get(grantUri);
7186        if (perm == null) {
7187            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7188            targetUris.put(grantUri, perm);
7189        }
7190
7191        return perm;
7192    }
7193
7194    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7195            final int modeFlags) {
7196        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7197        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7198                : UriPermission.STRENGTH_OWNED;
7199
7200        // Root gets to do everything.
7201        if (uid == 0) {
7202            return true;
7203        }
7204
7205        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7206        if (perms == null) return false;
7207
7208        // First look for exact match
7209        final UriPermission exactPerm = perms.get(grantUri);
7210        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7211            return true;
7212        }
7213
7214        // No exact match, look for prefixes
7215        final int N = perms.size();
7216        for (int i = 0; i < N; i++) {
7217            final UriPermission perm = perms.valueAt(i);
7218            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7219                    && perm.getStrength(modeFlags) >= minStrength) {
7220                return true;
7221            }
7222        }
7223
7224        return false;
7225    }
7226
7227    /**
7228     * @param uri This uri must NOT contain an embedded userId.
7229     * @param userId The userId in which the uri is to be resolved.
7230     */
7231    @Override
7232    public int checkUriPermission(Uri uri, int pid, int uid,
7233            final int modeFlags, int userId, IBinder callerToken) {
7234        enforceNotIsolatedCaller("checkUriPermission");
7235
7236        // Another redirected-binder-call permissions check as in
7237        // {@link checkPermissionWithToken}.
7238        Identity tlsIdentity = sCallerIdentity.get();
7239        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7240            uid = tlsIdentity.uid;
7241            pid = tlsIdentity.pid;
7242        }
7243
7244        // Our own process gets to do everything.
7245        if (pid == MY_PID) {
7246            return PackageManager.PERMISSION_GRANTED;
7247        }
7248        synchronized (this) {
7249            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7250                    ? PackageManager.PERMISSION_GRANTED
7251                    : PackageManager.PERMISSION_DENIED;
7252        }
7253    }
7254
7255    /**
7256     * Check if the targetPkg can be granted permission to access uri by
7257     * the callingUid using the given modeFlags.  Throws a security exception
7258     * if callingUid is not allowed to do this.  Returns the uid of the target
7259     * if the URI permission grant should be performed; returns -1 if it is not
7260     * needed (for example targetPkg already has permission to access the URI).
7261     * If you already know the uid of the target, you can supply it in
7262     * lastTargetUid else set that to -1.
7263     */
7264    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7265            final int modeFlags, int lastTargetUid) {
7266        if (!Intent.isAccessUriMode(modeFlags)) {
7267            return -1;
7268        }
7269
7270        if (targetPkg != null) {
7271            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7272                    "Checking grant " + targetPkg + " permission to " + grantUri);
7273        }
7274
7275        final IPackageManager pm = AppGlobals.getPackageManager();
7276
7277        // If this is not a content: uri, we can't do anything with it.
7278        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7279            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7280                    "Can't grant URI permission for non-content URI: " + grantUri);
7281            return -1;
7282        }
7283
7284        final String authority = grantUri.uri.getAuthority();
7285        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7286        if (pi == null) {
7287            Slog.w(TAG, "No content provider found for permission check: " +
7288                    grantUri.uri.toSafeString());
7289            return -1;
7290        }
7291
7292        int targetUid = lastTargetUid;
7293        if (targetUid < 0 && targetPkg != null) {
7294            try {
7295                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7296                if (targetUid < 0) {
7297                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7298                            "Can't grant URI permission no uid for: " + targetPkg);
7299                    return -1;
7300                }
7301            } catch (RemoteException ex) {
7302                return -1;
7303            }
7304        }
7305
7306        if (targetUid >= 0) {
7307            // First...  does the target actually need this permission?
7308            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7309                // No need to grant the target this permission.
7310                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7311                        "Target " + targetPkg + " already has full permission to " + grantUri);
7312                return -1;
7313            }
7314        } else {
7315            // First...  there is no target package, so can anyone access it?
7316            boolean allowed = pi.exported;
7317            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7318                if (pi.readPermission != null) {
7319                    allowed = false;
7320                }
7321            }
7322            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7323                if (pi.writePermission != null) {
7324                    allowed = false;
7325                }
7326            }
7327            if (allowed) {
7328                return -1;
7329            }
7330        }
7331
7332        /* There is a special cross user grant if:
7333         * - The target is on another user.
7334         * - Apps on the current user can access the uri without any uid permissions.
7335         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7336         * grant uri permissions.
7337         */
7338        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7339                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7340                modeFlags, false /*without considering the uid permissions*/);
7341
7342        // Second...  is the provider allowing granting of URI permissions?
7343        if (!specialCrossUserGrant) {
7344            if (!pi.grantUriPermissions) {
7345                throw new SecurityException("Provider " + pi.packageName
7346                        + "/" + pi.name
7347                        + " does not allow granting of Uri permissions (uri "
7348                        + grantUri + ")");
7349            }
7350            if (pi.uriPermissionPatterns != null) {
7351                final int N = pi.uriPermissionPatterns.length;
7352                boolean allowed = false;
7353                for (int i=0; i<N; i++) {
7354                    if (pi.uriPermissionPatterns[i] != null
7355                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7356                        allowed = true;
7357                        break;
7358                    }
7359                }
7360                if (!allowed) {
7361                    throw new SecurityException("Provider " + pi.packageName
7362                            + "/" + pi.name
7363                            + " does not allow granting of permission to path of Uri "
7364                            + grantUri);
7365                }
7366            }
7367        }
7368
7369        // Third...  does the caller itself have permission to access
7370        // this uri?
7371        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7372            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7373                // Require they hold a strong enough Uri permission
7374                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7375                    throw new SecurityException("Uid " + callingUid
7376                            + " does not have permission to uri " + grantUri);
7377                }
7378            }
7379        }
7380        return targetUid;
7381    }
7382
7383    /**
7384     * @param uri This uri must NOT contain an embedded userId.
7385     * @param userId The userId in which the uri is to be resolved.
7386     */
7387    @Override
7388    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7389            final int modeFlags, int userId) {
7390        enforceNotIsolatedCaller("checkGrantUriPermission");
7391        synchronized(this) {
7392            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7393                    new GrantUri(userId, uri, false), modeFlags, -1);
7394        }
7395    }
7396
7397    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7398            final int modeFlags, UriPermissionOwner owner) {
7399        if (!Intent.isAccessUriMode(modeFlags)) {
7400            return;
7401        }
7402
7403        // So here we are: the caller has the assumed permission
7404        // to the uri, and the target doesn't.  Let's now give this to
7405        // the target.
7406
7407        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7408                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7409
7410        final String authority = grantUri.uri.getAuthority();
7411        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7412        if (pi == null) {
7413            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7414            return;
7415        }
7416
7417        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7418            grantUri.prefix = true;
7419        }
7420        final UriPermission perm = findOrCreateUriPermissionLocked(
7421                pi.packageName, targetPkg, targetUid, grantUri);
7422        perm.grantModes(modeFlags, owner);
7423    }
7424
7425    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7426            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7427        if (targetPkg == null) {
7428            throw new NullPointerException("targetPkg");
7429        }
7430        int targetUid;
7431        final IPackageManager pm = AppGlobals.getPackageManager();
7432        try {
7433            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7434        } catch (RemoteException ex) {
7435            return;
7436        }
7437
7438        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7439                targetUid);
7440        if (targetUid < 0) {
7441            return;
7442        }
7443
7444        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7445                owner);
7446    }
7447
7448    static class NeededUriGrants extends ArrayList<GrantUri> {
7449        final String targetPkg;
7450        final int targetUid;
7451        final int flags;
7452
7453        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7454            this.targetPkg = targetPkg;
7455            this.targetUid = targetUid;
7456            this.flags = flags;
7457        }
7458    }
7459
7460    /**
7461     * Like checkGrantUriPermissionLocked, but takes an Intent.
7462     */
7463    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7464            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7465        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7466                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7467                + " clip=" + (intent != null ? intent.getClipData() : null)
7468                + " from " + intent + "; flags=0x"
7469                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7470
7471        if (targetPkg == null) {
7472            throw new NullPointerException("targetPkg");
7473        }
7474
7475        if (intent == null) {
7476            return null;
7477        }
7478        Uri data = intent.getData();
7479        ClipData clip = intent.getClipData();
7480        if (data == null && clip == null) {
7481            return null;
7482        }
7483        // Default userId for uris in the intent (if they don't specify it themselves)
7484        int contentUserHint = intent.getContentUserHint();
7485        if (contentUserHint == UserHandle.USER_CURRENT) {
7486            contentUserHint = UserHandle.getUserId(callingUid);
7487        }
7488        final IPackageManager pm = AppGlobals.getPackageManager();
7489        int targetUid;
7490        if (needed != null) {
7491            targetUid = needed.targetUid;
7492        } else {
7493            try {
7494                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7495            } catch (RemoteException ex) {
7496                return null;
7497            }
7498            if (targetUid < 0) {
7499                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7500                        "Can't grant URI permission no uid for: " + targetPkg
7501                        + " on user " + targetUserId);
7502                return null;
7503            }
7504        }
7505        if (data != null) {
7506            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7507            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7508                    targetUid);
7509            if (targetUid > 0) {
7510                if (needed == null) {
7511                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7512                }
7513                needed.add(grantUri);
7514            }
7515        }
7516        if (clip != null) {
7517            for (int i=0; i<clip.getItemCount(); i++) {
7518                Uri uri = clip.getItemAt(i).getUri();
7519                if (uri != null) {
7520                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7521                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7522                            targetUid);
7523                    if (targetUid > 0) {
7524                        if (needed == null) {
7525                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7526                        }
7527                        needed.add(grantUri);
7528                    }
7529                } else {
7530                    Intent clipIntent = clip.getItemAt(i).getIntent();
7531                    if (clipIntent != null) {
7532                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7533                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7534                        if (newNeeded != null) {
7535                            needed = newNeeded;
7536                        }
7537                    }
7538                }
7539            }
7540        }
7541
7542        return needed;
7543    }
7544
7545    /**
7546     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7547     */
7548    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7549            UriPermissionOwner owner) {
7550        if (needed != null) {
7551            for (int i=0; i<needed.size(); i++) {
7552                GrantUri grantUri = needed.get(i);
7553                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7554                        grantUri, needed.flags, owner);
7555            }
7556        }
7557    }
7558
7559    void grantUriPermissionFromIntentLocked(int callingUid,
7560            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7561        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7562                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7563        if (needed == null) {
7564            return;
7565        }
7566
7567        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7568    }
7569
7570    /**
7571     * @param uri This uri must NOT contain an embedded userId.
7572     * @param userId The userId in which the uri is to be resolved.
7573     */
7574    @Override
7575    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7576            final int modeFlags, int userId) {
7577        enforceNotIsolatedCaller("grantUriPermission");
7578        GrantUri grantUri = new GrantUri(userId, uri, false);
7579        synchronized(this) {
7580            final ProcessRecord r = getRecordForAppLocked(caller);
7581            if (r == null) {
7582                throw new SecurityException("Unable to find app for caller "
7583                        + caller
7584                        + " when granting permission to uri " + grantUri);
7585            }
7586            if (targetPkg == null) {
7587                throw new IllegalArgumentException("null target");
7588            }
7589            if (grantUri == null) {
7590                throw new IllegalArgumentException("null uri");
7591            }
7592
7593            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7594                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7595                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7596                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7597
7598            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7599                    UserHandle.getUserId(r.uid));
7600        }
7601    }
7602
7603    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7604        if (perm.modeFlags == 0) {
7605            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7606                    perm.targetUid);
7607            if (perms != null) {
7608                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7609                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7610
7611                perms.remove(perm.uri);
7612                if (perms.isEmpty()) {
7613                    mGrantedUriPermissions.remove(perm.targetUid);
7614                }
7615            }
7616        }
7617    }
7618
7619    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7620        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7621                "Revoking all granted permissions to " + grantUri);
7622
7623        final IPackageManager pm = AppGlobals.getPackageManager();
7624        final String authority = grantUri.uri.getAuthority();
7625        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7626        if (pi == null) {
7627            Slog.w(TAG, "No content provider found for permission revoke: "
7628                    + grantUri.toSafeString());
7629            return;
7630        }
7631
7632        // Does the caller have this permission on the URI?
7633        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7634            // If they don't have direct access to the URI, then revoke any
7635            // ownerless URI permissions that have been granted to them.
7636            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7637            if (perms != null) {
7638                boolean persistChanged = false;
7639                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7640                    final UriPermission perm = it.next();
7641                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7642                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7643                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7644                                "Revoking non-owned " + perm.targetUid
7645                                + " permission to " + perm.uri);
7646                        persistChanged |= perm.revokeModes(
7647                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7648                        if (perm.modeFlags == 0) {
7649                            it.remove();
7650                        }
7651                    }
7652                }
7653                if (perms.isEmpty()) {
7654                    mGrantedUriPermissions.remove(callingUid);
7655                }
7656                if (persistChanged) {
7657                    schedulePersistUriGrants();
7658                }
7659            }
7660            return;
7661        }
7662
7663        boolean persistChanged = false;
7664
7665        // Go through all of the permissions and remove any that match.
7666        int N = mGrantedUriPermissions.size();
7667        for (int i = 0; i < N; i++) {
7668            final int targetUid = mGrantedUriPermissions.keyAt(i);
7669            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7670
7671            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7672                final UriPermission perm = it.next();
7673                if (perm.uri.sourceUserId == grantUri.sourceUserId
7674                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7675                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7676                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7677                    persistChanged |= perm.revokeModes(
7678                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7679                    if (perm.modeFlags == 0) {
7680                        it.remove();
7681                    }
7682                }
7683            }
7684
7685            if (perms.isEmpty()) {
7686                mGrantedUriPermissions.remove(targetUid);
7687                N--;
7688                i--;
7689            }
7690        }
7691
7692        if (persistChanged) {
7693            schedulePersistUriGrants();
7694        }
7695    }
7696
7697    /**
7698     * @param uri This uri must NOT contain an embedded userId.
7699     * @param userId The userId in which the uri is to be resolved.
7700     */
7701    @Override
7702    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7703            int userId) {
7704        enforceNotIsolatedCaller("revokeUriPermission");
7705        synchronized(this) {
7706            final ProcessRecord r = getRecordForAppLocked(caller);
7707            if (r == null) {
7708                throw new SecurityException("Unable to find app for caller "
7709                        + caller
7710                        + " when revoking permission to uri " + uri);
7711            }
7712            if (uri == null) {
7713                Slog.w(TAG, "revokeUriPermission: null uri");
7714                return;
7715            }
7716
7717            if (!Intent.isAccessUriMode(modeFlags)) {
7718                return;
7719            }
7720
7721            final String authority = uri.getAuthority();
7722            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7723            if (pi == null) {
7724                Slog.w(TAG, "No content provider found for permission revoke: "
7725                        + uri.toSafeString());
7726                return;
7727            }
7728
7729            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7730        }
7731    }
7732
7733    /**
7734     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7735     * given package.
7736     *
7737     * @param packageName Package name to match, or {@code null} to apply to all
7738     *            packages.
7739     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7740     *            to all users.
7741     * @param persistable If persistable grants should be removed.
7742     */
7743    private void removeUriPermissionsForPackageLocked(
7744            String packageName, int userHandle, boolean persistable) {
7745        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7746            throw new IllegalArgumentException("Must narrow by either package or user");
7747        }
7748
7749        boolean persistChanged = false;
7750
7751        int N = mGrantedUriPermissions.size();
7752        for (int i = 0; i < N; i++) {
7753            final int targetUid = mGrantedUriPermissions.keyAt(i);
7754            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7755
7756            // Only inspect grants matching user
7757            if (userHandle == UserHandle.USER_ALL
7758                    || userHandle == UserHandle.getUserId(targetUid)) {
7759                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7760                    final UriPermission perm = it.next();
7761
7762                    // Only inspect grants matching package
7763                    if (packageName == null || perm.sourcePkg.equals(packageName)
7764                            || perm.targetPkg.equals(packageName)) {
7765                        persistChanged |= perm.revokeModes(persistable
7766                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7767
7768                        // Only remove when no modes remain; any persisted grants
7769                        // will keep this alive.
7770                        if (perm.modeFlags == 0) {
7771                            it.remove();
7772                        }
7773                    }
7774                }
7775
7776                if (perms.isEmpty()) {
7777                    mGrantedUriPermissions.remove(targetUid);
7778                    N--;
7779                    i--;
7780                }
7781            }
7782        }
7783
7784        if (persistChanged) {
7785            schedulePersistUriGrants();
7786        }
7787    }
7788
7789    @Override
7790    public IBinder newUriPermissionOwner(String name) {
7791        enforceNotIsolatedCaller("newUriPermissionOwner");
7792        synchronized(this) {
7793            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7794            return owner.getExternalTokenLocked();
7795        }
7796    }
7797
7798    /**
7799     * @param uri This uri must NOT contain an embedded userId.
7800     * @param sourceUserId The userId in which the uri is to be resolved.
7801     * @param targetUserId The userId of the app that receives the grant.
7802     */
7803    @Override
7804    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7805            final int modeFlags, int sourceUserId, int targetUserId) {
7806        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7807                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7808        synchronized(this) {
7809            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7810            if (owner == null) {
7811                throw new IllegalArgumentException("Unknown owner: " + token);
7812            }
7813            if (fromUid != Binder.getCallingUid()) {
7814                if (Binder.getCallingUid() != Process.myUid()) {
7815                    // Only system code can grant URI permissions on behalf
7816                    // of other users.
7817                    throw new SecurityException("nice try");
7818                }
7819            }
7820            if (targetPkg == null) {
7821                throw new IllegalArgumentException("null target");
7822            }
7823            if (uri == null) {
7824                throw new IllegalArgumentException("null uri");
7825            }
7826
7827            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7828                    modeFlags, owner, targetUserId);
7829        }
7830    }
7831
7832    /**
7833     * @param uri This uri must NOT contain an embedded userId.
7834     * @param userId The userId in which the uri is to be resolved.
7835     */
7836    @Override
7837    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7838        synchronized(this) {
7839            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7840            if (owner == null) {
7841                throw new IllegalArgumentException("Unknown owner: " + token);
7842            }
7843
7844            if (uri == null) {
7845                owner.removeUriPermissionsLocked(mode);
7846            } else {
7847                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7848            }
7849        }
7850    }
7851
7852    private void schedulePersistUriGrants() {
7853        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7854            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7855                    10 * DateUtils.SECOND_IN_MILLIS);
7856        }
7857    }
7858
7859    private void writeGrantedUriPermissions() {
7860        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
7861
7862        // Snapshot permissions so we can persist without lock
7863        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7864        synchronized (this) {
7865            final int size = mGrantedUriPermissions.size();
7866            for (int i = 0; i < size; i++) {
7867                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7868                for (UriPermission perm : perms.values()) {
7869                    if (perm.persistedModeFlags != 0) {
7870                        persist.add(perm.snapshot());
7871                    }
7872                }
7873            }
7874        }
7875
7876        FileOutputStream fos = null;
7877        try {
7878            fos = mGrantFile.startWrite();
7879
7880            XmlSerializer out = new FastXmlSerializer();
7881            out.setOutput(fos, StandardCharsets.UTF_8.name());
7882            out.startDocument(null, true);
7883            out.startTag(null, TAG_URI_GRANTS);
7884            for (UriPermission.Snapshot perm : persist) {
7885                out.startTag(null, TAG_URI_GRANT);
7886                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7887                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7888                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7889                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7890                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7891                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7892                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7893                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7894                out.endTag(null, TAG_URI_GRANT);
7895            }
7896            out.endTag(null, TAG_URI_GRANTS);
7897            out.endDocument();
7898
7899            mGrantFile.finishWrite(fos);
7900        } catch (IOException e) {
7901            if (fos != null) {
7902                mGrantFile.failWrite(fos);
7903            }
7904        }
7905    }
7906
7907    private void readGrantedUriPermissionsLocked() {
7908        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
7909
7910        final long now = System.currentTimeMillis();
7911
7912        FileInputStream fis = null;
7913        try {
7914            fis = mGrantFile.openRead();
7915            final XmlPullParser in = Xml.newPullParser();
7916            in.setInput(fis, StandardCharsets.UTF_8.name());
7917
7918            int type;
7919            while ((type = in.next()) != END_DOCUMENT) {
7920                final String tag = in.getName();
7921                if (type == START_TAG) {
7922                    if (TAG_URI_GRANT.equals(tag)) {
7923                        final int sourceUserId;
7924                        final int targetUserId;
7925                        final int userHandle = readIntAttribute(in,
7926                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7927                        if (userHandle != UserHandle.USER_NULL) {
7928                            // For backwards compatibility.
7929                            sourceUserId = userHandle;
7930                            targetUserId = userHandle;
7931                        } else {
7932                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7933                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7934                        }
7935                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7936                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7937                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7938                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7939                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7940                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7941
7942                        // Sanity check that provider still belongs to source package
7943                        final ProviderInfo pi = getProviderInfoLocked(
7944                                uri.getAuthority(), sourceUserId);
7945                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7946                            int targetUid = -1;
7947                            try {
7948                                targetUid = AppGlobals.getPackageManager()
7949                                        .getPackageUid(targetPkg, targetUserId);
7950                            } catch (RemoteException e) {
7951                            }
7952                            if (targetUid != -1) {
7953                                final UriPermission perm = findOrCreateUriPermissionLocked(
7954                                        sourcePkg, targetPkg, targetUid,
7955                                        new GrantUri(sourceUserId, uri, prefix));
7956                                perm.initPersistedModes(modeFlags, createdTime);
7957                            }
7958                        } else {
7959                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7960                                    + " but instead found " + pi);
7961                        }
7962                    }
7963                }
7964            }
7965        } catch (FileNotFoundException e) {
7966            // Missing grants is okay
7967        } catch (IOException e) {
7968            Slog.wtf(TAG, "Failed reading Uri grants", e);
7969        } catch (XmlPullParserException e) {
7970            Slog.wtf(TAG, "Failed reading Uri grants", e);
7971        } finally {
7972            IoUtils.closeQuietly(fis);
7973        }
7974    }
7975
7976    /**
7977     * @param uri This uri must NOT contain an embedded userId.
7978     * @param userId The userId in which the uri is to be resolved.
7979     */
7980    @Override
7981    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7982        enforceNotIsolatedCaller("takePersistableUriPermission");
7983
7984        Preconditions.checkFlagsArgument(modeFlags,
7985                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7986
7987        synchronized (this) {
7988            final int callingUid = Binder.getCallingUid();
7989            boolean persistChanged = false;
7990            GrantUri grantUri = new GrantUri(userId, uri, false);
7991
7992            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7993                    new GrantUri(userId, uri, false));
7994            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7995                    new GrantUri(userId, uri, true));
7996
7997            final boolean exactValid = (exactPerm != null)
7998                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7999            final boolean prefixValid = (prefixPerm != null)
8000                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8001
8002            if (!(exactValid || prefixValid)) {
8003                throw new SecurityException("No persistable permission grants found for UID "
8004                        + callingUid + " and Uri " + grantUri.toSafeString());
8005            }
8006
8007            if (exactValid) {
8008                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8009            }
8010            if (prefixValid) {
8011                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8012            }
8013
8014            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8015
8016            if (persistChanged) {
8017                schedulePersistUriGrants();
8018            }
8019        }
8020    }
8021
8022    /**
8023     * @param uri This uri must NOT contain an embedded userId.
8024     * @param userId The userId in which the uri is to be resolved.
8025     */
8026    @Override
8027    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8028        enforceNotIsolatedCaller("releasePersistableUriPermission");
8029
8030        Preconditions.checkFlagsArgument(modeFlags,
8031                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8032
8033        synchronized (this) {
8034            final int callingUid = Binder.getCallingUid();
8035            boolean persistChanged = false;
8036
8037            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8038                    new GrantUri(userId, uri, false));
8039            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8040                    new GrantUri(userId, uri, true));
8041            if (exactPerm == null && prefixPerm == null) {
8042                throw new SecurityException("No permission grants found for UID " + callingUid
8043                        + " and Uri " + uri.toSafeString());
8044            }
8045
8046            if (exactPerm != null) {
8047                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8048                removeUriPermissionIfNeededLocked(exactPerm);
8049            }
8050            if (prefixPerm != null) {
8051                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8052                removeUriPermissionIfNeededLocked(prefixPerm);
8053            }
8054
8055            if (persistChanged) {
8056                schedulePersistUriGrants();
8057            }
8058        }
8059    }
8060
8061    /**
8062     * Prune any older {@link UriPermission} for the given UID until outstanding
8063     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8064     *
8065     * @return if any mutations occured that require persisting.
8066     */
8067    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8068        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8069        if (perms == null) return false;
8070        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8071
8072        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8073        for (UriPermission perm : perms.values()) {
8074            if (perm.persistedModeFlags != 0) {
8075                persisted.add(perm);
8076            }
8077        }
8078
8079        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8080        if (trimCount <= 0) return false;
8081
8082        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8083        for (int i = 0; i < trimCount; i++) {
8084            final UriPermission perm = persisted.get(i);
8085
8086            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8087                    "Trimming grant created at " + perm.persistedCreateTime);
8088
8089            perm.releasePersistableModes(~0);
8090            removeUriPermissionIfNeededLocked(perm);
8091        }
8092
8093        return true;
8094    }
8095
8096    @Override
8097    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8098            String packageName, boolean incoming) {
8099        enforceNotIsolatedCaller("getPersistedUriPermissions");
8100        Preconditions.checkNotNull(packageName, "packageName");
8101
8102        final int callingUid = Binder.getCallingUid();
8103        final IPackageManager pm = AppGlobals.getPackageManager();
8104        try {
8105            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8106            if (packageUid != callingUid) {
8107                throw new SecurityException(
8108                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8109            }
8110        } catch (RemoteException e) {
8111            throw new SecurityException("Failed to verify package name ownership");
8112        }
8113
8114        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8115        synchronized (this) {
8116            if (incoming) {
8117                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8118                        callingUid);
8119                if (perms == null) {
8120                    Slog.w(TAG, "No permission grants found for " + packageName);
8121                } else {
8122                    for (UriPermission perm : perms.values()) {
8123                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8124                            result.add(perm.buildPersistedPublicApiObject());
8125                        }
8126                    }
8127                }
8128            } else {
8129                final int size = mGrantedUriPermissions.size();
8130                for (int i = 0; i < size; i++) {
8131                    final ArrayMap<GrantUri, UriPermission> perms =
8132                            mGrantedUriPermissions.valueAt(i);
8133                    for (UriPermission perm : perms.values()) {
8134                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8135                            result.add(perm.buildPersistedPublicApiObject());
8136                        }
8137                    }
8138                }
8139            }
8140        }
8141        return new ParceledListSlice<android.content.UriPermission>(result);
8142    }
8143
8144    @Override
8145    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8146        synchronized (this) {
8147            ProcessRecord app =
8148                who != null ? getRecordForAppLocked(who) : null;
8149            if (app == null) return;
8150
8151            Message msg = Message.obtain();
8152            msg.what = WAIT_FOR_DEBUGGER_MSG;
8153            msg.obj = app;
8154            msg.arg1 = waiting ? 1 : 0;
8155            mUiHandler.sendMessage(msg);
8156        }
8157    }
8158
8159    @Override
8160    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8161        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8162        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8163        outInfo.availMem = Process.getFreeMemory();
8164        outInfo.totalMem = Process.getTotalMemory();
8165        outInfo.threshold = homeAppMem;
8166        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8167        outInfo.hiddenAppThreshold = cachedAppMem;
8168        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8169                ProcessList.SERVICE_ADJ);
8170        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8171                ProcessList.VISIBLE_APP_ADJ);
8172        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8173                ProcessList.FOREGROUND_APP_ADJ);
8174    }
8175
8176    // =========================================================
8177    // TASK MANAGEMENT
8178    // =========================================================
8179
8180    @Override
8181    public List<IAppTask> getAppTasks(String callingPackage) {
8182        int callingUid = Binder.getCallingUid();
8183        long ident = Binder.clearCallingIdentity();
8184
8185        synchronized(this) {
8186            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8187            try {
8188                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8189
8190                final int N = mRecentTasks.size();
8191                for (int i = 0; i < N; i++) {
8192                    TaskRecord tr = mRecentTasks.get(i);
8193                    // Skip tasks that do not match the caller.  We don't need to verify
8194                    // callingPackage, because we are also limiting to callingUid and know
8195                    // that will limit to the correct security sandbox.
8196                    if (tr.effectiveUid != callingUid) {
8197                        continue;
8198                    }
8199                    Intent intent = tr.getBaseIntent();
8200                    if (intent == null ||
8201                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8202                        continue;
8203                    }
8204                    ActivityManager.RecentTaskInfo taskInfo =
8205                            createRecentTaskInfoFromTaskRecord(tr);
8206                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8207                    list.add(taskImpl);
8208                }
8209            } finally {
8210                Binder.restoreCallingIdentity(ident);
8211            }
8212            return list;
8213        }
8214    }
8215
8216    @Override
8217    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8218        final int callingUid = Binder.getCallingUid();
8219        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8220
8221        synchronized(this) {
8222            if (DEBUG_ALL) Slog.v(
8223                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8224
8225            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8226                    callingUid);
8227
8228            // TODO: Improve with MRU list from all ActivityStacks.
8229            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8230        }
8231
8232        return list;
8233    }
8234
8235    /**
8236     * Creates a new RecentTaskInfo from a TaskRecord.
8237     */
8238    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8239        // Update the task description to reflect any changes in the task stack
8240        tr.updateTaskDescription();
8241
8242        // Compose the recent task info
8243        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8244        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8245        rti.persistentId = tr.taskId;
8246        rti.baseIntent = new Intent(tr.getBaseIntent());
8247        rti.origActivity = tr.origActivity;
8248        rti.description = tr.lastDescription;
8249        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8250        rti.userId = tr.userId;
8251        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8252        rti.firstActiveTime = tr.firstActiveTime;
8253        rti.lastActiveTime = tr.lastActiveTime;
8254        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8255        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8256        rti.numActivities = 0;
8257
8258        ActivityRecord base = null;
8259        ActivityRecord top = null;
8260        ActivityRecord tmp;
8261
8262        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8263            tmp = tr.mActivities.get(i);
8264            if (tmp.finishing) {
8265                continue;
8266            }
8267            base = tmp;
8268            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8269                top = base;
8270            }
8271            rti.numActivities++;
8272        }
8273
8274        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8275        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8276
8277        return rti;
8278    }
8279
8280    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8281        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8282                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8283        if (!allowed) {
8284            if (checkPermission(android.Manifest.permission.GET_TASKS,
8285                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8286                // Temporary compatibility: some existing apps on the system image may
8287                // still be requesting the old permission and not switched to the new
8288                // one; if so, we'll still allow them full access.  This means we need
8289                // to see if they are holding the old permission and are a system app.
8290                try {
8291                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8292                        allowed = true;
8293                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8294                                + " is using old GET_TASKS but privileged; allowing");
8295                    }
8296                } catch (RemoteException e) {
8297                }
8298            }
8299        }
8300        if (!allowed) {
8301            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8302                    + " does not hold REAL_GET_TASKS; limiting output");
8303        }
8304        return allowed;
8305    }
8306
8307    @Override
8308    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8309        final int callingUid = Binder.getCallingUid();
8310        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8311                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8312
8313        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8314        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8315        synchronized (this) {
8316            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8317                    callingUid);
8318            final boolean detailed = checkCallingPermission(
8319                    android.Manifest.permission.GET_DETAILED_TASKS)
8320                    == PackageManager.PERMISSION_GRANTED;
8321
8322            final int recentsCount = mRecentTasks.size();
8323            ArrayList<ActivityManager.RecentTaskInfo> res =
8324                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8325
8326            final Set<Integer> includedUsers;
8327            if (includeProfiles) {
8328                includedUsers = getProfileIdsLocked(userId);
8329            } else {
8330                includedUsers = new HashSet<>();
8331            }
8332            includedUsers.add(Integer.valueOf(userId));
8333
8334            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8335                TaskRecord tr = mRecentTasks.get(i);
8336                // Only add calling user or related users recent tasks
8337                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8338                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8339                    continue;
8340                }
8341
8342                // Return the entry if desired by the caller.  We always return
8343                // the first entry, because callers always expect this to be the
8344                // foreground app.  We may filter others if the caller has
8345                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8346                // we should exclude the entry.
8347
8348                if (i == 0
8349                        || withExcluded
8350                        || (tr.intent == null)
8351                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8352                                == 0)) {
8353                    if (!allowed) {
8354                        // If the caller doesn't have the GET_TASKS permission, then only
8355                        // allow them to see a small subset of tasks -- their own and home.
8356                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8357                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8358                            continue;
8359                        }
8360                    }
8361                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8362                        if (tr.stack != null && tr.stack.isHomeStack()) {
8363                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8364                                    "Skipping, home stack task: " + tr);
8365                            continue;
8366                        }
8367                    }
8368                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8369                        // Don't include auto remove tasks that are finished or finishing.
8370                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8371                                "Skipping, auto-remove without activity: " + tr);
8372                        continue;
8373                    }
8374                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8375                            && !tr.isAvailable) {
8376                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8377                                "Skipping, unavail real act: " + tr);
8378                        continue;
8379                    }
8380
8381                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8382                    if (!detailed) {
8383                        rti.baseIntent.replaceExtras((Bundle)null);
8384                    }
8385
8386                    res.add(rti);
8387                    maxNum--;
8388                }
8389            }
8390            return res;
8391        }
8392    }
8393
8394    @Override
8395    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8396        synchronized (this) {
8397            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8398                    "getTaskThumbnail()");
8399            TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id, false);
8400            if (tr != null) {
8401                return tr.getTaskThumbnailLocked();
8402            }
8403        }
8404        return null;
8405    }
8406
8407    @Override
8408    public int addAppTask(IBinder activityToken, Intent intent,
8409            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8410        final int callingUid = Binder.getCallingUid();
8411        final long callingIdent = Binder.clearCallingIdentity();
8412
8413        try {
8414            synchronized (this) {
8415                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8416                if (r == null) {
8417                    throw new IllegalArgumentException("Activity does not exist; token="
8418                            + activityToken);
8419                }
8420                ComponentName comp = intent.getComponent();
8421                if (comp == null) {
8422                    throw new IllegalArgumentException("Intent " + intent
8423                            + " must specify explicit component");
8424                }
8425                if (thumbnail.getWidth() != mThumbnailWidth
8426                        || thumbnail.getHeight() != mThumbnailHeight) {
8427                    throw new IllegalArgumentException("Bad thumbnail size: got "
8428                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8429                            + mThumbnailWidth + "x" + mThumbnailHeight);
8430                }
8431                if (intent.getSelector() != null) {
8432                    intent.setSelector(null);
8433                }
8434                if (intent.getSourceBounds() != null) {
8435                    intent.setSourceBounds(null);
8436                }
8437                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8438                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8439                        // The caller has added this as an auto-remove task...  that makes no
8440                        // sense, so turn off auto-remove.
8441                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8442                    }
8443                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8444                    // Must be a new task.
8445                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8446                }
8447                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8448                    mLastAddedTaskActivity = null;
8449                }
8450                ActivityInfo ainfo = mLastAddedTaskActivity;
8451                if (ainfo == null) {
8452                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8453                            comp, 0, UserHandle.getUserId(callingUid));
8454                    if (ainfo.applicationInfo.uid != callingUid) {
8455                        throw new SecurityException(
8456                                "Can't add task for another application: target uid="
8457                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8458                    }
8459                }
8460
8461                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8462                        intent, description);
8463
8464                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
8465                if (trimIdx >= 0) {
8466                    // If this would have caused a trim, then we'll abort because that
8467                    // means it would be added at the end of the list but then just removed.
8468                    return INVALID_TASK_ID;
8469                }
8470
8471                final int N = mRecentTasks.size();
8472                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8473                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8474                    tr.removedFromRecents();
8475                }
8476
8477                task.inRecents = true;
8478                mRecentTasks.add(task);
8479                r.task.stack.addTask(task, false, false);
8480
8481                task.setLastThumbnail(thumbnail);
8482                task.freeLastThumbnail();
8483
8484                return task.taskId;
8485            }
8486        } finally {
8487            Binder.restoreCallingIdentity(callingIdent);
8488        }
8489    }
8490
8491    @Override
8492    public Point getAppTaskThumbnailSize() {
8493        synchronized (this) {
8494            return new Point(mThumbnailWidth,  mThumbnailHeight);
8495        }
8496    }
8497
8498    @Override
8499    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8500        synchronized (this) {
8501            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8502            if (r != null) {
8503                r.setTaskDescription(td);
8504                r.task.updateTaskDescription();
8505            }
8506        }
8507    }
8508
8509    @Override
8510    public void setTaskResizeable(int taskId, boolean resizeable) {
8511        synchronized (this) {
8512            TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8513            if (task == null) {
8514                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
8515                return;
8516            }
8517            if (task.mResizeable != resizeable) {
8518                task.mResizeable = resizeable;
8519                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8520                mStackSupervisor.resumeTopActivitiesLocked();
8521            }
8522        }
8523    }
8524
8525    @Override
8526    public void resizeTask(int taskId, Rect bounds) {
8527        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8528                "resizeTask()");
8529        long ident = Binder.clearCallingIdentity();
8530        try {
8531            synchronized (this) {
8532                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8533                if (task == null) {
8534                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
8535                    return;
8536                }
8537                mStackSupervisor.resizeTaskLocked(task, bounds);
8538            }
8539        } finally {
8540            Binder.restoreCallingIdentity(ident);
8541        }
8542    }
8543
8544    @Override
8545    public Bitmap getTaskDescriptionIcon(String filename) {
8546        if (!FileUtils.isValidExtFilename(filename)
8547                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8548            throw new IllegalArgumentException("Bad filename: " + filename);
8549        }
8550        return mTaskPersister.getTaskDescriptionIcon(filename);
8551    }
8552
8553    @Override
8554    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8555            throws RemoteException {
8556        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8557                opts.getCustomInPlaceResId() == 0) {
8558            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8559                    "with valid animation");
8560        }
8561        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8562        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8563                opts.getCustomInPlaceResId());
8564        mWindowManager.executeAppTransition();
8565    }
8566
8567    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8568        mRecentTasks.remove(tr);
8569        tr.removedFromRecents();
8570        ComponentName component = tr.getBaseIntent().getComponent();
8571        if (component == null) {
8572            Slog.w(TAG, "No component for base intent of task: " + tr);
8573            return;
8574        }
8575
8576        // Find any running services associated with this app and stop if needed.
8577        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8578
8579        if (!killProcess) {
8580            return;
8581        }
8582
8583        // Determine if the process(es) for this task should be killed.
8584        final String pkg = component.getPackageName();
8585        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
8586        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8587        for (int i = 0; i < pmap.size(); i++) {
8588
8589            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8590            for (int j = 0; j < uids.size(); j++) {
8591                ProcessRecord proc = uids.valueAt(j);
8592                if (proc.userId != tr.userId) {
8593                    // Don't kill process for a different user.
8594                    continue;
8595                }
8596                if (proc == mHomeProcess) {
8597                    // Don't kill the home process along with tasks from the same package.
8598                    continue;
8599                }
8600                if (!proc.pkgList.containsKey(pkg)) {
8601                    // Don't kill process that is not associated with this task.
8602                    continue;
8603                }
8604
8605                for (int k = 0; k < proc.activities.size(); k++) {
8606                    TaskRecord otherTask = proc.activities.get(k).task;
8607                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8608                        // Don't kill process(es) that has an activity in a different task that is
8609                        // also in recents.
8610                        return;
8611                    }
8612                }
8613
8614                if (proc.foregroundServices) {
8615                    // Don't kill process(es) with foreground service.
8616                    return;
8617                }
8618
8619                // Add process to kill list.
8620                procsToKill.add(proc);
8621            }
8622        }
8623
8624        // Kill the running processes.
8625        for (int i = 0; i < procsToKill.size(); i++) {
8626            ProcessRecord pr = procsToKill.get(i);
8627            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
8628                    && pr.curReceiver == null) {
8629                pr.kill("remove task", true);
8630            } else {
8631                // We delay killing processes that are not in the background or running a receiver.
8632                pr.waitingToKill = "remove task";
8633            }
8634        }
8635    }
8636
8637    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8638        // Remove all tasks with activities in the specified package from the list of recent tasks
8639        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8640            TaskRecord tr = mRecentTasks.get(i);
8641            if (tr.userId != userId) continue;
8642
8643            ComponentName cn = tr.intent.getComponent();
8644            if (cn != null && cn.getPackageName().equals(packageName)) {
8645                // If the package name matches, remove the task.
8646                removeTaskByIdLocked(tr.taskId, true);
8647            }
8648        }
8649    }
8650
8651    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
8652            int userId) {
8653
8654        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8655            TaskRecord tr = mRecentTasks.get(i);
8656            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
8657                continue;
8658            }
8659
8660            ComponentName cn = tr.intent.getComponent();
8661            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
8662                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
8663            if (sameComponent) {
8664                removeTaskByIdLocked(tr.taskId, false);
8665            }
8666        }
8667    }
8668
8669    /**
8670     * Removes the task with the specified task id.
8671     *
8672     * @param taskId Identifier of the task to be removed.
8673     * @param killProcess Kill any process associated with the task if possible.
8674     * @return Returns true if the given task was found and removed.
8675     */
8676    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8677        TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8678        if (tr != null) {
8679            tr.removeTaskActivitiesLocked();
8680            cleanUpRemovedTaskLocked(tr, killProcess);
8681            if (tr.isPersistable) {
8682                notifyTaskPersisterLocked(null, true);
8683            }
8684            return true;
8685        }
8686        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8687        return false;
8688    }
8689
8690    @Override
8691    public boolean removeTask(int taskId) {
8692        synchronized (this) {
8693            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8694                    "removeTask()");
8695            long ident = Binder.clearCallingIdentity();
8696            try {
8697                return removeTaskByIdLocked(taskId, true);
8698            } finally {
8699                Binder.restoreCallingIdentity(ident);
8700            }
8701        }
8702    }
8703
8704    /**
8705     * TODO: Add mController hook
8706     */
8707    @Override
8708    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8709        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
8710
8711        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
8712        synchronized(this) {
8713            moveTaskToFrontLocked(taskId, flags, options);
8714        }
8715    }
8716
8717    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8718        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8719                Binder.getCallingUid(), -1, -1, "Task to front")) {
8720            ActivityOptions.abort(options);
8721            return;
8722        }
8723        final long origId = Binder.clearCallingIdentity();
8724        try {
8725            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8726            if (task == null) {
8727                Slog.d(TAG, "Could not find task for id: "+ taskId);
8728                return;
8729            }
8730            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8731                mStackSupervisor.showLockTaskToast();
8732                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8733                return;
8734            }
8735            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8736            if (prev != null && prev.isRecentsActivity()) {
8737                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8738            }
8739            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
8740        } finally {
8741            Binder.restoreCallingIdentity(origId);
8742        }
8743        ActivityOptions.abort(options);
8744    }
8745
8746    /**
8747     * Moves an activity, and all of the other activities within the same task, to the bottom
8748     * of the history stack.  The activity's order within the task is unchanged.
8749     *
8750     * @param token A reference to the activity we wish to move
8751     * @param nonRoot If false then this only works if the activity is the root
8752     *                of a task; if true it will work for any activity in a task.
8753     * @return Returns true if the move completed, false if not.
8754     */
8755    @Override
8756    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8757        enforceNotIsolatedCaller("moveActivityTaskToBack");
8758        synchronized(this) {
8759            final long origId = Binder.clearCallingIdentity();
8760            try {
8761                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8762                final TaskRecord task = mRecentTasks.taskForIdLocked(taskId);
8763                if (task != null) {
8764                    if (mStackSupervisor.isLockedTask(task)) {
8765                        mStackSupervisor.showLockTaskToast();
8766                        return false;
8767                    }
8768                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
8769                }
8770            } finally {
8771                Binder.restoreCallingIdentity(origId);
8772            }
8773        }
8774        return false;
8775    }
8776
8777    @Override
8778    public void moveTaskBackwards(int task) {
8779        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8780                "moveTaskBackwards()");
8781
8782        synchronized(this) {
8783            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8784                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8785                return;
8786            }
8787            final long origId = Binder.clearCallingIdentity();
8788            moveTaskBackwardsLocked(task);
8789            Binder.restoreCallingIdentity(origId);
8790        }
8791    }
8792
8793    private final void moveTaskBackwardsLocked(int task) {
8794        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8795    }
8796
8797    @Override
8798    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
8799            IActivityContainerCallback callback) throws RemoteException {
8800        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8801                "createActivityContainer()");
8802        synchronized (this) {
8803            if (parentActivityToken == null) {
8804                throw new IllegalArgumentException("parent token must not be null");
8805            }
8806            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
8807            if (r == null) {
8808                return null;
8809            }
8810            if (callback == null) {
8811                throw new IllegalArgumentException("callback must not be null");
8812            }
8813            return mStackSupervisor.createVirtualActivityContainer(r, callback);
8814        }
8815    }
8816
8817    @Override
8818    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8819        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8820                "deleteActivityContainer()");
8821        synchronized (this) {
8822            mStackSupervisor.deleteActivityContainer(container);
8823        }
8824    }
8825
8826    @Override
8827    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
8828        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8829                "createStackOnDisplay()");
8830        synchronized (this) {
8831            final int stackId = mStackSupervisor.getNextStackId();
8832            final ActivityStack stack = mStackSupervisor.createStackOnDisplay(stackId, displayId);
8833            if (stack == null) {
8834                return null;
8835            }
8836            return stack.mActivityContainer;
8837        }
8838    }
8839
8840    @Override
8841    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
8842        synchronized (this) {
8843            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8844            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
8845                return stack.mActivityContainer.getDisplayId();
8846            }
8847            return Display.DEFAULT_DISPLAY;
8848        }
8849    }
8850
8851    @Override
8852    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8853        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8854                "moveTaskToStack()");
8855        if (stackId == HOME_STACK_ID) {
8856            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8857                    new RuntimeException("here").fillInStackTrace());
8858        }
8859        synchronized (this) {
8860            long ident = Binder.clearCallingIdentity();
8861            try {
8862                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
8863                        + " to stackId=" + stackId + " toTop=" + toTop);
8864                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop);
8865            } finally {
8866                Binder.restoreCallingIdentity(ident);
8867            }
8868        }
8869    }
8870
8871    @Override
8872    public void resizeStack(int stackId, Rect bounds) {
8873        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8874                "resizeStack()");
8875        long ident = Binder.clearCallingIdentity();
8876        try {
8877            synchronized (this) {
8878                mStackSupervisor.resizeStackLocked(stackId, bounds);
8879            }
8880        } finally {
8881            Binder.restoreCallingIdentity(ident);
8882        }
8883    }
8884
8885    @Override
8886    public List<StackInfo> getAllStackInfos() {
8887        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8888                "getAllStackInfos()");
8889        long ident = Binder.clearCallingIdentity();
8890        try {
8891            synchronized (this) {
8892                return mStackSupervisor.getAllStackInfosLocked();
8893            }
8894        } finally {
8895            Binder.restoreCallingIdentity(ident);
8896        }
8897    }
8898
8899    @Override
8900    public StackInfo getStackInfo(int stackId) {
8901        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8902                "getStackInfo()");
8903        long ident = Binder.clearCallingIdentity();
8904        try {
8905            synchronized (this) {
8906                return mStackSupervisor.getStackInfoLocked(stackId);
8907            }
8908        } finally {
8909            Binder.restoreCallingIdentity(ident);
8910        }
8911    }
8912
8913    @Override
8914    public boolean isInHomeStack(int taskId) {
8915        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8916                "getStackInfo()");
8917        long ident = Binder.clearCallingIdentity();
8918        try {
8919            synchronized (this) {
8920                TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8921                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8922            }
8923        } finally {
8924            Binder.restoreCallingIdentity(ident);
8925        }
8926    }
8927
8928    @Override
8929    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8930        synchronized(this) {
8931            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8932        }
8933    }
8934
8935    @Override
8936    public void updateDeviceOwner(String packageName) {
8937        final int callingUid = Binder.getCallingUid();
8938        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
8939            throw new SecurityException("updateDeviceOwner called from non-system process");
8940        }
8941        synchronized (this) {
8942            mDeviceOwnerName = packageName;
8943        }
8944    }
8945
8946    @Override
8947    public void updateLockTaskPackages(int userId, String[] packages) {
8948        final int callingUid = Binder.getCallingUid();
8949        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
8950            throw new SecurityException("updateLockTaskPackage called from non-system process");
8951        }
8952        synchronized (this) {
8953            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
8954                    Arrays.toString(packages));
8955            mLockTaskPackages.put(userId, packages);
8956            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
8957        }
8958    }
8959
8960
8961    void startLockTaskModeLocked(TaskRecord task) {
8962        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
8963        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
8964            return;
8965        }
8966
8967        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
8968        // is initiated by system after the pinning request was shown and locked mode is initiated
8969        // by an authorized app directly
8970        final int callingUid = Binder.getCallingUid();
8971        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
8972        long ident = Binder.clearCallingIdentity();
8973        try {
8974            final ActivityStack stack = mStackSupervisor.getFocusedStack();
8975            if (!isSystemInitiated) {
8976                task.mLockTaskUid = callingUid;
8977                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
8978                    // startLockTask() called by app and task mode is lockTaskModeDefault.
8979                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
8980                    StatusBarManagerInternal statusBarManager =
8981                            LocalServices.getService(StatusBarManagerInternal.class);
8982                    if (statusBarManager != null) {
8983                        statusBarManager.showScreenPinningRequest();
8984                    }
8985                    return;
8986                }
8987
8988                if (stack == null || task != stack.topTask()) {
8989                    throw new IllegalArgumentException("Invalid task, not in foreground");
8990                }
8991            }
8992            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
8993                    "Locking fully");
8994            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
8995                    ActivityManager.LOCK_TASK_MODE_PINNED :
8996                    ActivityManager.LOCK_TASK_MODE_LOCKED,
8997                    "startLockTask", true);
8998        } finally {
8999            Binder.restoreCallingIdentity(ident);
9000        }
9001    }
9002
9003    @Override
9004    public void startLockTaskMode(int taskId) {
9005        synchronized (this) {
9006            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9007            if (task != null) {
9008                startLockTaskModeLocked(task);
9009            }
9010        }
9011    }
9012
9013    @Override
9014    public void startLockTaskMode(IBinder token) {
9015        synchronized (this) {
9016            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9017            if (r == null) {
9018                return;
9019            }
9020            final TaskRecord task = r.task;
9021            if (task != null) {
9022                startLockTaskModeLocked(task);
9023            }
9024        }
9025    }
9026
9027    @Override
9028    public void startLockTaskModeOnCurrent() throws RemoteException {
9029        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9030                "startLockTaskModeOnCurrent");
9031        long ident = Binder.clearCallingIdentity();
9032        try {
9033            synchronized (this) {
9034                ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9035                if (r != null) {
9036                    startLockTaskModeLocked(r.task);
9037                }
9038            }
9039        } finally {
9040            Binder.restoreCallingIdentity(ident);
9041        }
9042    }
9043
9044    @Override
9045    public void stopLockTaskMode() {
9046        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9047        if (lockTask == null) {
9048            // Our work here is done.
9049            return;
9050        }
9051
9052        final int callingUid = Binder.getCallingUid();
9053        final int lockTaskUid = lockTask.mLockTaskUid;
9054        // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9055        // It is possible lockTaskMode was started by the system process because
9056        // android:lockTaskMode is set to a locking value in the application manifest instead of
9057        // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9058        // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9059        if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9060                callingUid != lockTaskUid
9061                && (lockTaskUid != 0
9062                    || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9063            throw new SecurityException("Invalid uid, expected " + lockTaskUid
9064                    + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9065        }
9066
9067        long ident = Binder.clearCallingIdentity();
9068        try {
9069            Log.d(TAG, "stopLockTaskMode");
9070            // Stop lock task
9071            synchronized (this) {
9072                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9073                        "stopLockTask", true);
9074            }
9075        } finally {
9076            Binder.restoreCallingIdentity(ident);
9077        }
9078    }
9079
9080    @Override
9081    public void stopLockTaskModeOnCurrent() throws RemoteException {
9082        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9083                "stopLockTaskModeOnCurrent");
9084        long ident = Binder.clearCallingIdentity();
9085        try {
9086            stopLockTaskMode();
9087        } finally {
9088            Binder.restoreCallingIdentity(ident);
9089        }
9090    }
9091
9092    @Override
9093    public boolean isInLockTaskMode() {
9094        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9095    }
9096
9097    @Override
9098    public int getLockTaskModeState() {
9099        synchronized (this) {
9100            return mStackSupervisor.getLockTaskModeState();
9101        }
9102    }
9103
9104    @Override
9105    public void showLockTaskEscapeMessage(IBinder token) {
9106        synchronized (this) {
9107            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9108            if (r == null) {
9109                return;
9110            }
9111            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9112        }
9113    }
9114
9115    // =========================================================
9116    // CONTENT PROVIDERS
9117    // =========================================================
9118
9119    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9120        List<ProviderInfo> providers = null;
9121        try {
9122            providers = AppGlobals.getPackageManager().
9123                queryContentProviders(app.processName, app.uid,
9124                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
9125        } catch (RemoteException ex) {
9126        }
9127        if (DEBUG_MU) Slog.v(TAG_MU,
9128                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9129        int userId = app.userId;
9130        if (providers != null) {
9131            int N = providers.size();
9132            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9133            for (int i=0; i<N; i++) {
9134                ProviderInfo cpi =
9135                    (ProviderInfo)providers.get(i);
9136                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9137                        cpi.name, cpi.flags);
9138                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_OWNER) {
9139                    // This is a singleton provider, but a user besides the
9140                    // default user is asking to initialize a process it runs
9141                    // in...  well, no, it doesn't actually run in this process,
9142                    // it runs in the process of the default user.  Get rid of it.
9143                    providers.remove(i);
9144                    N--;
9145                    i--;
9146                    continue;
9147                }
9148
9149                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9150                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9151                if (cpr == null) {
9152                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9153                    mProviderMap.putProviderByClass(comp, cpr);
9154                }
9155                if (DEBUG_MU) Slog.v(TAG_MU,
9156                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9157                app.pubProviders.put(cpi.name, cpr);
9158                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9159                    // Don't add this if it is a platform component that is marked
9160                    // to run in multiple processes, because this is actually
9161                    // part of the framework so doesn't make sense to track as a
9162                    // separate apk in the process.
9163                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9164                            mProcessStats);
9165                }
9166                ensurePackageDexOpt(cpi.applicationInfo.packageName);
9167            }
9168        }
9169        return providers;
9170    }
9171
9172    /**
9173     * Check if {@link ProcessRecord} has a possible chance at accessing the
9174     * given {@link ProviderInfo}. Final permission checking is always done
9175     * in {@link ContentProvider}.
9176     */
9177    private final String checkContentProviderPermissionLocked(
9178            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9179        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9180        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9181        boolean checkedGrants = false;
9182        if (checkUser) {
9183            // Looking for cross-user grants before enforcing the typical cross-users permissions
9184            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
9185            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9186                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9187                    return null;
9188                }
9189                checkedGrants = true;
9190            }
9191            userId = handleIncomingUser(callingPid, callingUid, userId,
9192                    false, ALLOW_NON_FULL,
9193                    "checkContentProviderPermissionLocked " + cpi.authority, null);
9194            if (userId != tmpTargetUserId) {
9195                // When we actually went to determine the final targer user ID, this ended
9196                // up different than our initial check for the authority.  This is because
9197                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9198                // SELF.  So we need to re-check the grants again.
9199                checkedGrants = false;
9200            }
9201        }
9202        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9203                cpi.applicationInfo.uid, cpi.exported)
9204                == PackageManager.PERMISSION_GRANTED) {
9205            return null;
9206        }
9207        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9208                cpi.applicationInfo.uid, cpi.exported)
9209                == PackageManager.PERMISSION_GRANTED) {
9210            return null;
9211        }
9212
9213        PathPermission[] pps = cpi.pathPermissions;
9214        if (pps != null) {
9215            int i = pps.length;
9216            while (i > 0) {
9217                i--;
9218                PathPermission pp = pps[i];
9219                String pprperm = pp.getReadPermission();
9220                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9221                        cpi.applicationInfo.uid, cpi.exported)
9222                        == PackageManager.PERMISSION_GRANTED) {
9223                    return null;
9224                }
9225                String ppwperm = pp.getWritePermission();
9226                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9227                        cpi.applicationInfo.uid, cpi.exported)
9228                        == PackageManager.PERMISSION_GRANTED) {
9229                    return null;
9230                }
9231            }
9232        }
9233        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9234            return null;
9235        }
9236
9237        String msg;
9238        if (!cpi.exported) {
9239            msg = "Permission Denial: opening provider " + cpi.name
9240                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9241                    + ", uid=" + callingUid + ") that is not exported from uid "
9242                    + cpi.applicationInfo.uid;
9243        } else {
9244            msg = "Permission Denial: opening provider " + cpi.name
9245                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9246                    + ", uid=" + callingUid + ") requires "
9247                    + cpi.readPermission + " or " + cpi.writePermission;
9248        }
9249        Slog.w(TAG, msg);
9250        return msg;
9251    }
9252
9253    /**
9254     * Returns if the ContentProvider has granted a uri to callingUid
9255     */
9256    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9257        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9258        if (perms != null) {
9259            for (int i=perms.size()-1; i>=0; i--) {
9260                GrantUri grantUri = perms.keyAt(i);
9261                if (grantUri.sourceUserId == userId || !checkUser) {
9262                    if (matchesProvider(grantUri.uri, cpi)) {
9263                        return true;
9264                    }
9265                }
9266            }
9267        }
9268        return false;
9269    }
9270
9271    /**
9272     * Returns true if the uri authority is one of the authorities specified in the provider.
9273     */
9274    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9275        String uriAuth = uri.getAuthority();
9276        String cpiAuth = cpi.authority;
9277        if (cpiAuth.indexOf(';') == -1) {
9278            return cpiAuth.equals(uriAuth);
9279        }
9280        String[] cpiAuths = cpiAuth.split(";");
9281        int length = cpiAuths.length;
9282        for (int i = 0; i < length; i++) {
9283            if (cpiAuths[i].equals(uriAuth)) return true;
9284        }
9285        return false;
9286    }
9287
9288    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9289            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9290        if (r != null) {
9291            for (int i=0; i<r.conProviders.size(); i++) {
9292                ContentProviderConnection conn = r.conProviders.get(i);
9293                if (conn.provider == cpr) {
9294                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9295                            "Adding provider requested by "
9296                            + r.processName + " from process "
9297                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9298                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9299                    if (stable) {
9300                        conn.stableCount++;
9301                        conn.numStableIncs++;
9302                    } else {
9303                        conn.unstableCount++;
9304                        conn.numUnstableIncs++;
9305                    }
9306                    return conn;
9307                }
9308            }
9309            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9310            if (stable) {
9311                conn.stableCount = 1;
9312                conn.numStableIncs = 1;
9313            } else {
9314                conn.unstableCount = 1;
9315                conn.numUnstableIncs = 1;
9316            }
9317            cpr.connections.add(conn);
9318            r.conProviders.add(conn);
9319            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9320            return conn;
9321        }
9322        cpr.addExternalProcessHandleLocked(externalProcessToken);
9323        return null;
9324    }
9325
9326    boolean decProviderCountLocked(ContentProviderConnection conn,
9327            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9328        if (conn != null) {
9329            cpr = conn.provider;
9330            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9331                    "Removing provider requested by "
9332                    + conn.client.processName + " from process "
9333                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9334                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9335            if (stable) {
9336                conn.stableCount--;
9337            } else {
9338                conn.unstableCount--;
9339            }
9340            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9341                cpr.connections.remove(conn);
9342                conn.client.conProviders.remove(conn);
9343                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9344                return true;
9345            }
9346            return false;
9347        }
9348        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9349        return false;
9350    }
9351
9352    private void checkTime(long startTime, String where) {
9353        long now = SystemClock.elapsedRealtime();
9354        if ((now-startTime) > 1000) {
9355            // If we are taking more than a second, log about it.
9356            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9357        }
9358    }
9359
9360    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9361            String name, IBinder token, boolean stable, int userId) {
9362        ContentProviderRecord cpr;
9363        ContentProviderConnection conn = null;
9364        ProviderInfo cpi = null;
9365
9366        synchronized(this) {
9367            long startTime = SystemClock.elapsedRealtime();
9368
9369            ProcessRecord r = null;
9370            if (caller != null) {
9371                r = getRecordForAppLocked(caller);
9372                if (r == null) {
9373                    throw new SecurityException(
9374                            "Unable to find app for caller " + caller
9375                          + " (pid=" + Binder.getCallingPid()
9376                          + ") when getting content provider " + name);
9377                }
9378            }
9379
9380            boolean checkCrossUser = true;
9381
9382            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9383
9384            // First check if this content provider has been published...
9385            cpr = mProviderMap.getProviderByName(name, userId);
9386            // If that didn't work, check if it exists for user 0 and then
9387            // verify that it's a singleton provider before using it.
9388            if (cpr == null && userId != UserHandle.USER_OWNER) {
9389                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9390                if (cpr != null) {
9391                    cpi = cpr.info;
9392                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9393                            cpi.name, cpi.flags)
9394                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9395                        userId = UserHandle.USER_OWNER;
9396                        checkCrossUser = false;
9397                    } else {
9398                        cpr = null;
9399                        cpi = null;
9400                    }
9401                }
9402            }
9403
9404            boolean providerRunning = cpr != null;
9405            if (providerRunning) {
9406                cpi = cpr.info;
9407                String msg;
9408                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9409                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9410                        != null) {
9411                    throw new SecurityException(msg);
9412                }
9413                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9414
9415                if (r != null && cpr.canRunHere(r)) {
9416                    // This provider has been published or is in the process
9417                    // of being published...  but it is also allowed to run
9418                    // in the caller's process, so don't make a connection
9419                    // and just let the caller instantiate its own instance.
9420                    ContentProviderHolder holder = cpr.newHolder(null);
9421                    // don't give caller the provider object, it needs
9422                    // to make its own.
9423                    holder.provider = null;
9424                    return holder;
9425                }
9426
9427                final long origId = Binder.clearCallingIdentity();
9428
9429                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9430
9431                // In this case the provider instance already exists, so we can
9432                // return it right away.
9433                conn = incProviderCountLocked(r, cpr, token, stable);
9434                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9435                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9436                        // If this is a perceptible app accessing the provider,
9437                        // make sure to count it as being accessed and thus
9438                        // back up on the LRU list.  This is good because
9439                        // content providers are often expensive to start.
9440                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9441                        updateLruProcessLocked(cpr.proc, false, null);
9442                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9443                    }
9444                }
9445
9446                if (cpr.proc != null) {
9447                    if (false) {
9448                        if (cpr.name.flattenToShortString().equals(
9449                                "com.android.providers.calendar/.CalendarProvider2")) {
9450                            Slog.v(TAG, "****************** KILLING "
9451                                + cpr.name.flattenToShortString());
9452                            Process.killProcess(cpr.proc.pid);
9453                        }
9454                    }
9455                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9456                    boolean success = updateOomAdjLocked(cpr.proc);
9457                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
9458                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9459                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
9460                    // NOTE: there is still a race here where a signal could be
9461                    // pending on the process even though we managed to update its
9462                    // adj level.  Not sure what to do about this, but at least
9463                    // the race is now smaller.
9464                    if (!success) {
9465                        // Uh oh...  it looks like the provider's process
9466                        // has been killed on us.  We need to wait for a new
9467                        // process to be started, and make sure its death
9468                        // doesn't kill our process.
9469                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
9470                                + " is crashing; detaching " + r);
9471                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9472                        checkTime(startTime, "getContentProviderImpl: before appDied");
9473                        appDiedLocked(cpr.proc);
9474                        checkTime(startTime, "getContentProviderImpl: after appDied");
9475                        if (!lastRef) {
9476                            // This wasn't the last ref our process had on
9477                            // the provider...  we have now been killed, bail.
9478                            return null;
9479                        }
9480                        providerRunning = false;
9481                        conn = null;
9482                    }
9483                }
9484
9485                Binder.restoreCallingIdentity(origId);
9486            }
9487
9488            boolean singleton;
9489            if (!providerRunning) {
9490                try {
9491                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9492                    cpi = AppGlobals.getPackageManager().
9493                        resolveContentProvider(name,
9494                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9495                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9496                } catch (RemoteException ex) {
9497                }
9498                if (cpi == null) {
9499                    return null;
9500                }
9501                // If the provider is a singleton AND
9502                // (it's a call within the same user || the provider is a
9503                // privileged app)
9504                // Then allow connecting to the singleton provider
9505                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9506                        cpi.name, cpi.flags)
9507                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9508                if (singleton) {
9509                    userId = UserHandle.USER_OWNER;
9510                }
9511                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9512                checkTime(startTime, "getContentProviderImpl: got app info for user");
9513
9514                String msg;
9515                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9516                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9517                        != null) {
9518                    throw new SecurityException(msg);
9519                }
9520                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9521
9522                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9523                        && !cpi.processName.equals("system")) {
9524                    // If this content provider does not run in the system
9525                    // process, and the system is not yet ready to run other
9526                    // processes, then fail fast instead of hanging.
9527                    throw new IllegalArgumentException(
9528                            "Attempt to launch content provider before system ready");
9529                }
9530
9531                // Make sure that the user who owns this provider is running.  If not,
9532                // we don't want to allow it to run.
9533                if (!isUserRunningLocked(userId, false)) {
9534                    Slog.w(TAG, "Unable to launch app "
9535                            + cpi.applicationInfo.packageName + "/"
9536                            + cpi.applicationInfo.uid + " for provider "
9537                            + name + ": user " + userId + " is stopped");
9538                    return null;
9539                }
9540
9541                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9542                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9543                cpr = mProviderMap.getProviderByClass(comp, userId);
9544                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9545                final boolean firstClass = cpr == null;
9546                if (firstClass) {
9547                    final long ident = Binder.clearCallingIdentity();
9548                    try {
9549                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9550                        ApplicationInfo ai =
9551                            AppGlobals.getPackageManager().
9552                                getApplicationInfo(
9553                                        cpi.applicationInfo.packageName,
9554                                        STOCK_PM_FLAGS, userId);
9555                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9556                        if (ai == null) {
9557                            Slog.w(TAG, "No package info for content provider "
9558                                    + cpi.name);
9559                            return null;
9560                        }
9561                        ai = getAppInfoForUser(ai, userId);
9562                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9563                    } catch (RemoteException ex) {
9564                        // pm is in same process, this will never happen.
9565                    } finally {
9566                        Binder.restoreCallingIdentity(ident);
9567                    }
9568                }
9569
9570                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9571
9572                if (r != null && cpr.canRunHere(r)) {
9573                    // If this is a multiprocess provider, then just return its
9574                    // info and allow the caller to instantiate it.  Only do
9575                    // this if the provider is the same user as the caller's
9576                    // process, or can run as root (so can be in any process).
9577                    return cpr.newHolder(null);
9578                }
9579
9580                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
9581                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
9582                            + cpr.info.name + " callers=" + Debug.getCallers(6));
9583
9584                // This is single process, and our app is now connecting to it.
9585                // See if we are already in the process of launching this
9586                // provider.
9587                final int N = mLaunchingProviders.size();
9588                int i;
9589                for (i = 0; i < N; i++) {
9590                    if (mLaunchingProviders.get(i) == cpr) {
9591                        break;
9592                    }
9593                }
9594
9595                // If the provider is not already being launched, then get it
9596                // started.
9597                if (i >= N) {
9598                    final long origId = Binder.clearCallingIdentity();
9599
9600                    try {
9601                        // Content provider is now in use, its package can't be stopped.
9602                        try {
9603                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9604                            AppGlobals.getPackageManager().setPackageStoppedState(
9605                                    cpr.appInfo.packageName, false, userId);
9606                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9607                        } catch (RemoteException e) {
9608                        } catch (IllegalArgumentException e) {
9609                            Slog.w(TAG, "Failed trying to unstop package "
9610                                    + cpr.appInfo.packageName + ": " + e);
9611                        }
9612
9613                        // Use existing process if already started
9614                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9615                        ProcessRecord proc = getProcessRecordLocked(
9616                                cpi.processName, cpr.appInfo.uid, false);
9617                        if (proc != null && proc.thread != null) {
9618                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
9619                                    "Installing in existing process " + proc);
9620                            if (!proc.pubProviders.containsKey(cpi.name)) {
9621                                checkTime(startTime, "getContentProviderImpl: scheduling install");
9622                                proc.pubProviders.put(cpi.name, cpr);
9623                                try {
9624                                    proc.thread.scheduleInstallProvider(cpi);
9625                                } catch (RemoteException e) {
9626                                }
9627                            }
9628                        } else {
9629                            checkTime(startTime, "getContentProviderImpl: before start process");
9630                            proc = startProcessLocked(cpi.processName,
9631                                    cpr.appInfo, false, 0, "content provider",
9632                                    new ComponentName(cpi.applicationInfo.packageName,
9633                                            cpi.name), false, false, false);
9634                            checkTime(startTime, "getContentProviderImpl: after start process");
9635                            if (proc == null) {
9636                                Slog.w(TAG, "Unable to launch app "
9637                                        + cpi.applicationInfo.packageName + "/"
9638                                        + cpi.applicationInfo.uid + " for provider "
9639                                        + name + ": process is bad");
9640                                return null;
9641                            }
9642                        }
9643                        cpr.launchingApp = proc;
9644                        mLaunchingProviders.add(cpr);
9645                    } finally {
9646                        Binder.restoreCallingIdentity(origId);
9647                    }
9648                }
9649
9650                checkTime(startTime, "getContentProviderImpl: updating data structures");
9651
9652                // Make sure the provider is published (the same provider class
9653                // may be published under multiple names).
9654                if (firstClass) {
9655                    mProviderMap.putProviderByClass(comp, cpr);
9656                }
9657
9658                mProviderMap.putProviderByName(name, cpr);
9659                conn = incProviderCountLocked(r, cpr, token, stable);
9660                if (conn != null) {
9661                    conn.waiting = true;
9662                }
9663            }
9664            checkTime(startTime, "getContentProviderImpl: done!");
9665        }
9666
9667        // Wait for the provider to be published...
9668        synchronized (cpr) {
9669            while (cpr.provider == null) {
9670                if (cpr.launchingApp == null) {
9671                    Slog.w(TAG, "Unable to launch app "
9672                            + cpi.applicationInfo.packageName + "/"
9673                            + cpi.applicationInfo.uid + " for provider "
9674                            + name + ": launching app became null");
9675                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9676                            UserHandle.getUserId(cpi.applicationInfo.uid),
9677                            cpi.applicationInfo.packageName,
9678                            cpi.applicationInfo.uid, name);
9679                    return null;
9680                }
9681                try {
9682                    if (DEBUG_MU) Slog.v(TAG_MU,
9683                            "Waiting to start provider " + cpr
9684                            + " launchingApp=" + cpr.launchingApp);
9685                    if (conn != null) {
9686                        conn.waiting = true;
9687                    }
9688                    cpr.wait();
9689                } catch (InterruptedException ex) {
9690                } finally {
9691                    if (conn != null) {
9692                        conn.waiting = false;
9693                    }
9694                }
9695            }
9696        }
9697        return cpr != null ? cpr.newHolder(conn) : null;
9698    }
9699
9700    @Override
9701    public final ContentProviderHolder getContentProvider(
9702            IApplicationThread caller, String name, int userId, boolean stable) {
9703        enforceNotIsolatedCaller("getContentProvider");
9704        if (caller == null) {
9705            String msg = "null IApplicationThread when getting content provider "
9706                    + name;
9707            Slog.w(TAG, msg);
9708            throw new SecurityException(msg);
9709        }
9710        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9711        // with cross-user grant.
9712        return getContentProviderImpl(caller, name, null, stable, userId);
9713    }
9714
9715    public ContentProviderHolder getContentProviderExternal(
9716            String name, int userId, IBinder token) {
9717        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9718            "Do not have permission in call getContentProviderExternal()");
9719        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9720                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9721        return getContentProviderExternalUnchecked(name, token, userId);
9722    }
9723
9724    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9725            IBinder token, int userId) {
9726        return getContentProviderImpl(null, name, token, true, userId);
9727    }
9728
9729    /**
9730     * Drop a content provider from a ProcessRecord's bookkeeping
9731     */
9732    public void removeContentProvider(IBinder connection, boolean stable) {
9733        enforceNotIsolatedCaller("removeContentProvider");
9734        long ident = Binder.clearCallingIdentity();
9735        try {
9736            synchronized (this) {
9737                ContentProviderConnection conn;
9738                try {
9739                    conn = (ContentProviderConnection)connection;
9740                } catch (ClassCastException e) {
9741                    String msg ="removeContentProvider: " + connection
9742                            + " not a ContentProviderConnection";
9743                    Slog.w(TAG, msg);
9744                    throw new IllegalArgumentException(msg);
9745                }
9746                if (conn == null) {
9747                    throw new NullPointerException("connection is null");
9748                }
9749                if (decProviderCountLocked(conn, null, null, stable)) {
9750                    updateOomAdjLocked();
9751                }
9752            }
9753        } finally {
9754            Binder.restoreCallingIdentity(ident);
9755        }
9756    }
9757
9758    public void removeContentProviderExternal(String name, IBinder token) {
9759        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9760            "Do not have permission in call removeContentProviderExternal()");
9761        int userId = UserHandle.getCallingUserId();
9762        long ident = Binder.clearCallingIdentity();
9763        try {
9764            removeContentProviderExternalUnchecked(name, token, userId);
9765        } finally {
9766            Binder.restoreCallingIdentity(ident);
9767        }
9768    }
9769
9770    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9771        synchronized (this) {
9772            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9773            if(cpr == null) {
9774                //remove from mProvidersByClass
9775                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
9776                return;
9777            }
9778
9779            //update content provider record entry info
9780            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9781            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9782            if (localCpr.hasExternalProcessHandles()) {
9783                if (localCpr.removeExternalProcessHandleLocked(token)) {
9784                    updateOomAdjLocked();
9785                } else {
9786                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9787                            + " with no external reference for token: "
9788                            + token + ".");
9789                }
9790            } else {
9791                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9792                        + " with no external references.");
9793            }
9794        }
9795    }
9796
9797    public final void publishContentProviders(IApplicationThread caller,
9798            List<ContentProviderHolder> providers) {
9799        if (providers == null) {
9800            return;
9801        }
9802
9803        enforceNotIsolatedCaller("publishContentProviders");
9804        synchronized (this) {
9805            final ProcessRecord r = getRecordForAppLocked(caller);
9806            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9807            if (r == null) {
9808                throw new SecurityException(
9809                        "Unable to find app for caller " + caller
9810                      + " (pid=" + Binder.getCallingPid()
9811                      + ") when publishing content providers");
9812            }
9813
9814            final long origId = Binder.clearCallingIdentity();
9815
9816            final int N = providers.size();
9817            for (int i=0; i<N; i++) {
9818                ContentProviderHolder src = providers.get(i);
9819                if (src == null || src.info == null || src.provider == null) {
9820                    continue;
9821                }
9822                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9823                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9824                if (dst != null) {
9825                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9826                    mProviderMap.putProviderByClass(comp, dst);
9827                    String names[] = dst.info.authority.split(";");
9828                    for (int j = 0; j < names.length; j++) {
9829                        mProviderMap.putProviderByName(names[j], dst);
9830                    }
9831
9832                    int NL = mLaunchingProviders.size();
9833                    int j;
9834                    for (j=0; j<NL; j++) {
9835                        if (mLaunchingProviders.get(j) == dst) {
9836                            mLaunchingProviders.remove(j);
9837                            j--;
9838                            NL--;
9839                        }
9840                    }
9841                    synchronized (dst) {
9842                        dst.provider = src.provider;
9843                        dst.proc = r;
9844                        dst.notifyAll();
9845                    }
9846                    updateOomAdjLocked(r);
9847                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
9848                            src.info.authority);
9849                }
9850            }
9851
9852            Binder.restoreCallingIdentity(origId);
9853        }
9854    }
9855
9856    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9857        ContentProviderConnection conn;
9858        try {
9859            conn = (ContentProviderConnection)connection;
9860        } catch (ClassCastException e) {
9861            String msg ="refContentProvider: " + connection
9862                    + " not a ContentProviderConnection";
9863            Slog.w(TAG, msg);
9864            throw new IllegalArgumentException(msg);
9865        }
9866        if (conn == null) {
9867            throw new NullPointerException("connection is null");
9868        }
9869
9870        synchronized (this) {
9871            if (stable > 0) {
9872                conn.numStableIncs += stable;
9873            }
9874            stable = conn.stableCount + stable;
9875            if (stable < 0) {
9876                throw new IllegalStateException("stableCount < 0: " + stable);
9877            }
9878
9879            if (unstable > 0) {
9880                conn.numUnstableIncs += unstable;
9881            }
9882            unstable = conn.unstableCount + unstable;
9883            if (unstable < 0) {
9884                throw new IllegalStateException("unstableCount < 0: " + unstable);
9885            }
9886
9887            if ((stable+unstable) <= 0) {
9888                throw new IllegalStateException("ref counts can't go to zero here: stable="
9889                        + stable + " unstable=" + unstable);
9890            }
9891            conn.stableCount = stable;
9892            conn.unstableCount = unstable;
9893            return !conn.dead;
9894        }
9895    }
9896
9897    public void unstableProviderDied(IBinder connection) {
9898        ContentProviderConnection conn;
9899        try {
9900            conn = (ContentProviderConnection)connection;
9901        } catch (ClassCastException e) {
9902            String msg ="refContentProvider: " + connection
9903                    + " not a ContentProviderConnection";
9904            Slog.w(TAG, msg);
9905            throw new IllegalArgumentException(msg);
9906        }
9907        if (conn == null) {
9908            throw new NullPointerException("connection is null");
9909        }
9910
9911        // Safely retrieve the content provider associated with the connection.
9912        IContentProvider provider;
9913        synchronized (this) {
9914            provider = conn.provider.provider;
9915        }
9916
9917        if (provider == null) {
9918            // Um, yeah, we're way ahead of you.
9919            return;
9920        }
9921
9922        // Make sure the caller is being honest with us.
9923        if (provider.asBinder().pingBinder()) {
9924            // Er, no, still looks good to us.
9925            synchronized (this) {
9926                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9927                        + " says " + conn + " died, but we don't agree");
9928                return;
9929            }
9930        }
9931
9932        // Well look at that!  It's dead!
9933        synchronized (this) {
9934            if (conn.provider.provider != provider) {
9935                // But something changed...  good enough.
9936                return;
9937            }
9938
9939            ProcessRecord proc = conn.provider.proc;
9940            if (proc == null || proc.thread == null) {
9941                // Seems like the process is already cleaned up.
9942                return;
9943            }
9944
9945            // As far as we're concerned, this is just like receiving a
9946            // death notification...  just a bit prematurely.
9947            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9948                    + ") early provider death");
9949            final long ident = Binder.clearCallingIdentity();
9950            try {
9951                appDiedLocked(proc);
9952            } finally {
9953                Binder.restoreCallingIdentity(ident);
9954            }
9955        }
9956    }
9957
9958    @Override
9959    public void appNotRespondingViaProvider(IBinder connection) {
9960        enforceCallingPermission(
9961                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9962
9963        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9964        if (conn == null) {
9965            Slog.w(TAG, "ContentProviderConnection is null");
9966            return;
9967        }
9968
9969        final ProcessRecord host = conn.provider.proc;
9970        if (host == null) {
9971            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9972            return;
9973        }
9974
9975        final long token = Binder.clearCallingIdentity();
9976        try {
9977            appNotResponding(host, null, null, false, "ContentProvider not responding");
9978        } finally {
9979            Binder.restoreCallingIdentity(token);
9980        }
9981    }
9982
9983    public final void installSystemProviders() {
9984        List<ProviderInfo> providers;
9985        synchronized (this) {
9986            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9987            providers = generateApplicationProvidersLocked(app);
9988            if (providers != null) {
9989                for (int i=providers.size()-1; i>=0; i--) {
9990                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9991                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9992                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9993                                + ": not system .apk");
9994                        providers.remove(i);
9995                    }
9996                }
9997            }
9998        }
9999        if (providers != null) {
10000            mSystemThread.installSystemProviders(providers);
10001        }
10002
10003        mCoreSettingsObserver = new CoreSettingsObserver(this);
10004
10005        //mUsageStatsService.monitorPackages();
10006    }
10007
10008    /**
10009     * Allows apps to retrieve the MIME type of a URI.
10010     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
10011     * users, then it does not need permission to access the ContentProvider.
10012     * Either, it needs cross-user uri grants.
10013     *
10014     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
10015     *
10016     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
10017     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
10018     */
10019    public String getProviderMimeType(Uri uri, int userId) {
10020        enforceNotIsolatedCaller("getProviderMimeType");
10021        final String name = uri.getAuthority();
10022        int callingUid = Binder.getCallingUid();
10023        int callingPid = Binder.getCallingPid();
10024        long ident = 0;
10025        boolean clearedIdentity = false;
10026        userId = unsafeConvertIncomingUser(userId);
10027        if (canClearIdentity(callingPid, callingUid, userId)) {
10028            clearedIdentity = true;
10029            ident = Binder.clearCallingIdentity();
10030        }
10031        ContentProviderHolder holder = null;
10032        try {
10033            holder = getContentProviderExternalUnchecked(name, null, userId);
10034            if (holder != null) {
10035                return holder.provider.getType(uri);
10036            }
10037        } catch (RemoteException e) {
10038            Log.w(TAG, "Content provider dead retrieving " + uri, e);
10039            return null;
10040        } finally {
10041            // We need to clear the identity to call removeContentProviderExternalUnchecked
10042            if (!clearedIdentity) {
10043                ident = Binder.clearCallingIdentity();
10044            }
10045            try {
10046                if (holder != null) {
10047                    removeContentProviderExternalUnchecked(name, null, userId);
10048                }
10049            } finally {
10050                Binder.restoreCallingIdentity(ident);
10051            }
10052        }
10053
10054        return null;
10055    }
10056
10057    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
10058        if (UserHandle.getUserId(callingUid) == userId) {
10059            return true;
10060        }
10061        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
10062                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
10063                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
10064                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
10065                return true;
10066        }
10067        return false;
10068    }
10069
10070    // =========================================================
10071    // GLOBAL MANAGEMENT
10072    // =========================================================
10073
10074    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
10075            boolean isolated, int isolatedUid) {
10076        String proc = customProcess != null ? customProcess : info.processName;
10077        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10078        final int userId = UserHandle.getUserId(info.uid);
10079        int uid = info.uid;
10080        if (isolated) {
10081            if (isolatedUid == 0) {
10082                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
10083                while (true) {
10084                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
10085                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
10086                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
10087                    }
10088                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
10089                    mNextIsolatedProcessUid++;
10090                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
10091                        // No process for this uid, use it.
10092                        break;
10093                    }
10094                    stepsLeft--;
10095                    if (stepsLeft <= 0) {
10096                        return null;
10097                    }
10098                }
10099            } else {
10100                // Special case for startIsolatedProcess (internal only), where
10101                // the uid of the isolated process is specified by the caller.
10102                uid = isolatedUid;
10103            }
10104        }
10105        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
10106        if (!mBooted && !mBooting
10107                && userId == UserHandle.USER_OWNER
10108                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10109            r.persistent = true;
10110        }
10111        addProcessNameLocked(r);
10112        return r;
10113    }
10114
10115    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
10116            String abiOverride) {
10117        ProcessRecord app;
10118        if (!isolated) {
10119            app = getProcessRecordLocked(info.processName, info.uid, true);
10120        } else {
10121            app = null;
10122        }
10123
10124        if (app == null) {
10125            app = newProcessRecordLocked(info, null, isolated, 0);
10126            updateLruProcessLocked(app, false, null);
10127            updateOomAdjLocked();
10128        }
10129
10130        // This package really, really can not be stopped.
10131        try {
10132            AppGlobals.getPackageManager().setPackageStoppedState(
10133                    info.packageName, false, UserHandle.getUserId(app.uid));
10134        } catch (RemoteException e) {
10135        } catch (IllegalArgumentException e) {
10136            Slog.w(TAG, "Failed trying to unstop package "
10137                    + info.packageName + ": " + e);
10138        }
10139
10140        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10141            app.persistent = true;
10142            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10143        }
10144        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10145            mPersistentStartingProcesses.add(app);
10146            startProcessLocked(app, "added application", app.processName, abiOverride,
10147                    null /* entryPoint */, null /* entryPointArgs */);
10148        }
10149
10150        return app;
10151    }
10152
10153    public void unhandledBack() {
10154        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10155                "unhandledBack()");
10156
10157        synchronized(this) {
10158            final long origId = Binder.clearCallingIdentity();
10159            try {
10160                getFocusedStack().unhandledBackLocked();
10161            } finally {
10162                Binder.restoreCallingIdentity(origId);
10163            }
10164        }
10165    }
10166
10167    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10168        enforceNotIsolatedCaller("openContentUri");
10169        final int userId = UserHandle.getCallingUserId();
10170        String name = uri.getAuthority();
10171        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10172        ParcelFileDescriptor pfd = null;
10173        if (cph != null) {
10174            // We record the binder invoker's uid in thread-local storage before
10175            // going to the content provider to open the file.  Later, in the code
10176            // that handles all permissions checks, we look for this uid and use
10177            // that rather than the Activity Manager's own uid.  The effect is that
10178            // we do the check against the caller's permissions even though it looks
10179            // to the content provider like the Activity Manager itself is making
10180            // the request.
10181            Binder token = new Binder();
10182            sCallerIdentity.set(new Identity(
10183                    token, Binder.getCallingPid(), Binder.getCallingUid()));
10184            try {
10185                pfd = cph.provider.openFile(null, uri, "r", null, token);
10186            } catch (FileNotFoundException e) {
10187                // do nothing; pfd will be returned null
10188            } finally {
10189                // Ensure that whatever happens, we clean up the identity state
10190                sCallerIdentity.remove();
10191                // Ensure we're done with the provider.
10192                removeContentProviderExternalUnchecked(name, null, userId);
10193            }
10194        } else {
10195            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10196        }
10197        return pfd;
10198    }
10199
10200    // Actually is sleeping or shutting down or whatever else in the future
10201    // is an inactive state.
10202    public boolean isSleepingOrShuttingDown() {
10203        return isSleeping() || mShuttingDown;
10204    }
10205
10206    public boolean isSleeping() {
10207        return mSleeping;
10208    }
10209
10210    void onWakefulnessChanged(int wakefulness) {
10211        synchronized(this) {
10212            mWakefulness = wakefulness;
10213            updateSleepIfNeededLocked();
10214        }
10215    }
10216
10217    void finishRunningVoiceLocked() {
10218        if (mRunningVoice != null) {
10219            mRunningVoice = null;
10220            mVoiceWakeLock.release();
10221            updateSleepIfNeededLocked();
10222        }
10223    }
10224
10225    void startTimeTrackingFocusedActivityLocked() {
10226        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
10227            mCurAppTimeTracker.start(mFocusedActivity.packageName);
10228        }
10229    }
10230
10231    void updateSleepIfNeededLocked() {
10232        if (mSleeping && !shouldSleepLocked()) {
10233            mSleeping = false;
10234            startTimeTrackingFocusedActivityLocked();
10235            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
10236            mStackSupervisor.comeOutOfSleepIfNeededLocked();
10237            updateOomAdjLocked();
10238        } else if (!mSleeping && shouldSleepLocked()) {
10239            mSleeping = true;
10240            if (mCurAppTimeTracker != null) {
10241                mCurAppTimeTracker.stop();
10242            }
10243            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
10244            mStackSupervisor.goingToSleepLocked();
10245            updateOomAdjLocked();
10246
10247            // Initialize the wake times of all processes.
10248            checkExcessivePowerUsageLocked(false);
10249            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10250            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10251            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10252        }
10253    }
10254
10255    private boolean shouldSleepLocked() {
10256        // Resume applications while running a voice interactor.
10257        if (mRunningVoice != null) {
10258            return false;
10259        }
10260
10261        // TODO: Transform the lock screen state into a sleep token instead.
10262        switch (mWakefulness) {
10263            case PowerManagerInternal.WAKEFULNESS_AWAKE:
10264            case PowerManagerInternal.WAKEFULNESS_DREAMING:
10265            case PowerManagerInternal.WAKEFULNESS_DOZING:
10266                // Pause applications whenever the lock screen is shown or any sleep
10267                // tokens have been acquired.
10268                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
10269            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10270            default:
10271                // If we're asleep then pause applications unconditionally.
10272                return true;
10273        }
10274    }
10275
10276    /** Pokes the task persister. */
10277    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10278        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10279            // Never persist the home stack.
10280            return;
10281        }
10282        mTaskPersister.wakeup(task, flush);
10283    }
10284
10285    /** Notifies all listeners when the task stack has changed. */
10286    void notifyTaskStackChangedLocked() {
10287        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10288        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10289        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10290    }
10291
10292    @Override
10293    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
10294        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
10295    }
10296
10297    @Override
10298    public boolean shutdown(int timeout) {
10299        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10300                != PackageManager.PERMISSION_GRANTED) {
10301            throw new SecurityException("Requires permission "
10302                    + android.Manifest.permission.SHUTDOWN);
10303        }
10304
10305        boolean timedout = false;
10306
10307        synchronized(this) {
10308            mShuttingDown = true;
10309            updateEventDispatchingLocked();
10310            timedout = mStackSupervisor.shutdownLocked(timeout);
10311        }
10312
10313        mAppOpsService.shutdown();
10314        if (mUsageStatsService != null) {
10315            mUsageStatsService.prepareShutdown();
10316        }
10317        mBatteryStatsService.shutdown();
10318        synchronized (this) {
10319            mProcessStats.shutdownLocked();
10320            notifyTaskPersisterLocked(null, true);
10321        }
10322
10323        return timedout;
10324    }
10325
10326    public final void activitySlept(IBinder token) {
10327        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
10328
10329        final long origId = Binder.clearCallingIdentity();
10330
10331        synchronized (this) {
10332            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10333            if (r != null) {
10334                mStackSupervisor.activitySleptLocked(r);
10335            }
10336        }
10337
10338        Binder.restoreCallingIdentity(origId);
10339    }
10340
10341    private String lockScreenShownToString() {
10342        switch (mLockScreenShown) {
10343            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10344            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10345            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10346            default: return "Unknown=" + mLockScreenShown;
10347        }
10348    }
10349
10350    void logLockScreen(String msg) {
10351        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
10352                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10353                + PowerManagerInternal.wakefulnessToString(mWakefulness)
10354                + " mSleeping=" + mSleeping);
10355    }
10356
10357    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
10358        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
10359        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
10360            boolean wasRunningVoice = mRunningVoice != null;
10361            mRunningVoice = session;
10362            if (!wasRunningVoice) {
10363                mVoiceWakeLock.acquire();
10364                updateSleepIfNeededLocked();
10365            }
10366        }
10367    }
10368
10369    private void updateEventDispatchingLocked() {
10370        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10371    }
10372
10373    public void setLockScreenShown(boolean shown) {
10374        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10375                != PackageManager.PERMISSION_GRANTED) {
10376            throw new SecurityException("Requires permission "
10377                    + android.Manifest.permission.DEVICE_POWER);
10378        }
10379
10380        synchronized(this) {
10381            long ident = Binder.clearCallingIdentity();
10382            try {
10383                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10384                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10385                updateSleepIfNeededLocked();
10386            } finally {
10387                Binder.restoreCallingIdentity(ident);
10388            }
10389        }
10390    }
10391
10392    @Override
10393    public void stopAppSwitches() {
10394        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10395                != PackageManager.PERMISSION_GRANTED) {
10396            throw new SecurityException("Requires permission "
10397                    + android.Manifest.permission.STOP_APP_SWITCHES);
10398        }
10399
10400        synchronized(this) {
10401            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10402                    + APP_SWITCH_DELAY_TIME;
10403            mDidAppSwitch = false;
10404            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10405            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10406            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10407        }
10408    }
10409
10410    public void resumeAppSwitches() {
10411        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10412                != PackageManager.PERMISSION_GRANTED) {
10413            throw new SecurityException("Requires permission "
10414                    + android.Manifest.permission.STOP_APP_SWITCHES);
10415        }
10416
10417        synchronized(this) {
10418            // Note that we don't execute any pending app switches... we will
10419            // let those wait until either the timeout, or the next start
10420            // activity request.
10421            mAppSwitchesAllowedTime = 0;
10422        }
10423    }
10424
10425    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10426            int callingPid, int callingUid, String name) {
10427        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10428            return true;
10429        }
10430
10431        int perm = checkComponentPermission(
10432                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10433                sourceUid, -1, true);
10434        if (perm == PackageManager.PERMISSION_GRANTED) {
10435            return true;
10436        }
10437
10438        // If the actual IPC caller is different from the logical source, then
10439        // also see if they are allowed to control app switches.
10440        if (callingUid != -1 && callingUid != sourceUid) {
10441            perm = checkComponentPermission(
10442                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10443                    callingUid, -1, true);
10444            if (perm == PackageManager.PERMISSION_GRANTED) {
10445                return true;
10446            }
10447        }
10448
10449        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10450        return false;
10451    }
10452
10453    public void setDebugApp(String packageName, boolean waitForDebugger,
10454            boolean persistent) {
10455        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10456                "setDebugApp()");
10457
10458        long ident = Binder.clearCallingIdentity();
10459        try {
10460            // Note that this is not really thread safe if there are multiple
10461            // callers into it at the same time, but that's not a situation we
10462            // care about.
10463            if (persistent) {
10464                final ContentResolver resolver = mContext.getContentResolver();
10465                Settings.Global.putString(
10466                    resolver, Settings.Global.DEBUG_APP,
10467                    packageName);
10468                Settings.Global.putInt(
10469                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10470                    waitForDebugger ? 1 : 0);
10471            }
10472
10473            synchronized (this) {
10474                if (!persistent) {
10475                    mOrigDebugApp = mDebugApp;
10476                    mOrigWaitForDebugger = mWaitForDebugger;
10477                }
10478                mDebugApp = packageName;
10479                mWaitForDebugger = waitForDebugger;
10480                mDebugTransient = !persistent;
10481                if (packageName != null) {
10482                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10483                            false, UserHandle.USER_ALL, "set debug app");
10484                }
10485            }
10486        } finally {
10487            Binder.restoreCallingIdentity(ident);
10488        }
10489    }
10490
10491    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10492        synchronized (this) {
10493            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10494            if (!isDebuggable) {
10495                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10496                    throw new SecurityException("Process not debuggable: " + app.packageName);
10497                }
10498            }
10499
10500            mOpenGlTraceApp = processName;
10501        }
10502    }
10503
10504    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10505        synchronized (this) {
10506            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10507            if (!isDebuggable) {
10508                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10509                    throw new SecurityException("Process not debuggable: " + app.packageName);
10510                }
10511            }
10512            mProfileApp = processName;
10513            mProfileFile = profilerInfo.profileFile;
10514            if (mProfileFd != null) {
10515                try {
10516                    mProfileFd.close();
10517                } catch (IOException e) {
10518                }
10519                mProfileFd = null;
10520            }
10521            mProfileFd = profilerInfo.profileFd;
10522            mSamplingInterval = profilerInfo.samplingInterval;
10523            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10524            mProfileType = 0;
10525        }
10526    }
10527
10528    @Override
10529    public void setAlwaysFinish(boolean enabled) {
10530        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10531                "setAlwaysFinish()");
10532
10533        Settings.Global.putInt(
10534                mContext.getContentResolver(),
10535                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10536
10537        synchronized (this) {
10538            mAlwaysFinishActivities = enabled;
10539        }
10540    }
10541
10542    @Override
10543    public void setActivityController(IActivityController controller) {
10544        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10545                "setActivityController()");
10546        synchronized (this) {
10547            mController = controller;
10548            Watchdog.getInstance().setActivityController(controller);
10549        }
10550    }
10551
10552    @Override
10553    public void setUserIsMonkey(boolean userIsMonkey) {
10554        synchronized (this) {
10555            synchronized (mPidsSelfLocked) {
10556                final int callingPid = Binder.getCallingPid();
10557                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10558                if (precessRecord == null) {
10559                    throw new SecurityException("Unknown process: " + callingPid);
10560                }
10561                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10562                    throw new SecurityException("Only an instrumentation process "
10563                            + "with a UiAutomation can call setUserIsMonkey");
10564                }
10565            }
10566            mUserIsMonkey = userIsMonkey;
10567        }
10568    }
10569
10570    @Override
10571    public boolean isUserAMonkey() {
10572        synchronized (this) {
10573            // If there is a controller also implies the user is a monkey.
10574            return (mUserIsMonkey || mController != null);
10575        }
10576    }
10577
10578    public void requestBugReport() {
10579        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10580        SystemProperties.set("ctl.start", "bugreport");
10581    }
10582
10583    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10584        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10585    }
10586
10587    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10588        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10589            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10590        }
10591        return KEY_DISPATCHING_TIMEOUT;
10592    }
10593
10594    @Override
10595    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10596        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10597                != PackageManager.PERMISSION_GRANTED) {
10598            throw new SecurityException("Requires permission "
10599                    + android.Manifest.permission.FILTER_EVENTS);
10600        }
10601        ProcessRecord proc;
10602        long timeout;
10603        synchronized (this) {
10604            synchronized (mPidsSelfLocked) {
10605                proc = mPidsSelfLocked.get(pid);
10606            }
10607            timeout = getInputDispatchingTimeoutLocked(proc);
10608        }
10609
10610        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10611            return -1;
10612        }
10613
10614        return timeout;
10615    }
10616
10617    /**
10618     * Handle input dispatching timeouts.
10619     * Returns whether input dispatching should be aborted or not.
10620     */
10621    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10622            final ActivityRecord activity, final ActivityRecord parent,
10623            final boolean aboveSystem, String reason) {
10624        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10625                != PackageManager.PERMISSION_GRANTED) {
10626            throw new SecurityException("Requires permission "
10627                    + android.Manifest.permission.FILTER_EVENTS);
10628        }
10629
10630        final String annotation;
10631        if (reason == null) {
10632            annotation = "Input dispatching timed out";
10633        } else {
10634            annotation = "Input dispatching timed out (" + reason + ")";
10635        }
10636
10637        if (proc != null) {
10638            synchronized (this) {
10639                if (proc.debugging) {
10640                    return false;
10641                }
10642
10643                if (mDidDexOpt) {
10644                    // Give more time since we were dexopting.
10645                    mDidDexOpt = false;
10646                    return false;
10647                }
10648
10649                if (proc.instrumentationClass != null) {
10650                    Bundle info = new Bundle();
10651                    info.putString("shortMsg", "keyDispatchingTimedOut");
10652                    info.putString("longMsg", annotation);
10653                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10654                    return true;
10655                }
10656            }
10657            mHandler.post(new Runnable() {
10658                @Override
10659                public void run() {
10660                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10661                }
10662            });
10663        }
10664
10665        return true;
10666    }
10667
10668    @Override
10669    public Bundle getAssistContextExtras(int requestType) {
10670        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
10671                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
10672        if (pae == null) {
10673            return null;
10674        }
10675        synchronized (pae) {
10676            while (!pae.haveResult) {
10677                try {
10678                    pae.wait();
10679                } catch (InterruptedException e) {
10680                }
10681            }
10682        }
10683        synchronized (this) {
10684            buildAssistBundleLocked(pae, pae.result);
10685            mPendingAssistExtras.remove(pae);
10686            mHandler.removeCallbacks(pae);
10687        }
10688        return pae.extras;
10689    }
10690
10691    @Override
10692    public boolean isScreenCaptureAllowedOnCurrentActivity() {
10693        int userId = mCurrentUserId;
10694        synchronized (this) {
10695            ActivityRecord activity = getFocusedStack().topActivity();
10696            if (activity == null) {
10697                return false;
10698            }
10699            userId = activity.userId;
10700        }
10701        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
10702                Context.DEVICE_POLICY_SERVICE);
10703        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
10704    }
10705
10706    @Override
10707    public void requestAssistContextExtras(int requestType, IResultReceiver receiver) {
10708        enqueueAssistContext(requestType, null, null, receiver, UserHandle.getCallingUserId(),
10709                null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT);
10710    }
10711
10712    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10713            IResultReceiver receiver, int userHandle, Bundle args, long timeout) {
10714        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10715                "enqueueAssistContext()");
10716        synchronized (this) {
10717            ActivityRecord activity = getFocusedStack().topActivity();
10718            if (activity == null) {
10719                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
10720                return null;
10721            }
10722            if (activity.app == null || activity.app.thread == null) {
10723                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10724                return null;
10725            }
10726            if (activity.app.pid == Binder.getCallingPid()) {
10727                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10728                return null;
10729            }
10730            PendingAssistExtras pae;
10731            Bundle extras = new Bundle();
10732            if (args != null) {
10733                extras.putAll(args);
10734            }
10735            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10736            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
10737            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
10738            try {
10739                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10740                        requestType);
10741                mPendingAssistExtras.add(pae);
10742                mHandler.postDelayed(pae, timeout);
10743            } catch (RemoteException e) {
10744                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10745                return null;
10746            }
10747            return pae;
10748        }
10749    }
10750
10751    void pendingAssistExtrasTimedOutLocked(PendingAssistExtras pae) {
10752        mPendingAssistExtras.remove(pae);
10753        if (pae.receiver != null) {
10754            // Caller wants result sent back to them.
10755            try {
10756                pae.receiver.send(0, null);
10757            } catch (RemoteException e) {
10758            }
10759        }
10760    }
10761
10762    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
10763        if (result != null) {
10764            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
10765        }
10766        if (pae.hint != null) {
10767            pae.extras.putBoolean(pae.hint, true);
10768        }
10769    }
10770
10771    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
10772            AssistContent content, Uri referrer) {
10773        PendingAssistExtras pae = (PendingAssistExtras)token;
10774        synchronized (pae) {
10775            pae.result = extras;
10776            pae.structure = structure;
10777            pae.content = content;
10778            if (referrer != null) {
10779                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
10780            }
10781            pae.haveResult = true;
10782            pae.notifyAll();
10783            if (pae.intent == null && pae.receiver == null) {
10784                // Caller is just waiting for the result.
10785                return;
10786            }
10787        }
10788
10789        // We are now ready to launch the assist activity.
10790        synchronized (this) {
10791            buildAssistBundleLocked(pae, extras);
10792            boolean exists = mPendingAssistExtras.remove(pae);
10793            mHandler.removeCallbacks(pae);
10794            if (!exists) {
10795                // Timed out.
10796                return;
10797            }
10798            if (pae.receiver != null) {
10799                // Caller wants result sent back to them.
10800                Bundle topBundle = new Bundle();
10801                topBundle.putBundle("data", pae.extras);
10802                topBundle.putParcelable("structure", pae.structure);
10803                topBundle.putParcelable("content", pae.content);
10804                try {
10805                    pae.receiver.send(0, topBundle);
10806                } catch (RemoteException e) {
10807                }
10808                return;
10809            }
10810        }
10811
10812        long ident = Binder.clearCallingIdentity();
10813        try {
10814            pae.intent.replaceExtras(pae.extras);
10815            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10816                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
10817                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10818            closeSystemDialogs("assist");
10819            try {
10820                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10821            } catch (ActivityNotFoundException e) {
10822                Slog.w(TAG, "No activity to handle assist action.", e);
10823            }
10824        } finally {
10825            Binder.restoreCallingIdentity(ident);
10826        }
10827    }
10828
10829    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
10830            Bundle args) {
10831        return enqueueAssistContext(requestType, intent, hint, null, userHandle, args,
10832                PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
10833    }
10834
10835    public void registerProcessObserver(IProcessObserver observer) {
10836        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10837                "registerProcessObserver()");
10838        synchronized (this) {
10839            mProcessObservers.register(observer);
10840        }
10841    }
10842
10843    @Override
10844    public void unregisterProcessObserver(IProcessObserver observer) {
10845        synchronized (this) {
10846            mProcessObservers.unregister(observer);
10847        }
10848    }
10849
10850    public void registerUidObserver(IUidObserver observer) {
10851        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10852                "registerUidObserver()");
10853        synchronized (this) {
10854            mUidObservers.register(observer);
10855        }
10856    }
10857
10858    @Override
10859    public void unregisterUidObserver(IUidObserver observer) {
10860        synchronized (this) {
10861            mUidObservers.unregister(observer);
10862        }
10863    }
10864
10865    @Override
10866    public boolean convertFromTranslucent(IBinder token) {
10867        final long origId = Binder.clearCallingIdentity();
10868        try {
10869            synchronized (this) {
10870                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10871                if (r == null) {
10872                    return false;
10873                }
10874                final boolean translucentChanged = r.changeWindowTranslucency(true);
10875                if (translucentChanged) {
10876                    r.task.stack.releaseBackgroundResources(r);
10877                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10878                }
10879                mWindowManager.setAppFullscreen(token, true);
10880                return translucentChanged;
10881            }
10882        } finally {
10883            Binder.restoreCallingIdentity(origId);
10884        }
10885    }
10886
10887    @Override
10888    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10889        final long origId = Binder.clearCallingIdentity();
10890        try {
10891            synchronized (this) {
10892                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10893                if (r == null) {
10894                    return false;
10895                }
10896                int index = r.task.mActivities.lastIndexOf(r);
10897                if (index > 0) {
10898                    ActivityRecord under = r.task.mActivities.get(index - 1);
10899                    under.returningOptions = options;
10900                }
10901                final boolean translucentChanged = r.changeWindowTranslucency(false);
10902                if (translucentChanged) {
10903                    r.task.stack.convertActivityToTranslucent(r);
10904                }
10905                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10906                mWindowManager.setAppFullscreen(token, false);
10907                return translucentChanged;
10908            }
10909        } finally {
10910            Binder.restoreCallingIdentity(origId);
10911        }
10912    }
10913
10914    @Override
10915    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10916        final long origId = Binder.clearCallingIdentity();
10917        try {
10918            synchronized (this) {
10919                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10920                if (r != null) {
10921                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10922                }
10923            }
10924            return false;
10925        } finally {
10926            Binder.restoreCallingIdentity(origId);
10927        }
10928    }
10929
10930    @Override
10931    public boolean isBackgroundVisibleBehind(IBinder token) {
10932        final long origId = Binder.clearCallingIdentity();
10933        try {
10934            synchronized (this) {
10935                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10936                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10937                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
10938                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10939                return visible;
10940            }
10941        } finally {
10942            Binder.restoreCallingIdentity(origId);
10943        }
10944    }
10945
10946    @Override
10947    public ActivityOptions getActivityOptions(IBinder token) {
10948        final long origId = Binder.clearCallingIdentity();
10949        try {
10950            synchronized (this) {
10951                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10952                if (r != null) {
10953                    final ActivityOptions activityOptions = r.pendingOptions;
10954                    r.pendingOptions = null;
10955                    return activityOptions;
10956                }
10957                return null;
10958            }
10959        } finally {
10960            Binder.restoreCallingIdentity(origId);
10961        }
10962    }
10963
10964    @Override
10965    public void setImmersive(IBinder token, boolean immersive) {
10966        synchronized(this) {
10967            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10968            if (r == null) {
10969                throw new IllegalArgumentException();
10970            }
10971            r.immersive = immersive;
10972
10973            // update associated state if we're frontmost
10974            if (r == mFocusedActivity) {
10975                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
10976                applyUpdateLockStateLocked(r);
10977            }
10978        }
10979    }
10980
10981    @Override
10982    public boolean isImmersive(IBinder token) {
10983        synchronized (this) {
10984            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10985            if (r == null) {
10986                throw new IllegalArgumentException();
10987            }
10988            return r.immersive;
10989        }
10990    }
10991
10992    public boolean isTopActivityImmersive() {
10993        enforceNotIsolatedCaller("startActivity");
10994        synchronized (this) {
10995            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10996            return (r != null) ? r.immersive : false;
10997        }
10998    }
10999
11000    @Override
11001    public boolean isTopOfTask(IBinder token) {
11002        synchronized (this) {
11003            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11004            if (r == null) {
11005                throw new IllegalArgumentException();
11006            }
11007            return r.task.getTopActivity() == r;
11008        }
11009    }
11010
11011    public final void enterSafeMode() {
11012        synchronized(this) {
11013            // It only makes sense to do this before the system is ready
11014            // and started launching other packages.
11015            if (!mSystemReady) {
11016                try {
11017                    AppGlobals.getPackageManager().enterSafeMode();
11018                } catch (RemoteException e) {
11019                }
11020            }
11021
11022            mSafeMode = true;
11023        }
11024    }
11025
11026    public final void showSafeModeOverlay() {
11027        View v = LayoutInflater.from(mContext).inflate(
11028                com.android.internal.R.layout.safe_mode, null);
11029        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
11030        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
11031        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
11032        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
11033        lp.gravity = Gravity.BOTTOM | Gravity.START;
11034        lp.format = v.getBackground().getOpacity();
11035        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
11036                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
11037        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
11038        ((WindowManager)mContext.getSystemService(
11039                Context.WINDOW_SERVICE)).addView(v, lp);
11040    }
11041
11042    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
11043        if (!(sender instanceof PendingIntentRecord)) {
11044            return;
11045        }
11046        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11047        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11048        synchronized (stats) {
11049            if (mBatteryStatsService.isOnBattery()) {
11050                mBatteryStatsService.enforceCallingPermission();
11051                int MY_UID = Binder.getCallingUid();
11052                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11053                BatteryStatsImpl.Uid.Pkg pkg =
11054                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
11055                            sourcePkg != null ? sourcePkg : rec.key.packageName);
11056                pkg.noteWakeupAlarmLocked(tag);
11057            }
11058        }
11059    }
11060
11061    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
11062        if (!(sender instanceof PendingIntentRecord)) {
11063            return;
11064        }
11065        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11066        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11067        synchronized (stats) {
11068            mBatteryStatsService.enforceCallingPermission();
11069            int MY_UID = Binder.getCallingUid();
11070            int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11071            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
11072        }
11073    }
11074
11075    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
11076        if (!(sender instanceof PendingIntentRecord)) {
11077            return;
11078        }
11079        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11080        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11081        synchronized (stats) {
11082            mBatteryStatsService.enforceCallingPermission();
11083            int MY_UID = Binder.getCallingUid();
11084            int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11085            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
11086        }
11087    }
11088
11089    public boolean killPids(int[] pids, String pReason, boolean secure) {
11090        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11091            throw new SecurityException("killPids only available to the system");
11092        }
11093        String reason = (pReason == null) ? "Unknown" : pReason;
11094        // XXX Note: don't acquire main activity lock here, because the window
11095        // manager calls in with its locks held.
11096
11097        boolean killed = false;
11098        synchronized (mPidsSelfLocked) {
11099            int[] types = new int[pids.length];
11100            int worstType = 0;
11101            for (int i=0; i<pids.length; i++) {
11102                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11103                if (proc != null) {
11104                    int type = proc.setAdj;
11105                    types[i] = type;
11106                    if (type > worstType) {
11107                        worstType = type;
11108                    }
11109                }
11110            }
11111
11112            // If the worst oom_adj is somewhere in the cached proc LRU range,
11113            // then constrain it so we will kill all cached procs.
11114            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
11115                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
11116                worstType = ProcessList.CACHED_APP_MIN_ADJ;
11117            }
11118
11119            // If this is not a secure call, don't let it kill processes that
11120            // are important.
11121            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
11122                worstType = ProcessList.SERVICE_ADJ;
11123            }
11124
11125            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
11126            for (int i=0; i<pids.length; i++) {
11127                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11128                if (proc == null) {
11129                    continue;
11130                }
11131                int adj = proc.setAdj;
11132                if (adj >= worstType && !proc.killedByAm) {
11133                    proc.kill(reason, true);
11134                    killed = true;
11135                }
11136            }
11137        }
11138        return killed;
11139    }
11140
11141    @Override
11142    public void killUid(int uid, String reason) {
11143        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
11144        synchronized (this) {
11145            final long identity = Binder.clearCallingIdentity();
11146            try {
11147                killPackageProcessesLocked(null, UserHandle.getAppId(uid),
11148                        UserHandle.getUserId(uid),
11149                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
11150                        reason != null ? reason : "kill uid");
11151            } finally {
11152                Binder.restoreCallingIdentity(identity);
11153            }
11154        }
11155    }
11156
11157    @Override
11158    public boolean killProcessesBelowForeground(String reason) {
11159        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11160            throw new SecurityException("killProcessesBelowForeground() only available to system");
11161        }
11162
11163        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
11164    }
11165
11166    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
11167        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11168            throw new SecurityException("killProcessesBelowAdj() only available to system");
11169        }
11170
11171        boolean killed = false;
11172        synchronized (mPidsSelfLocked) {
11173            final int size = mPidsSelfLocked.size();
11174            for (int i = 0; i < size; i++) {
11175                final int pid = mPidsSelfLocked.keyAt(i);
11176                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11177                if (proc == null) continue;
11178
11179                final int adj = proc.setAdj;
11180                if (adj > belowAdj && !proc.killedByAm) {
11181                    proc.kill(reason, true);
11182                    killed = true;
11183                }
11184            }
11185        }
11186        return killed;
11187    }
11188
11189    @Override
11190    public void hang(final IBinder who, boolean allowRestart) {
11191        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11192                != PackageManager.PERMISSION_GRANTED) {
11193            throw new SecurityException("Requires permission "
11194                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11195        }
11196
11197        final IBinder.DeathRecipient death = new DeathRecipient() {
11198            @Override
11199            public void binderDied() {
11200                synchronized (this) {
11201                    notifyAll();
11202                }
11203            }
11204        };
11205
11206        try {
11207            who.linkToDeath(death, 0);
11208        } catch (RemoteException e) {
11209            Slog.w(TAG, "hang: given caller IBinder is already dead.");
11210            return;
11211        }
11212
11213        synchronized (this) {
11214            Watchdog.getInstance().setAllowRestart(allowRestart);
11215            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
11216            synchronized (death) {
11217                while (who.isBinderAlive()) {
11218                    try {
11219                        death.wait();
11220                    } catch (InterruptedException e) {
11221                    }
11222                }
11223            }
11224            Watchdog.getInstance().setAllowRestart(true);
11225        }
11226    }
11227
11228    @Override
11229    public void restart() {
11230        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11231                != PackageManager.PERMISSION_GRANTED) {
11232            throw new SecurityException("Requires permission "
11233                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11234        }
11235
11236        Log.i(TAG, "Sending shutdown broadcast...");
11237
11238        BroadcastReceiver br = new BroadcastReceiver() {
11239            @Override public void onReceive(Context context, Intent intent) {
11240                // Now the broadcast is done, finish up the low-level shutdown.
11241                Log.i(TAG, "Shutting down activity manager...");
11242                shutdown(10000);
11243                Log.i(TAG, "Shutdown complete, restarting!");
11244                Process.killProcess(Process.myPid());
11245                System.exit(10);
11246            }
11247        };
11248
11249        // First send the high-level shut down broadcast.
11250        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
11251        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
11252        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
11253        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
11254        mContext.sendOrderedBroadcastAsUser(intent,
11255                UserHandle.ALL, null, br, mHandler, 0, null, null);
11256        */
11257        br.onReceive(mContext, intent);
11258    }
11259
11260    private long getLowRamTimeSinceIdle(long now) {
11261        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
11262    }
11263
11264    @Override
11265    public void performIdleMaintenance() {
11266        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11267                != PackageManager.PERMISSION_GRANTED) {
11268            throw new SecurityException("Requires permission "
11269                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11270        }
11271
11272        synchronized (this) {
11273            final long now = SystemClock.uptimeMillis();
11274            final long timeSinceLastIdle = now - mLastIdleTime;
11275            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
11276            mLastIdleTime = now;
11277            mLowRamTimeSinceLastIdle = 0;
11278            if (mLowRamStartTime != 0) {
11279                mLowRamStartTime = now;
11280            }
11281
11282            StringBuilder sb = new StringBuilder(128);
11283            sb.append("Idle maintenance over ");
11284            TimeUtils.formatDuration(timeSinceLastIdle, sb);
11285            sb.append(" low RAM for ");
11286            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11287            Slog.i(TAG, sb.toString());
11288
11289            // If at least 1/3 of our time since the last idle period has been spent
11290            // with RAM low, then we want to kill processes.
11291            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
11292
11293            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11294                ProcessRecord proc = mLruProcesses.get(i);
11295                if (proc.notCachedSinceIdle) {
11296                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
11297                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
11298                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
11299                        if (doKilling && proc.initialIdlePss != 0
11300                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
11301                            sb = new StringBuilder(128);
11302                            sb.append("Kill");
11303                            sb.append(proc.processName);
11304                            sb.append(" in idle maint: pss=");
11305                            sb.append(proc.lastPss);
11306                            sb.append(", initialPss=");
11307                            sb.append(proc.initialIdlePss);
11308                            sb.append(", period=");
11309                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
11310                            sb.append(", lowRamPeriod=");
11311                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11312                            Slog.wtfQuiet(TAG, sb.toString());
11313                            proc.kill("idle maint (pss " + proc.lastPss
11314                                    + " from " + proc.initialIdlePss + ")", true);
11315                        }
11316                    }
11317                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
11318                    proc.notCachedSinceIdle = true;
11319                    proc.initialIdlePss = 0;
11320                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
11321                            mTestPssMode, isSleeping(), now);
11322                }
11323            }
11324
11325            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
11326            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
11327        }
11328    }
11329
11330    private void retrieveSettings() {
11331        final ContentResolver resolver = mContext.getContentResolver();
11332        String debugApp = Settings.Global.getString(
11333            resolver, Settings.Global.DEBUG_APP);
11334        boolean waitForDebugger = Settings.Global.getInt(
11335            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11336        boolean alwaysFinishActivities = Settings.Global.getInt(
11337            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11338        boolean forceRtl = Settings.Global.getInt(
11339                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11340        // Transfer any global setting for forcing RTL layout, into a System Property
11341        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11342
11343        Configuration configuration = new Configuration();
11344        Settings.System.getConfiguration(resolver, configuration);
11345        if (forceRtl) {
11346            // This will take care of setting the correct layout direction flags
11347            configuration.setLayoutDirection(configuration.locale);
11348        }
11349
11350        synchronized (this) {
11351            mDebugApp = mOrigDebugApp = debugApp;
11352            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11353            mAlwaysFinishActivities = alwaysFinishActivities;
11354            // This happens before any activities are started, so we can
11355            // change mConfiguration in-place.
11356            updateConfigurationLocked(configuration, null, false, true);
11357            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
11358                    "Initial config: " + mConfiguration);
11359        }
11360    }
11361
11362    /** Loads resources after the current configuration has been set. */
11363    private void loadResourcesOnSystemReady() {
11364        final Resources res = mContext.getResources();
11365        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11366        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11367        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11368    }
11369
11370    public boolean testIsSystemReady() {
11371        // no need to synchronize(this) just to read & return the value
11372        return mSystemReady;
11373    }
11374
11375    private static File getCalledPreBootReceiversFile() {
11376        File dataDir = Environment.getDataDirectory();
11377        File systemDir = new File(dataDir, "system");
11378        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11379        return fname;
11380    }
11381
11382    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11383        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11384        File file = getCalledPreBootReceiversFile();
11385        FileInputStream fis = null;
11386        try {
11387            fis = new FileInputStream(file);
11388            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11389            int fvers = dis.readInt();
11390            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11391                String vers = dis.readUTF();
11392                String codename = dis.readUTF();
11393                String build = dis.readUTF();
11394                if (android.os.Build.VERSION.RELEASE.equals(vers)
11395                        && android.os.Build.VERSION.CODENAME.equals(codename)
11396                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11397                    int num = dis.readInt();
11398                    while (num > 0) {
11399                        num--;
11400                        String pkg = dis.readUTF();
11401                        String cls = dis.readUTF();
11402                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11403                    }
11404                }
11405            }
11406        } catch (FileNotFoundException e) {
11407        } catch (IOException e) {
11408            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11409        } finally {
11410            if (fis != null) {
11411                try {
11412                    fis.close();
11413                } catch (IOException e) {
11414                }
11415            }
11416        }
11417        return lastDoneReceivers;
11418    }
11419
11420    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11421        File file = getCalledPreBootReceiversFile();
11422        FileOutputStream fos = null;
11423        DataOutputStream dos = null;
11424        try {
11425            fos = new FileOutputStream(file);
11426            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11427            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11428            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11429            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11430            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11431            dos.writeInt(list.size());
11432            for (int i=0; i<list.size(); i++) {
11433                dos.writeUTF(list.get(i).getPackageName());
11434                dos.writeUTF(list.get(i).getClassName());
11435            }
11436        } catch (IOException e) {
11437            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11438            file.delete();
11439        } finally {
11440            FileUtils.sync(fos);
11441            if (dos != null) {
11442                try {
11443                    dos.close();
11444                } catch (IOException e) {
11445                    // TODO Auto-generated catch block
11446                    e.printStackTrace();
11447                }
11448            }
11449        }
11450    }
11451
11452    final class PreBootContinuation extends IIntentReceiver.Stub {
11453        final Intent intent;
11454        final Runnable onFinishCallback;
11455        final ArrayList<ComponentName> doneReceivers;
11456        final List<ResolveInfo> ris;
11457        final int[] users;
11458        int lastRi = -1;
11459        int curRi = 0;
11460        int curUser = 0;
11461
11462        PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
11463                ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
11464            intent = _intent;
11465            onFinishCallback = _onFinishCallback;
11466            doneReceivers = _doneReceivers;
11467            ris = _ris;
11468            users = _users;
11469        }
11470
11471        void go() {
11472            if (lastRi != curRi) {
11473                ActivityInfo ai = ris.get(curRi).activityInfo;
11474                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11475                intent.setComponent(comp);
11476                doneReceivers.add(comp);
11477                lastRi = curRi;
11478                CharSequence label = ai.loadLabel(mContext.getPackageManager());
11479                showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
11480            }
11481            Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
11482                    + " for user " + users[curUser]);
11483            EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
11484            broadcastIntentLocked(null, null, intent, null, this,
11485                    0, null, null, null, AppOpsManager.OP_NONE,
11486                    null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
11487        }
11488
11489        public void performReceive(Intent intent, int resultCode,
11490                String data, Bundle extras, boolean ordered,
11491                boolean sticky, int sendingUser) {
11492            curUser++;
11493            if (curUser >= users.length) {
11494                curUser = 0;
11495                curRi++;
11496                if (curRi >= ris.size()) {
11497                    // All done sending broadcasts!
11498                    if (onFinishCallback != null) {
11499                        // The raw IIntentReceiver interface is called
11500                        // with the AM lock held, so redispatch to
11501                        // execute our code without the lock.
11502                        mHandler.post(onFinishCallback);
11503                    }
11504                    return;
11505                }
11506            }
11507            go();
11508        }
11509    }
11510
11511    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11512            ArrayList<ComponentName> doneReceivers, int userId) {
11513        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11514        List<ResolveInfo> ris = null;
11515        try {
11516            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11517                    intent, null, 0, userId);
11518        } catch (RemoteException e) {
11519        }
11520        if (ris == null) {
11521            return false;
11522        }
11523        for (int i=ris.size()-1; i>=0; i--) {
11524            if ((ris.get(i).activityInfo.applicationInfo.flags
11525                    &ApplicationInfo.FLAG_SYSTEM) == 0) {
11526                ris.remove(i);
11527            }
11528        }
11529        intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11530
11531        // For User 0, load the version number. When delivering to a new user, deliver
11532        // to all receivers.
11533        if (userId == UserHandle.USER_OWNER) {
11534            ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11535            for (int i=0; i<ris.size(); i++) {
11536                ActivityInfo ai = ris.get(i).activityInfo;
11537                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11538                if (lastDoneReceivers.contains(comp)) {
11539                    // We already did the pre boot receiver for this app with the current
11540                    // platform version, so don't do it again...
11541                    ris.remove(i);
11542                    i--;
11543                    // ...however, do keep it as one that has been done, so we don't
11544                    // forget about it when rewriting the file of last done receivers.
11545                    doneReceivers.add(comp);
11546                }
11547            }
11548        }
11549
11550        if (ris.size() <= 0) {
11551            return false;
11552        }
11553
11554        // If primary user, send broadcast to all available users, else just to userId
11555        final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11556                : new int[] { userId };
11557        if (users.length <= 0) {
11558            return false;
11559        }
11560
11561        PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
11562                ris, users);
11563        cont.go();
11564        return true;
11565    }
11566
11567    public void systemReady(final Runnable goingCallback) {
11568        synchronized(this) {
11569            if (mSystemReady) {
11570                // If we're done calling all the receivers, run the next "boot phase" passed in
11571                // by the SystemServer
11572                if (goingCallback != null) {
11573                    goingCallback.run();
11574                }
11575                return;
11576            }
11577
11578            mLocalDeviceIdleController
11579                    = LocalServices.getService(DeviceIdleController.LocalService.class);
11580
11581            // Make sure we have the current profile info, since it is needed for
11582            // security checks.
11583            updateCurrentProfileIdsLocked();
11584
11585            mRecentTasks.clear();
11586            mRecentTasks.addAll(mTaskPersister.restoreTasksLocked());
11587            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
11588            mTaskPersister.startPersisting();
11589
11590            // Check to see if there are any update receivers to run.
11591            if (!mDidUpdate) {
11592                if (mWaitingUpdate) {
11593                    return;
11594                }
11595                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11596                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11597                    public void run() {
11598                        synchronized (ActivityManagerService.this) {
11599                            mDidUpdate = true;
11600                        }
11601                        showBootMessage(mContext.getText(
11602                                R.string.android_upgrading_complete),
11603                                false);
11604                        writeLastDonePreBootReceivers(doneReceivers);
11605                        systemReady(goingCallback);
11606                    }
11607                }, doneReceivers, UserHandle.USER_OWNER);
11608
11609                if (mWaitingUpdate) {
11610                    return;
11611                }
11612                mDidUpdate = true;
11613            }
11614
11615            mAppOpsService.systemReady();
11616            mSystemReady = true;
11617        }
11618
11619        ArrayList<ProcessRecord> procsToKill = null;
11620        synchronized(mPidsSelfLocked) {
11621            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11622                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11623                if (!isAllowedWhileBooting(proc.info)){
11624                    if (procsToKill == null) {
11625                        procsToKill = new ArrayList<ProcessRecord>();
11626                    }
11627                    procsToKill.add(proc);
11628                }
11629            }
11630        }
11631
11632        synchronized(this) {
11633            if (procsToKill != null) {
11634                for (int i=procsToKill.size()-1; i>=0; i--) {
11635                    ProcessRecord proc = procsToKill.get(i);
11636                    Slog.i(TAG, "Removing system update proc: " + proc);
11637                    removeProcessLocked(proc, true, false, "system update done");
11638                }
11639            }
11640
11641            // Now that we have cleaned up any update processes, we
11642            // are ready to start launching real processes and know that
11643            // we won't trample on them any more.
11644            mProcessesReady = true;
11645        }
11646
11647        Slog.i(TAG, "System now ready");
11648        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11649            SystemClock.uptimeMillis());
11650
11651        synchronized(this) {
11652            // Make sure we have no pre-ready processes sitting around.
11653
11654            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11655                ResolveInfo ri = mContext.getPackageManager()
11656                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11657                                STOCK_PM_FLAGS);
11658                CharSequence errorMsg = null;
11659                if (ri != null) {
11660                    ActivityInfo ai = ri.activityInfo;
11661                    ApplicationInfo app = ai.applicationInfo;
11662                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11663                        mTopAction = Intent.ACTION_FACTORY_TEST;
11664                        mTopData = null;
11665                        mTopComponent = new ComponentName(app.packageName,
11666                                ai.name);
11667                    } else {
11668                        errorMsg = mContext.getResources().getText(
11669                                com.android.internal.R.string.factorytest_not_system);
11670                    }
11671                } else {
11672                    errorMsg = mContext.getResources().getText(
11673                            com.android.internal.R.string.factorytest_no_action);
11674                }
11675                if (errorMsg != null) {
11676                    mTopAction = null;
11677                    mTopData = null;
11678                    mTopComponent = null;
11679                    Message msg = Message.obtain();
11680                    msg.what = SHOW_FACTORY_ERROR_MSG;
11681                    msg.getData().putCharSequence("msg", errorMsg);
11682                    mUiHandler.sendMessage(msg);
11683                }
11684            }
11685        }
11686
11687        retrieveSettings();
11688        loadResourcesOnSystemReady();
11689
11690        synchronized (this) {
11691            readGrantedUriPermissionsLocked();
11692        }
11693
11694        if (goingCallback != null) goingCallback.run();
11695
11696        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11697                Integer.toString(mCurrentUserId), mCurrentUserId);
11698        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11699                Integer.toString(mCurrentUserId), mCurrentUserId);
11700        mSystemServiceManager.startUser(mCurrentUserId);
11701
11702        synchronized (this) {
11703            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11704                try {
11705                    List apps = AppGlobals.getPackageManager().
11706                        getPersistentApplications(STOCK_PM_FLAGS);
11707                    if (apps != null) {
11708                        int N = apps.size();
11709                        int i;
11710                        for (i=0; i<N; i++) {
11711                            ApplicationInfo info
11712                                = (ApplicationInfo)apps.get(i);
11713                            if (info != null &&
11714                                    !info.packageName.equals("android")) {
11715                                addAppLocked(info, false, null /* ABI override */);
11716                            }
11717                        }
11718                    }
11719                } catch (RemoteException ex) {
11720                    // pm is in same process, this will never happen.
11721                }
11722            }
11723
11724            // Start up initial activity.
11725            mBooting = true;
11726            startHomeActivityLocked(mCurrentUserId, "systemReady");
11727
11728            try {
11729                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11730                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11731                            + " data partition or your device will be unstable.");
11732                    mUiHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11733                }
11734            } catch (RemoteException e) {
11735            }
11736
11737            if (!Build.isBuildConsistent()) {
11738                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11739                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11740            }
11741
11742            long ident = Binder.clearCallingIdentity();
11743            try {
11744                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11745                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11746                        | Intent.FLAG_RECEIVER_FOREGROUND);
11747                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11748                broadcastIntentLocked(null, null, intent,
11749                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11750                        null, false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11751                intent = new Intent(Intent.ACTION_USER_STARTING);
11752                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11753                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11754                broadcastIntentLocked(null, null, intent,
11755                        null, new IIntentReceiver.Stub() {
11756                            @Override
11757                            public void performReceive(Intent intent, int resultCode, String data,
11758                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11759                                    throws RemoteException {
11760                            }
11761                        }, 0, null, null,
11762                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11763                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11764            } catch (Throwable t) {
11765                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11766            } finally {
11767                Binder.restoreCallingIdentity(ident);
11768            }
11769            mStackSupervisor.resumeTopActivitiesLocked();
11770            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11771        }
11772    }
11773
11774    private boolean makeAppCrashingLocked(ProcessRecord app,
11775            String shortMsg, String longMsg, String stackTrace) {
11776        app.crashing = true;
11777        app.crashingReport = generateProcessError(app,
11778                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11779        startAppProblemLocked(app);
11780        app.stopFreezingAllLocked();
11781        return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
11782    }
11783
11784    private void makeAppNotRespondingLocked(ProcessRecord app,
11785            String activity, String shortMsg, String longMsg) {
11786        app.notResponding = true;
11787        app.notRespondingReport = generateProcessError(app,
11788                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11789                activity, shortMsg, longMsg, null);
11790        startAppProblemLocked(app);
11791        app.stopFreezingAllLocked();
11792    }
11793
11794    /**
11795     * Generate a process error record, suitable for attachment to a ProcessRecord.
11796     *
11797     * @param app The ProcessRecord in which the error occurred.
11798     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11799     *                      ActivityManager.AppErrorStateInfo
11800     * @param activity The activity associated with the crash, if known.
11801     * @param shortMsg Short message describing the crash.
11802     * @param longMsg Long message describing the crash.
11803     * @param stackTrace Full crash stack trace, may be null.
11804     *
11805     * @return Returns a fully-formed AppErrorStateInfo record.
11806     */
11807    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11808            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11809        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11810
11811        report.condition = condition;
11812        report.processName = app.processName;
11813        report.pid = app.pid;
11814        report.uid = app.info.uid;
11815        report.tag = activity;
11816        report.shortMsg = shortMsg;
11817        report.longMsg = longMsg;
11818        report.stackTrace = stackTrace;
11819
11820        return report;
11821    }
11822
11823    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11824        synchronized (this) {
11825            app.crashing = false;
11826            app.crashingReport = null;
11827            app.notResponding = false;
11828            app.notRespondingReport = null;
11829            if (app.anrDialog == fromDialog) {
11830                app.anrDialog = null;
11831            }
11832            if (app.waitDialog == fromDialog) {
11833                app.waitDialog = null;
11834            }
11835            if (app.pid > 0 && app.pid != MY_PID) {
11836                handleAppCrashLocked(app, "user-terminated" /*reason*/,
11837                        null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
11838                app.kill("user request after error", true);
11839            }
11840        }
11841    }
11842
11843    private boolean handleAppCrashLocked(ProcessRecord app, String reason,
11844            String shortMsg, String longMsg, String stackTrace) {
11845        long now = SystemClock.uptimeMillis();
11846
11847        Long crashTime;
11848        if (!app.isolated) {
11849            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11850        } else {
11851            crashTime = null;
11852        }
11853        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11854            // This process loses!
11855            Slog.w(TAG, "Process " + app.info.processName
11856                    + " has crashed too many times: killing!");
11857            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11858                    app.userId, app.info.processName, app.uid);
11859            mStackSupervisor.handleAppCrashLocked(app);
11860            if (!app.persistent) {
11861                // We don't want to start this process again until the user
11862                // explicitly does so...  but for persistent process, we really
11863                // need to keep it running.  If a persistent process is actually
11864                // repeatedly crashing, then badness for everyone.
11865                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11866                        app.info.processName);
11867                if (!app.isolated) {
11868                    // XXX We don't have a way to mark isolated processes
11869                    // as bad, since they don't have a peristent identity.
11870                    mBadProcesses.put(app.info.processName, app.uid,
11871                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11872                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11873                }
11874                app.bad = true;
11875                app.removed = true;
11876                // Don't let services in this process be restarted and potentially
11877                // annoy the user repeatedly.  Unless it is persistent, since those
11878                // processes run critical code.
11879                removeProcessLocked(app, false, false, "crash");
11880                mStackSupervisor.resumeTopActivitiesLocked();
11881                return false;
11882            }
11883            mStackSupervisor.resumeTopActivitiesLocked();
11884        } else {
11885            mStackSupervisor.finishTopRunningActivityLocked(app, reason);
11886        }
11887
11888        // Bump up the crash count of any services currently running in the proc.
11889        for (int i=app.services.size()-1; i>=0; i--) {
11890            // Any services running in the application need to be placed
11891            // back in the pending list.
11892            ServiceRecord sr = app.services.valueAt(i);
11893            sr.crashCount++;
11894        }
11895
11896        // If the crashing process is what we consider to be the "home process" and it has been
11897        // replaced by a third-party app, clear the package preferred activities from packages
11898        // with a home activity running in the process to prevent a repeatedly crashing app
11899        // from blocking the user to manually clear the list.
11900        final ArrayList<ActivityRecord> activities = app.activities;
11901        if (app == mHomeProcess && activities.size() > 0
11902                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11903            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11904                final ActivityRecord r = activities.get(activityNdx);
11905                if (r.isHomeActivity()) {
11906                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11907                    try {
11908                        ActivityThread.getPackageManager()
11909                                .clearPackagePreferredActivities(r.packageName);
11910                    } catch (RemoteException c) {
11911                        // pm is in same process, this will never happen.
11912                    }
11913                }
11914            }
11915        }
11916
11917        if (!app.isolated) {
11918            // XXX Can't keep track of crash times for isolated processes,
11919            // because they don't have a perisistent identity.
11920            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11921        }
11922
11923        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11924        return true;
11925    }
11926
11927    void startAppProblemLocked(ProcessRecord app) {
11928        // If this app is not running under the current user, then we
11929        // can't give it a report button because that would require
11930        // launching the report UI under a different user.
11931        app.errorReportReceiver = null;
11932
11933        for (int userId : mCurrentProfileIds) {
11934            if (app.userId == userId) {
11935                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11936                        mContext, app.info.packageName, app.info.flags);
11937            }
11938        }
11939        skipCurrentReceiverLocked(app);
11940    }
11941
11942    void skipCurrentReceiverLocked(ProcessRecord app) {
11943        for (BroadcastQueue queue : mBroadcastQueues) {
11944            queue.skipCurrentReceiverLocked(app);
11945        }
11946    }
11947
11948    /**
11949     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11950     * The application process will exit immediately after this call returns.
11951     * @param app object of the crashing app, null for the system server
11952     * @param crashInfo describing the exception
11953     */
11954    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11955        ProcessRecord r = findAppProcess(app, "Crash");
11956        final String processName = app == null ? "system_server"
11957                : (r == null ? "unknown" : r.processName);
11958
11959        handleApplicationCrashInner("crash", r, processName, crashInfo);
11960    }
11961
11962    /* Native crash reporting uses this inner version because it needs to be somewhat
11963     * decoupled from the AM-managed cleanup lifecycle
11964     */
11965    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11966            ApplicationErrorReport.CrashInfo crashInfo) {
11967        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11968                UserHandle.getUserId(Binder.getCallingUid()), processName,
11969                r == null ? -1 : r.info.flags,
11970                crashInfo.exceptionClassName,
11971                crashInfo.exceptionMessage,
11972                crashInfo.throwFileName,
11973                crashInfo.throwLineNumber);
11974
11975        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11976
11977        crashApplication(r, crashInfo);
11978    }
11979
11980    public void handleApplicationStrictModeViolation(
11981            IBinder app,
11982            int violationMask,
11983            StrictMode.ViolationInfo info) {
11984        ProcessRecord r = findAppProcess(app, "StrictMode");
11985        if (r == null) {
11986            return;
11987        }
11988
11989        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11990            Integer stackFingerprint = info.hashCode();
11991            boolean logIt = true;
11992            synchronized (mAlreadyLoggedViolatedStacks) {
11993                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11994                    logIt = false;
11995                    // TODO: sub-sample into EventLog for these, with
11996                    // the info.durationMillis?  Then we'd get
11997                    // the relative pain numbers, without logging all
11998                    // the stack traces repeatedly.  We'd want to do
11999                    // likewise in the client code, which also does
12000                    // dup suppression, before the Binder call.
12001                } else {
12002                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12003                        mAlreadyLoggedViolatedStacks.clear();
12004                    }
12005                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12006                }
12007            }
12008            if (logIt) {
12009                logStrictModeViolationToDropBox(r, info);
12010            }
12011        }
12012
12013        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12014            AppErrorResult result = new AppErrorResult();
12015            synchronized (this) {
12016                final long origId = Binder.clearCallingIdentity();
12017
12018                Message msg = Message.obtain();
12019                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
12020                HashMap<String, Object> data = new HashMap<String, Object>();
12021                data.put("result", result);
12022                data.put("app", r);
12023                data.put("violationMask", violationMask);
12024                data.put("info", info);
12025                msg.obj = data;
12026                mUiHandler.sendMessage(msg);
12027
12028                Binder.restoreCallingIdentity(origId);
12029            }
12030            int res = result.get();
12031            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12032        }
12033    }
12034
12035    // Depending on the policy in effect, there could be a bunch of
12036    // these in quick succession so we try to batch these together to
12037    // minimize disk writes, number of dropbox entries, and maximize
12038    // compression, by having more fewer, larger records.
12039    private void logStrictModeViolationToDropBox(
12040            ProcessRecord process,
12041            StrictMode.ViolationInfo info) {
12042        if (info == null) {
12043            return;
12044        }
12045        final boolean isSystemApp = process == null ||
12046                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12047                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12048        final String processName = process == null ? "unknown" : process.processName;
12049        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12050        final DropBoxManager dbox = (DropBoxManager)
12051                mContext.getSystemService(Context.DROPBOX_SERVICE);
12052
12053        // Exit early if the dropbox isn't configured to accept this report type.
12054        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12055
12056        boolean bufferWasEmpty;
12057        boolean needsFlush;
12058        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12059        synchronized (sb) {
12060            bufferWasEmpty = sb.length() == 0;
12061            appendDropBoxProcessHeaders(process, processName, sb);
12062            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12063            sb.append("System-App: ").append(isSystemApp).append("\n");
12064            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12065            if (info.violationNumThisLoop != 0) {
12066                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12067            }
12068            if (info.numAnimationsRunning != 0) {
12069                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12070            }
12071            if (info.broadcastIntentAction != null) {
12072                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12073            }
12074            if (info.durationMillis != -1) {
12075                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12076            }
12077            if (info.numInstances != -1) {
12078                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12079            }
12080            if (info.tags != null) {
12081                for (String tag : info.tags) {
12082                    sb.append("Span-Tag: ").append(tag).append("\n");
12083                }
12084            }
12085            sb.append("\n");
12086            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
12087                sb.append(info.crashInfo.stackTrace);
12088                sb.append("\n");
12089            }
12090            if (info.message != null) {
12091                sb.append(info.message);
12092                sb.append("\n");
12093            }
12094
12095            // Only buffer up to ~64k.  Various logging bits truncate
12096            // things at 128k.
12097            needsFlush = (sb.length() > 64 * 1024);
12098        }
12099
12100        // Flush immediately if the buffer's grown too large, or this
12101        // is a non-system app.  Non-system apps are isolated with a
12102        // different tag & policy and not batched.
12103        //
12104        // Batching is useful during internal testing with
12105        // StrictMode settings turned up high.  Without batching,
12106        // thousands of separate files could be created on boot.
12107        if (!isSystemApp || needsFlush) {
12108            new Thread("Error dump: " + dropboxTag) {
12109                @Override
12110                public void run() {
12111                    String report;
12112                    synchronized (sb) {
12113                        report = sb.toString();
12114                        sb.delete(0, sb.length());
12115                        sb.trimToSize();
12116                    }
12117                    if (report.length() != 0) {
12118                        dbox.addText(dropboxTag, report);
12119                    }
12120                }
12121            }.start();
12122            return;
12123        }
12124
12125        // System app batching:
12126        if (!bufferWasEmpty) {
12127            // An existing dropbox-writing thread is outstanding, so
12128            // we don't need to start it up.  The existing thread will
12129            // catch the buffer appends we just did.
12130            return;
12131        }
12132
12133        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
12134        // (After this point, we shouldn't access AMS internal data structures.)
12135        new Thread("Error dump: " + dropboxTag) {
12136            @Override
12137            public void run() {
12138                // 5 second sleep to let stacks arrive and be batched together
12139                try {
12140                    Thread.sleep(5000);  // 5 seconds
12141                } catch (InterruptedException e) {}
12142
12143                String errorReport;
12144                synchronized (mStrictModeBuffer) {
12145                    errorReport = mStrictModeBuffer.toString();
12146                    if (errorReport.length() == 0) {
12147                        return;
12148                    }
12149                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
12150                    mStrictModeBuffer.trimToSize();
12151                }
12152                dbox.addText(dropboxTag, errorReport);
12153            }
12154        }.start();
12155    }
12156
12157    /**
12158     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
12159     * @param app object of the crashing app, null for the system server
12160     * @param tag reported by the caller
12161     * @param system whether this wtf is coming from the system
12162     * @param crashInfo describing the context of the error
12163     * @return true if the process should exit immediately (WTF is fatal)
12164     */
12165    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
12166            final ApplicationErrorReport.CrashInfo crashInfo) {
12167        final int callingUid = Binder.getCallingUid();
12168        final int callingPid = Binder.getCallingPid();
12169
12170        if (system) {
12171            // If this is coming from the system, we could very well have low-level
12172            // system locks held, so we want to do this all asynchronously.  And we
12173            // never want this to become fatal, so there is that too.
12174            mHandler.post(new Runnable() {
12175                @Override public void run() {
12176                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
12177                }
12178            });
12179            return false;
12180        }
12181
12182        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
12183                crashInfo);
12184
12185        if (r != null && r.pid != Process.myPid() &&
12186                Settings.Global.getInt(mContext.getContentResolver(),
12187                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
12188            crashApplication(r, crashInfo);
12189            return true;
12190        } else {
12191            return false;
12192        }
12193    }
12194
12195    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
12196            final ApplicationErrorReport.CrashInfo crashInfo) {
12197        final ProcessRecord r = findAppProcess(app, "WTF");
12198        final String processName = app == null ? "system_server"
12199                : (r == null ? "unknown" : r.processName);
12200
12201        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
12202                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
12203
12204        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
12205
12206        return r;
12207    }
12208
12209    /**
12210     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
12211     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
12212     */
12213    private ProcessRecord findAppProcess(IBinder app, String reason) {
12214        if (app == null) {
12215            return null;
12216        }
12217
12218        synchronized (this) {
12219            final int NP = mProcessNames.getMap().size();
12220            for (int ip=0; ip<NP; ip++) {
12221                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12222                final int NA = apps.size();
12223                for (int ia=0; ia<NA; ia++) {
12224                    ProcessRecord p = apps.valueAt(ia);
12225                    if (p.thread != null && p.thread.asBinder() == app) {
12226                        return p;
12227                    }
12228                }
12229            }
12230
12231            Slog.w(TAG, "Can't find mystery application for " + reason
12232                    + " from pid=" + Binder.getCallingPid()
12233                    + " uid=" + Binder.getCallingUid() + ": " + app);
12234            return null;
12235        }
12236    }
12237
12238    /**
12239     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
12240     * to append various headers to the dropbox log text.
12241     */
12242    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
12243            StringBuilder sb) {
12244        // Watchdog thread ends up invoking this function (with
12245        // a null ProcessRecord) to add the stack file to dropbox.
12246        // Do not acquire a lock on this (am) in such cases, as it
12247        // could cause a potential deadlock, if and when watchdog
12248        // is invoked due to unavailability of lock on am and it
12249        // would prevent watchdog from killing system_server.
12250        if (process == null) {
12251            sb.append("Process: ").append(processName).append("\n");
12252            return;
12253        }
12254        // Note: ProcessRecord 'process' is guarded by the service
12255        // instance.  (notably process.pkgList, which could otherwise change
12256        // concurrently during execution of this method)
12257        synchronized (this) {
12258            sb.append("Process: ").append(processName).append("\n");
12259            int flags = process.info.flags;
12260            IPackageManager pm = AppGlobals.getPackageManager();
12261            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
12262            for (int ip=0; ip<process.pkgList.size(); ip++) {
12263                String pkg = process.pkgList.keyAt(ip);
12264                sb.append("Package: ").append(pkg);
12265                try {
12266                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
12267                    if (pi != null) {
12268                        sb.append(" v").append(pi.versionCode);
12269                        if (pi.versionName != null) {
12270                            sb.append(" (").append(pi.versionName).append(")");
12271                        }
12272                    }
12273                } catch (RemoteException e) {
12274                    Slog.e(TAG, "Error getting package info: " + pkg, e);
12275                }
12276                sb.append("\n");
12277            }
12278        }
12279    }
12280
12281    private static String processClass(ProcessRecord process) {
12282        if (process == null || process.pid == MY_PID) {
12283            return "system_server";
12284        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
12285            return "system_app";
12286        } else {
12287            return "data_app";
12288        }
12289    }
12290
12291    /**
12292     * Write a description of an error (crash, WTF, ANR) to the drop box.
12293     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
12294     * @param process which caused the error, null means the system server
12295     * @param activity which triggered the error, null if unknown
12296     * @param parent activity related to the error, null if unknown
12297     * @param subject line related to the error, null if absent
12298     * @param report in long form describing the error, null if absent
12299     * @param logFile to include in the report, null if none
12300     * @param crashInfo giving an application stack trace, null if absent
12301     */
12302    public void addErrorToDropBox(String eventType,
12303            ProcessRecord process, String processName, ActivityRecord activity,
12304            ActivityRecord parent, String subject,
12305            final String report, final File logFile,
12306            final ApplicationErrorReport.CrashInfo crashInfo) {
12307        // NOTE -- this must never acquire the ActivityManagerService lock,
12308        // otherwise the watchdog may be prevented from resetting the system.
12309
12310        final String dropboxTag = processClass(process) + "_" + eventType;
12311        final DropBoxManager dbox = (DropBoxManager)
12312                mContext.getSystemService(Context.DROPBOX_SERVICE);
12313
12314        // Exit early if the dropbox isn't configured to accept this report type.
12315        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12316
12317        final StringBuilder sb = new StringBuilder(1024);
12318        appendDropBoxProcessHeaders(process, processName, sb);
12319        if (activity != null) {
12320            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
12321        }
12322        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
12323            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
12324        }
12325        if (parent != null && parent != activity) {
12326            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
12327        }
12328        if (subject != null) {
12329            sb.append("Subject: ").append(subject).append("\n");
12330        }
12331        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12332        if (Debug.isDebuggerConnected()) {
12333            sb.append("Debugger: Connected\n");
12334        }
12335        sb.append("\n");
12336
12337        // Do the rest in a worker thread to avoid blocking the caller on I/O
12338        // (After this point, we shouldn't access AMS internal data structures.)
12339        Thread worker = new Thread("Error dump: " + dropboxTag) {
12340            @Override
12341            public void run() {
12342                if (report != null) {
12343                    sb.append(report);
12344                }
12345                if (logFile != null) {
12346                    try {
12347                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
12348                                    "\n\n[[TRUNCATED]]"));
12349                    } catch (IOException e) {
12350                        Slog.e(TAG, "Error reading " + logFile, e);
12351                    }
12352                }
12353                if (crashInfo != null && crashInfo.stackTrace != null) {
12354                    sb.append(crashInfo.stackTrace);
12355                }
12356
12357                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
12358                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
12359                if (lines > 0) {
12360                    sb.append("\n");
12361
12362                    // Merge several logcat streams, and take the last N lines
12363                    InputStreamReader input = null;
12364                    try {
12365                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
12366                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
12367                                "-b", "crash",
12368                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
12369
12370                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
12371                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
12372                        input = new InputStreamReader(logcat.getInputStream());
12373
12374                        int num;
12375                        char[] buf = new char[8192];
12376                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
12377                    } catch (IOException e) {
12378                        Slog.e(TAG, "Error running logcat", e);
12379                    } finally {
12380                        if (input != null) try { input.close(); } catch (IOException e) {}
12381                    }
12382                }
12383
12384                dbox.addText(dropboxTag, sb.toString());
12385            }
12386        };
12387
12388        if (process == null) {
12389            // If process is null, we are being called from some internal code
12390            // and may be about to die -- run this synchronously.
12391            worker.run();
12392        } else {
12393            worker.start();
12394        }
12395    }
12396
12397    /**
12398     * Bring up the "unexpected error" dialog box for a crashing app.
12399     * Deal with edge cases (intercepts from instrumented applications,
12400     * ActivityController, error intent receivers, that sort of thing).
12401     * @param r the application crashing
12402     * @param crashInfo describing the failure
12403     */
12404    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12405        long timeMillis = System.currentTimeMillis();
12406        String shortMsg = crashInfo.exceptionClassName;
12407        String longMsg = crashInfo.exceptionMessage;
12408        String stackTrace = crashInfo.stackTrace;
12409        if (shortMsg != null && longMsg != null) {
12410            longMsg = shortMsg + ": " + longMsg;
12411        } else if (shortMsg != null) {
12412            longMsg = shortMsg;
12413        }
12414
12415        AppErrorResult result = new AppErrorResult();
12416        synchronized (this) {
12417            if (mController != null) {
12418                try {
12419                    String name = r != null ? r.processName : null;
12420                    int pid = r != null ? r.pid : Binder.getCallingPid();
12421                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
12422                    if (!mController.appCrashed(name, pid,
12423                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12424                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12425                                && "Native crash".equals(crashInfo.exceptionClassName)) {
12426                            Slog.w(TAG, "Skip killing native crashed app " + name
12427                                    + "(" + pid + ") during testing");
12428                        } else {
12429                            Slog.w(TAG, "Force-killing crashed app " + name
12430                                    + " at watcher's request");
12431                            if (r != null) {
12432                                r.kill("crash", true);
12433                            } else {
12434                                // Huh.
12435                                Process.killProcess(pid);
12436                                killProcessGroup(uid, pid);
12437                            }
12438                        }
12439                        return;
12440                    }
12441                } catch (RemoteException e) {
12442                    mController = null;
12443                    Watchdog.getInstance().setActivityController(null);
12444                }
12445            }
12446
12447            final long origId = Binder.clearCallingIdentity();
12448
12449            // If this process is running instrumentation, finish it.
12450            if (r != null && r.instrumentationClass != null) {
12451                Slog.w(TAG, "Error in app " + r.processName
12452                      + " running instrumentation " + r.instrumentationClass + ":");
12453                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12454                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12455                Bundle info = new Bundle();
12456                info.putString("shortMsg", shortMsg);
12457                info.putString("longMsg", longMsg);
12458                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12459                Binder.restoreCallingIdentity(origId);
12460                return;
12461            }
12462
12463            // Log crash in battery stats.
12464            if (r != null) {
12465                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12466            }
12467
12468            // If we can't identify the process or it's already exceeded its crash quota,
12469            // quit right away without showing a crash dialog.
12470            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12471                Binder.restoreCallingIdentity(origId);
12472                return;
12473            }
12474
12475            Message msg = Message.obtain();
12476            msg.what = SHOW_ERROR_MSG;
12477            HashMap data = new HashMap();
12478            data.put("result", result);
12479            data.put("app", r);
12480            msg.obj = data;
12481            mUiHandler.sendMessage(msg);
12482
12483            Binder.restoreCallingIdentity(origId);
12484        }
12485
12486        int res = result.get();
12487
12488        Intent appErrorIntent = null;
12489        synchronized (this) {
12490            if (r != null && !r.isolated) {
12491                // XXX Can't keep track of crash time for isolated processes,
12492                // since they don't have a persistent identity.
12493                mProcessCrashTimes.put(r.info.processName, r.uid,
12494                        SystemClock.uptimeMillis());
12495            }
12496            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12497                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12498            }
12499        }
12500
12501        if (appErrorIntent != null) {
12502            try {
12503                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12504            } catch (ActivityNotFoundException e) {
12505                Slog.w(TAG, "bug report receiver dissappeared", e);
12506            }
12507        }
12508    }
12509
12510    Intent createAppErrorIntentLocked(ProcessRecord r,
12511            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12512        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12513        if (report == null) {
12514            return null;
12515        }
12516        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12517        result.setComponent(r.errorReportReceiver);
12518        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12519        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12520        return result;
12521    }
12522
12523    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12524            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12525        if (r.errorReportReceiver == null) {
12526            return null;
12527        }
12528
12529        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12530            return null;
12531        }
12532
12533        ApplicationErrorReport report = new ApplicationErrorReport();
12534        report.packageName = r.info.packageName;
12535        report.installerPackageName = r.errorReportReceiver.getPackageName();
12536        report.processName = r.processName;
12537        report.time = timeMillis;
12538        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12539
12540        if (r.crashing || r.forceCrashReport) {
12541            report.type = ApplicationErrorReport.TYPE_CRASH;
12542            report.crashInfo = crashInfo;
12543        } else if (r.notResponding) {
12544            report.type = ApplicationErrorReport.TYPE_ANR;
12545            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12546
12547            report.anrInfo.activity = r.notRespondingReport.tag;
12548            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12549            report.anrInfo.info = r.notRespondingReport.longMsg;
12550        }
12551
12552        return report;
12553    }
12554
12555    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12556        enforceNotIsolatedCaller("getProcessesInErrorState");
12557        // assume our apps are happy - lazy create the list
12558        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12559
12560        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12561                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12562        int userId = UserHandle.getUserId(Binder.getCallingUid());
12563
12564        synchronized (this) {
12565
12566            // iterate across all processes
12567            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12568                ProcessRecord app = mLruProcesses.get(i);
12569                if (!allUsers && app.userId != userId) {
12570                    continue;
12571                }
12572                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12573                    // This one's in trouble, so we'll generate a report for it
12574                    // crashes are higher priority (in case there's a crash *and* an anr)
12575                    ActivityManager.ProcessErrorStateInfo report = null;
12576                    if (app.crashing) {
12577                        report = app.crashingReport;
12578                    } else if (app.notResponding) {
12579                        report = app.notRespondingReport;
12580                    }
12581
12582                    if (report != null) {
12583                        if (errList == null) {
12584                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12585                        }
12586                        errList.add(report);
12587                    } else {
12588                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12589                                " crashing = " + app.crashing +
12590                                " notResponding = " + app.notResponding);
12591                    }
12592                }
12593            }
12594        }
12595
12596        return errList;
12597    }
12598
12599    static int procStateToImportance(int procState, int memAdj,
12600            ActivityManager.RunningAppProcessInfo currApp) {
12601        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12602        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12603            currApp.lru = memAdj;
12604        } else {
12605            currApp.lru = 0;
12606        }
12607        return imp;
12608    }
12609
12610    private void fillInProcMemInfo(ProcessRecord app,
12611            ActivityManager.RunningAppProcessInfo outInfo) {
12612        outInfo.pid = app.pid;
12613        outInfo.uid = app.info.uid;
12614        if (mHeavyWeightProcess == app) {
12615            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12616        }
12617        if (app.persistent) {
12618            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12619        }
12620        if (app.activities.size() > 0) {
12621            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12622        }
12623        outInfo.lastTrimLevel = app.trimMemoryLevel;
12624        int adj = app.curAdj;
12625        int procState = app.curProcState;
12626        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12627        outInfo.importanceReasonCode = app.adjTypeCode;
12628        outInfo.processState = app.curProcState;
12629    }
12630
12631    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12632        enforceNotIsolatedCaller("getRunningAppProcesses");
12633
12634        final int callingUid = Binder.getCallingUid();
12635
12636        // Lazy instantiation of list
12637        List<ActivityManager.RunningAppProcessInfo> runList = null;
12638        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12639                callingUid) == PackageManager.PERMISSION_GRANTED;
12640        final int userId = UserHandle.getUserId(callingUid);
12641        final boolean allUids = isGetTasksAllowed(
12642                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
12643
12644        synchronized (this) {
12645            // Iterate across all processes
12646            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
12647                ProcessRecord app = mLruProcesses.get(i);
12648                if ((!allUsers && app.userId != userId)
12649                        || (!allUids && app.uid != callingUid)) {
12650                    continue;
12651                }
12652                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12653                    // Generate process state info for running application
12654                    ActivityManager.RunningAppProcessInfo currApp =
12655                        new ActivityManager.RunningAppProcessInfo(app.processName,
12656                                app.pid, app.getPackageList());
12657                    fillInProcMemInfo(app, currApp);
12658                    if (app.adjSource instanceof ProcessRecord) {
12659                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12660                        currApp.importanceReasonImportance =
12661                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12662                                        app.adjSourceProcState);
12663                    } else if (app.adjSource instanceof ActivityRecord) {
12664                        ActivityRecord r = (ActivityRecord)app.adjSource;
12665                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12666                    }
12667                    if (app.adjTarget instanceof ComponentName) {
12668                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12669                    }
12670                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12671                    //        + " lru=" + currApp.lru);
12672                    if (runList == null) {
12673                        runList = new ArrayList<>();
12674                    }
12675                    runList.add(currApp);
12676                }
12677            }
12678        }
12679        return runList;
12680    }
12681
12682    public List<ApplicationInfo> getRunningExternalApplications() {
12683        enforceNotIsolatedCaller("getRunningExternalApplications");
12684        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12685        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12686        if (runningApps != null && runningApps.size() > 0) {
12687            Set<String> extList = new HashSet<String>();
12688            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12689                if (app.pkgList != null) {
12690                    for (String pkg : app.pkgList) {
12691                        extList.add(pkg);
12692                    }
12693                }
12694            }
12695            IPackageManager pm = AppGlobals.getPackageManager();
12696            for (String pkg : extList) {
12697                try {
12698                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12699                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12700                        retList.add(info);
12701                    }
12702                } catch (RemoteException e) {
12703                }
12704            }
12705        }
12706        return retList;
12707    }
12708
12709    @Override
12710    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12711        enforceNotIsolatedCaller("getMyMemoryState");
12712        synchronized (this) {
12713            ProcessRecord proc;
12714            synchronized (mPidsSelfLocked) {
12715                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12716            }
12717            fillInProcMemInfo(proc, outInfo);
12718        }
12719    }
12720
12721    @Override
12722    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12723        if (checkCallingPermission(android.Manifest.permission.DUMP)
12724                != PackageManager.PERMISSION_GRANTED) {
12725            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12726                    + Binder.getCallingPid()
12727                    + ", uid=" + Binder.getCallingUid()
12728                    + " without permission "
12729                    + android.Manifest.permission.DUMP);
12730            return;
12731        }
12732
12733        boolean dumpAll = false;
12734        boolean dumpClient = false;
12735        String dumpPackage = null;
12736
12737        int opti = 0;
12738        while (opti < args.length) {
12739            String opt = args[opti];
12740            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12741                break;
12742            }
12743            opti++;
12744            if ("-a".equals(opt)) {
12745                dumpAll = true;
12746            } else if ("-c".equals(opt)) {
12747                dumpClient = true;
12748            } else if ("-p".equals(opt)) {
12749                if (opti < args.length) {
12750                    dumpPackage = args[opti];
12751                    opti++;
12752                } else {
12753                    pw.println("Error: -p option requires package argument");
12754                    return;
12755                }
12756                dumpClient = true;
12757            } else if ("-h".equals(opt)) {
12758                pw.println("Activity manager dump options:");
12759                pw.println("  [-a] [-c] [-p package] [-h] [cmd] ...");
12760                pw.println("  cmd may be one of:");
12761                pw.println("    a[ctivities]: activity stack state");
12762                pw.println("    r[recents]: recent activities state");
12763                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12764                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12765                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12766                pw.println("    o[om]: out of memory management");
12767                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12768                pw.println("    provider [COMP_SPEC]: provider client-side state");
12769                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12770                pw.println("    as[sociations]: tracked app associations");
12771                pw.println("    service [COMP_SPEC]: service client-side state");
12772                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12773                pw.println("    all: dump all activities");
12774                pw.println("    top: dump the top activity");
12775                pw.println("    write: write all pending state to storage");
12776                pw.println("    track-associations: enable association tracking");
12777                pw.println("    untrack-associations: disable and clear association tracking");
12778                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12779                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12780                pw.println("    a partial substring in a component name, a");
12781                pw.println("    hex object identifier.");
12782                pw.println("  -a: include all available server state.");
12783                pw.println("  -c: include client state.");
12784                pw.println("  -p: limit output to given package.");
12785                return;
12786            } else {
12787                pw.println("Unknown argument: " + opt + "; use -h for help");
12788            }
12789        }
12790
12791        long origId = Binder.clearCallingIdentity();
12792        boolean more = false;
12793        // Is the caller requesting to dump a particular piece of data?
12794        if (opti < args.length) {
12795            String cmd = args[opti];
12796            opti++;
12797            if ("activities".equals(cmd) || "a".equals(cmd)) {
12798                synchronized (this) {
12799                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12800                }
12801            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12802                synchronized (this) {
12803                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
12804                }
12805            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12806                String[] newArgs;
12807                String name;
12808                if (opti >= args.length) {
12809                    name = null;
12810                    newArgs = EMPTY_STRING_ARRAY;
12811                } else {
12812                    dumpPackage = args[opti];
12813                    opti++;
12814                    newArgs = new String[args.length - opti];
12815                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12816                            args.length - opti);
12817                }
12818                synchronized (this) {
12819                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
12820                }
12821            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12822                String[] newArgs;
12823                String name;
12824                if (opti >= args.length) {
12825                    name = null;
12826                    newArgs = EMPTY_STRING_ARRAY;
12827                } else {
12828                    dumpPackage = args[opti];
12829                    opti++;
12830                    newArgs = new String[args.length - opti];
12831                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12832                            args.length - opti);
12833                }
12834                synchronized (this) {
12835                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
12836                }
12837            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12838                String[] newArgs;
12839                String name;
12840                if (opti >= args.length) {
12841                    name = null;
12842                    newArgs = EMPTY_STRING_ARRAY;
12843                } else {
12844                    dumpPackage = args[opti];
12845                    opti++;
12846                    newArgs = new String[args.length - opti];
12847                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12848                            args.length - opti);
12849                }
12850                synchronized (this) {
12851                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
12852                }
12853            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12854                synchronized (this) {
12855                    dumpOomLocked(fd, pw, args, opti, true);
12856                }
12857            } else if ("provider".equals(cmd)) {
12858                String[] newArgs;
12859                String name;
12860                if (opti >= args.length) {
12861                    name = null;
12862                    newArgs = EMPTY_STRING_ARRAY;
12863                } else {
12864                    name = args[opti];
12865                    opti++;
12866                    newArgs = new String[args.length - opti];
12867                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12868                }
12869                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12870                    pw.println("No providers match: " + name);
12871                    pw.println("Use -h for help.");
12872                }
12873            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12874                synchronized (this) {
12875                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12876                }
12877            } else if ("service".equals(cmd)) {
12878                String[] newArgs;
12879                String name;
12880                if (opti >= args.length) {
12881                    name = null;
12882                    newArgs = EMPTY_STRING_ARRAY;
12883                } else {
12884                    name = args[opti];
12885                    opti++;
12886                    newArgs = new String[args.length - opti];
12887                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12888                            args.length - opti);
12889                }
12890                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12891                    pw.println("No services match: " + name);
12892                    pw.println("Use -h for help.");
12893                }
12894            } else if ("package".equals(cmd)) {
12895                String[] newArgs;
12896                if (opti >= args.length) {
12897                    pw.println("package: no package name specified");
12898                    pw.println("Use -h for help.");
12899                } else {
12900                    dumpPackage = args[opti];
12901                    opti++;
12902                    newArgs = new String[args.length - opti];
12903                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12904                            args.length - opti);
12905                    args = newArgs;
12906                    opti = 0;
12907                    more = true;
12908                }
12909            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
12910                synchronized (this) {
12911                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12912                }
12913            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12914                synchronized (this) {
12915                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12916                }
12917            } else if ("write".equals(cmd)) {
12918                mTaskPersister.flush();
12919                pw.println("All tasks persisted.");
12920                return;
12921            } else if ("track-associations".equals(cmd)) {
12922                synchronized (this) {
12923                    if (!mTrackingAssociations) {
12924                        mTrackingAssociations = true;
12925                        pw.println("Association tracking started.");
12926                    } else {
12927                        pw.println("Association tracking already enabled.");
12928                    }
12929                }
12930                return;
12931            } else if ("untrack-associations".equals(cmd)) {
12932                synchronized (this) {
12933                    if (mTrackingAssociations) {
12934                        mTrackingAssociations = false;
12935                        mAssociations.clear();
12936                        pw.println("Association tracking stopped.");
12937                    } else {
12938                        pw.println("Association tracking not running.");
12939                    }
12940                }
12941                return;
12942            } else {
12943                // Dumping a single activity?
12944                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12945                    pw.println("Bad activity command, or no activities match: " + cmd);
12946                    pw.println("Use -h for help.");
12947                }
12948            }
12949            if (!more) {
12950                Binder.restoreCallingIdentity(origId);
12951                return;
12952            }
12953        }
12954
12955        // No piece of data specified, dump everything.
12956        synchronized (this) {
12957            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12958            pw.println();
12959            if (dumpAll) {
12960                pw.println("-------------------------------------------------------------------------------");
12961            }
12962            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12963            pw.println();
12964            if (dumpAll) {
12965                pw.println("-------------------------------------------------------------------------------");
12966            }
12967            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12968            pw.println();
12969            if (dumpAll) {
12970                pw.println("-------------------------------------------------------------------------------");
12971            }
12972            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12973            pw.println();
12974            if (dumpAll) {
12975                pw.println("-------------------------------------------------------------------------------");
12976            }
12977            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12978            pw.println();
12979            if (dumpAll) {
12980                pw.println("-------------------------------------------------------------------------------");
12981            }
12982            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12983            if (mAssociations.size() > 0) {
12984                pw.println();
12985                if (dumpAll) {
12986                    pw.println("-------------------------------------------------------------------------------");
12987                }
12988                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12989            }
12990            pw.println();
12991            if (dumpAll) {
12992                pw.println("-------------------------------------------------------------------------------");
12993            }
12994            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12995        }
12996        Binder.restoreCallingIdentity(origId);
12997    }
12998
12999    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13000            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13001        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13002
13003        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13004                dumpPackage);
13005        boolean needSep = printedAnything;
13006
13007        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13008                dumpPackage, needSep, "  mFocusedActivity: ");
13009        if (printed) {
13010            printedAnything = true;
13011            needSep = false;
13012        }
13013
13014        if (dumpPackage == null) {
13015            if (needSep) {
13016                pw.println();
13017            }
13018            needSep = true;
13019            printedAnything = true;
13020            mStackSupervisor.dump(pw, "  ");
13021        }
13022
13023        if (!printedAnything) {
13024            pw.println("  (nothing)");
13025        }
13026    }
13027
13028    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13029            int opti, boolean dumpAll, String dumpPackage) {
13030        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13031
13032        boolean printedAnything = false;
13033
13034        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13035            boolean printedHeader = false;
13036
13037            final int N = mRecentTasks.size();
13038            for (int i=0; i<N; i++) {
13039                TaskRecord tr = mRecentTasks.get(i);
13040                if (dumpPackage != null) {
13041                    if (tr.realActivity == null ||
13042                            !dumpPackage.equals(tr.realActivity)) {
13043                        continue;
13044                    }
13045                }
13046                if (!printedHeader) {
13047                    pw.println("  Recent tasks:");
13048                    printedHeader = true;
13049                    printedAnything = true;
13050                }
13051                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13052                        pw.println(tr);
13053                if (dumpAll) {
13054                    mRecentTasks.get(i).dump(pw, "    ");
13055                }
13056            }
13057        }
13058
13059        if (!printedAnything) {
13060            pw.println("  (nothing)");
13061        }
13062    }
13063
13064    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13065            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13066        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13067
13068        int dumpUid = 0;
13069        if (dumpPackage != null) {
13070            IPackageManager pm = AppGlobals.getPackageManager();
13071            try {
13072                dumpUid = pm.getPackageUid(dumpPackage, 0);
13073            } catch (RemoteException e) {
13074            }
13075        }
13076
13077        boolean printedAnything = false;
13078
13079        final long now = SystemClock.uptimeMillis();
13080
13081        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13082            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13083                    = mAssociations.valueAt(i1);
13084            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13085                SparseArray<ArrayMap<String, Association>> sourceUids
13086                        = targetComponents.valueAt(i2);
13087                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13088                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13089                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13090                        Association ass = sourceProcesses.valueAt(i4);
13091                        if (dumpPackage != null) {
13092                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13093                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13094                                continue;
13095                            }
13096                        }
13097                        printedAnything = true;
13098                        pw.print("  ");
13099                        pw.print(ass.mTargetProcess);
13100                        pw.print("/");
13101                        UserHandle.formatUid(pw, ass.mTargetUid);
13102                        pw.print(" <- ");
13103                        pw.print(ass.mSourceProcess);
13104                        pw.print("/");
13105                        UserHandle.formatUid(pw, ass.mSourceUid);
13106                        pw.println();
13107                        pw.print("    via ");
13108                        pw.print(ass.mTargetComponent.flattenToShortString());
13109                        pw.println();
13110                        pw.print("    ");
13111                        long dur = ass.mTime;
13112                        if (ass.mNesting > 0) {
13113                            dur += now - ass.mStartTime;
13114                        }
13115                        TimeUtils.formatDuration(dur, pw);
13116                        pw.print(" (");
13117                        pw.print(ass.mCount);
13118                        pw.println(" times)");
13119                        if (ass.mNesting > 0) {
13120                            pw.print("    ");
13121                            pw.print(" Currently active: ");
13122                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13123                            pw.println();
13124                        }
13125                    }
13126                }
13127            }
13128
13129        }
13130
13131        if (!printedAnything) {
13132            pw.println("  (nothing)");
13133        }
13134    }
13135
13136    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13137            int opti, boolean dumpAll, String dumpPackage) {
13138        boolean needSep = false;
13139        boolean printedAnything = false;
13140        int numPers = 0;
13141
13142        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13143
13144        if (dumpAll) {
13145            final int NP = mProcessNames.getMap().size();
13146            for (int ip=0; ip<NP; ip++) {
13147                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13148                final int NA = procs.size();
13149                for (int ia=0; ia<NA; ia++) {
13150                    ProcessRecord r = procs.valueAt(ia);
13151                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13152                        continue;
13153                    }
13154                    if (!needSep) {
13155                        pw.println("  All known processes:");
13156                        needSep = true;
13157                        printedAnything = true;
13158                    }
13159                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13160                        pw.print(" UID "); pw.print(procs.keyAt(ia));
13161                        pw.print(" "); pw.println(r);
13162                    r.dump(pw, "    ");
13163                    if (r.persistent) {
13164                        numPers++;
13165                    }
13166                }
13167            }
13168        }
13169
13170        if (mIsolatedProcesses.size() > 0) {
13171            boolean printed = false;
13172            for (int i=0; i<mIsolatedProcesses.size(); i++) {
13173                ProcessRecord r = mIsolatedProcesses.valueAt(i);
13174                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13175                    continue;
13176                }
13177                if (!printed) {
13178                    if (needSep) {
13179                        pw.println();
13180                    }
13181                    pw.println("  Isolated process list (sorted by uid):");
13182                    printedAnything = true;
13183                    printed = true;
13184                    needSep = true;
13185                }
13186                pw.println(String.format("%sIsolated #%2d: %s",
13187                        "    ", i, r.toString()));
13188            }
13189        }
13190
13191        if (mActiveUids.size() > 0) {
13192            if (needSep) {
13193                pw.println();
13194            }
13195            pw.println("  UID states:");
13196            for (int i=0; i<mActiveUids.size(); i++) {
13197                UidRecord uidRec = mActiveUids.valueAt(i);
13198                pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13199                pw.print(": "); pw.println(uidRec);
13200            }
13201            needSep = true;
13202            printedAnything = true;
13203        }
13204
13205        if (mLruProcesses.size() > 0) {
13206            if (needSep) {
13207                pw.println();
13208            }
13209            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
13210                    pw.print(" total, non-act at ");
13211                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13212                    pw.print(", non-svc at ");
13213                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13214                    pw.println("):");
13215            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
13216            needSep = true;
13217            printedAnything = true;
13218        }
13219
13220        if (dumpAll || dumpPackage != null) {
13221            synchronized (mPidsSelfLocked) {
13222                boolean printed = false;
13223                for (int i=0; i<mPidsSelfLocked.size(); i++) {
13224                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
13225                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13226                        continue;
13227                    }
13228                    if (!printed) {
13229                        if (needSep) pw.println();
13230                        needSep = true;
13231                        pw.println("  PID mappings:");
13232                        printed = true;
13233                        printedAnything = true;
13234                    }
13235                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
13236                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
13237                }
13238            }
13239        }
13240
13241        if (mForegroundProcesses.size() > 0) {
13242            synchronized (mPidsSelfLocked) {
13243                boolean printed = false;
13244                for (int i=0; i<mForegroundProcesses.size(); i++) {
13245                    ProcessRecord r = mPidsSelfLocked.get(
13246                            mForegroundProcesses.valueAt(i).pid);
13247                    if (dumpPackage != null && (r == null
13248                            || !r.pkgList.containsKey(dumpPackage))) {
13249                        continue;
13250                    }
13251                    if (!printed) {
13252                        if (needSep) pw.println();
13253                        needSep = true;
13254                        pw.println("  Foreground Processes:");
13255                        printed = true;
13256                        printedAnything = true;
13257                    }
13258                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
13259                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
13260                }
13261            }
13262        }
13263
13264        if (mPersistentStartingProcesses.size() > 0) {
13265            if (needSep) pw.println();
13266            needSep = true;
13267            printedAnything = true;
13268            pw.println("  Persisent processes that are starting:");
13269            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
13270                    "Starting Norm", "Restarting PERS", dumpPackage);
13271        }
13272
13273        if (mRemovedProcesses.size() > 0) {
13274            if (needSep) pw.println();
13275            needSep = true;
13276            printedAnything = true;
13277            pw.println("  Processes that are being removed:");
13278            dumpProcessList(pw, this, mRemovedProcesses, "    ",
13279                    "Removed Norm", "Removed PERS", dumpPackage);
13280        }
13281
13282        if (mProcessesOnHold.size() > 0) {
13283            if (needSep) pw.println();
13284            needSep = true;
13285            printedAnything = true;
13286            pw.println("  Processes that are on old until the system is ready:");
13287            dumpProcessList(pw, this, mProcessesOnHold, "    ",
13288                    "OnHold Norm", "OnHold PERS", dumpPackage);
13289        }
13290
13291        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
13292
13293        if (mProcessCrashTimes.getMap().size() > 0) {
13294            boolean printed = false;
13295            long now = SystemClock.uptimeMillis();
13296            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
13297            final int NP = pmap.size();
13298            for (int ip=0; ip<NP; ip++) {
13299                String pname = pmap.keyAt(ip);
13300                SparseArray<Long> uids = pmap.valueAt(ip);
13301                final int N = uids.size();
13302                for (int i=0; i<N; i++) {
13303                    int puid = uids.keyAt(i);
13304                    ProcessRecord r = mProcessNames.get(pname, puid);
13305                    if (dumpPackage != null && (r == null
13306                            || !r.pkgList.containsKey(dumpPackage))) {
13307                        continue;
13308                    }
13309                    if (!printed) {
13310                        if (needSep) pw.println();
13311                        needSep = true;
13312                        pw.println("  Time since processes crashed:");
13313                        printed = true;
13314                        printedAnything = true;
13315                    }
13316                    pw.print("    Process "); pw.print(pname);
13317                            pw.print(" uid "); pw.print(puid);
13318                            pw.print(": last crashed ");
13319                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
13320                            pw.println(" ago");
13321                }
13322            }
13323        }
13324
13325        if (mBadProcesses.getMap().size() > 0) {
13326            boolean printed = false;
13327            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
13328            final int NP = pmap.size();
13329            for (int ip=0; ip<NP; ip++) {
13330                String pname = pmap.keyAt(ip);
13331                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
13332                final int N = uids.size();
13333                for (int i=0; i<N; i++) {
13334                    int puid = uids.keyAt(i);
13335                    ProcessRecord r = mProcessNames.get(pname, puid);
13336                    if (dumpPackage != null && (r == null
13337                            || !r.pkgList.containsKey(dumpPackage))) {
13338                        continue;
13339                    }
13340                    if (!printed) {
13341                        if (needSep) pw.println();
13342                        needSep = true;
13343                        pw.println("  Bad processes:");
13344                        printedAnything = true;
13345                    }
13346                    BadProcessInfo info = uids.valueAt(i);
13347                    pw.print("    Bad process "); pw.print(pname);
13348                            pw.print(" uid "); pw.print(puid);
13349                            pw.print(": crashed at time "); pw.println(info.time);
13350                    if (info.shortMsg != null) {
13351                        pw.print("      Short msg: "); pw.println(info.shortMsg);
13352                    }
13353                    if (info.longMsg != null) {
13354                        pw.print("      Long msg: "); pw.println(info.longMsg);
13355                    }
13356                    if (info.stack != null) {
13357                        pw.println("      Stack:");
13358                        int lastPos = 0;
13359                        for (int pos=0; pos<info.stack.length(); pos++) {
13360                            if (info.stack.charAt(pos) == '\n') {
13361                                pw.print("        ");
13362                                pw.write(info.stack, lastPos, pos-lastPos);
13363                                pw.println();
13364                                lastPos = pos+1;
13365                            }
13366                        }
13367                        if (lastPos < info.stack.length()) {
13368                            pw.print("        ");
13369                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
13370                            pw.println();
13371                        }
13372                    }
13373                }
13374            }
13375        }
13376
13377        if (dumpPackage == null) {
13378            pw.println();
13379            needSep = false;
13380            pw.println("  mStartedUsers:");
13381            for (int i=0; i<mStartedUsers.size(); i++) {
13382                UserState uss = mStartedUsers.valueAt(i);
13383                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
13384                        pw.print(": "); uss.dump("", pw);
13385            }
13386            pw.print("  mStartedUserArray: [");
13387            for (int i=0; i<mStartedUserArray.length; i++) {
13388                if (i > 0) pw.print(", ");
13389                pw.print(mStartedUserArray[i]);
13390            }
13391            pw.println("]");
13392            pw.print("  mUserLru: [");
13393            for (int i=0; i<mUserLru.size(); i++) {
13394                if (i > 0) pw.print(", ");
13395                pw.print(mUserLru.get(i));
13396            }
13397            pw.println("]");
13398            if (dumpAll) {
13399                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
13400            }
13401            synchronized (mUserProfileGroupIdsSelfLocked) {
13402                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
13403                    pw.println("  mUserProfileGroupIds:");
13404                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
13405                        pw.print("    User #");
13406                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
13407                        pw.print(" -> profile #");
13408                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
13409                    }
13410                }
13411            }
13412        }
13413        if (mHomeProcess != null && (dumpPackage == null
13414                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13415            if (needSep) {
13416                pw.println();
13417                needSep = false;
13418            }
13419            pw.println("  mHomeProcess: " + mHomeProcess);
13420        }
13421        if (mPreviousProcess != null && (dumpPackage == null
13422                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13423            if (needSep) {
13424                pw.println();
13425                needSep = false;
13426            }
13427            pw.println("  mPreviousProcess: " + mPreviousProcess);
13428        }
13429        if (dumpAll) {
13430            StringBuilder sb = new StringBuilder(128);
13431            sb.append("  mPreviousProcessVisibleTime: ");
13432            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13433            pw.println(sb);
13434        }
13435        if (mHeavyWeightProcess != null && (dumpPackage == null
13436                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13437            if (needSep) {
13438                pw.println();
13439                needSep = false;
13440            }
13441            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13442        }
13443        if (dumpPackage == null) {
13444            pw.println("  mConfiguration: " + mConfiguration);
13445        }
13446        if (dumpAll) {
13447            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13448            if (mCompatModePackages.getPackages().size() > 0) {
13449                boolean printed = false;
13450                for (Map.Entry<String, Integer> entry
13451                        : mCompatModePackages.getPackages().entrySet()) {
13452                    String pkg = entry.getKey();
13453                    int mode = entry.getValue();
13454                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
13455                        continue;
13456                    }
13457                    if (!printed) {
13458                        pw.println("  mScreenCompatPackages:");
13459                        printed = true;
13460                    }
13461                    pw.print("    "); pw.print(pkg); pw.print(": ");
13462                            pw.print(mode); pw.println();
13463                }
13464            }
13465        }
13466        if (dumpPackage == null) {
13467            pw.println("  mWakefulness="
13468                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
13469            pw.println("  mSleepTokens=" + mSleepTokens);
13470            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
13471                    + lockScreenShownToString());
13472            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
13473            if (mRunningVoice != null) {
13474                pw.println("  mRunningVoice=" + mRunningVoice);
13475                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
13476            }
13477        }
13478        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
13479                || mOrigWaitForDebugger) {
13480            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
13481                    || dumpPackage.equals(mOrigDebugApp)) {
13482                if (needSep) {
13483                    pw.println();
13484                    needSep = false;
13485                }
13486                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
13487                        + " mDebugTransient=" + mDebugTransient
13488                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
13489            }
13490        }
13491        if (mCurAppTimeTracker != null) {
13492            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
13493        }
13494        if (mMemWatchProcesses.getMap().size() > 0) {
13495            pw.println("  Mem watch processes:");
13496            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
13497                    = mMemWatchProcesses.getMap();
13498            for (int i=0; i<procs.size(); i++) {
13499                final String proc = procs.keyAt(i);
13500                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
13501                for (int j=0; j<uids.size(); j++) {
13502                    if (needSep) {
13503                        pw.println();
13504                        needSep = false;
13505                    }
13506                    StringBuilder sb = new StringBuilder();
13507                    sb.append("    ").append(proc).append('/');
13508                    UserHandle.formatUid(sb, uids.keyAt(j));
13509                    Pair<Long, String> val = uids.valueAt(j);
13510                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
13511                    if (val.second != null) {
13512                        sb.append(", report to ").append(val.second);
13513                    }
13514                    pw.println(sb.toString());
13515                }
13516            }
13517            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
13518            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
13519            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
13520                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
13521        }
13522        if (mOpenGlTraceApp != null) {
13523            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
13524                if (needSep) {
13525                    pw.println();
13526                    needSep = false;
13527                }
13528                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
13529            }
13530        }
13531        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
13532                || mProfileFd != null) {
13533            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13534                if (needSep) {
13535                    pw.println();
13536                    needSep = false;
13537                }
13538                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13539                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13540                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13541                        + mAutoStopProfiler);
13542                pw.println("  mProfileType=" + mProfileType);
13543            }
13544        }
13545        if (dumpPackage == null) {
13546            if (mAlwaysFinishActivities || mController != null) {
13547                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
13548                        + " mController=" + mController);
13549            }
13550            if (dumpAll) {
13551                pw.println("  Total persistent processes: " + numPers);
13552                pw.println("  mProcessesReady=" + mProcessesReady
13553                        + " mSystemReady=" + mSystemReady
13554                        + " mBooted=" + mBooted
13555                        + " mFactoryTest=" + mFactoryTest);
13556                pw.println("  mBooting=" + mBooting
13557                        + " mCallFinishBooting=" + mCallFinishBooting
13558                        + " mBootAnimationComplete=" + mBootAnimationComplete);
13559                pw.print("  mLastPowerCheckRealtime=");
13560                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13561                        pw.println("");
13562                pw.print("  mLastPowerCheckUptime=");
13563                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13564                        pw.println("");
13565                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13566                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13567                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13568                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
13569                        + " (" + mLruProcesses.size() + " total)"
13570                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13571                        + " mNumServiceProcs=" + mNumServiceProcs
13572                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13573                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
13574                        + " mLastMemoryLevel" + mLastMemoryLevel
13575                        + " mLastNumProcesses" + mLastNumProcesses);
13576                long now = SystemClock.uptimeMillis();
13577                pw.print("  mLastIdleTime=");
13578                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
13579                        pw.print(" mLowRamSinceLastIdle=");
13580                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13581                        pw.println();
13582            }
13583        }
13584
13585        if (!printedAnything) {
13586            pw.println("  (nothing)");
13587        }
13588    }
13589
13590    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13591            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13592        if (mProcessesToGc.size() > 0) {
13593            boolean printed = false;
13594            long now = SystemClock.uptimeMillis();
13595            for (int i=0; i<mProcessesToGc.size(); i++) {
13596                ProcessRecord proc = mProcessesToGc.get(i);
13597                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13598                    continue;
13599                }
13600                if (!printed) {
13601                    if (needSep) pw.println();
13602                    needSep = true;
13603                    pw.println("  Processes that are waiting to GC:");
13604                    printed = true;
13605                }
13606                pw.print("    Process "); pw.println(proc);
13607                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13608                        pw.print(", last gced=");
13609                        pw.print(now-proc.lastRequestedGc);
13610                        pw.print(" ms ago, last lowMem=");
13611                        pw.print(now-proc.lastLowMemory);
13612                        pw.println(" ms ago");
13613
13614            }
13615        }
13616        return needSep;
13617    }
13618
13619    void printOomLevel(PrintWriter pw, String name, int adj) {
13620        pw.print("    ");
13621        if (adj >= 0) {
13622            pw.print(' ');
13623            if (adj < 10) pw.print(' ');
13624        } else {
13625            if (adj > -10) pw.print(' ');
13626        }
13627        pw.print(adj);
13628        pw.print(": ");
13629        pw.print(name);
13630        pw.print(" (");
13631        pw.print(mProcessList.getMemLevel(adj)/1024);
13632        pw.println(" kB)");
13633    }
13634
13635    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13636            int opti, boolean dumpAll) {
13637        boolean needSep = false;
13638
13639        if (mLruProcesses.size() > 0) {
13640            if (needSep) pw.println();
13641            needSep = true;
13642            pw.println("  OOM levels:");
13643            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13644            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13645            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13646            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13647            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13648            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13649            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13650            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13651            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13652            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13653            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13654            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13655            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13656            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13657
13658            if (needSep) pw.println();
13659            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13660                    pw.print(" total, non-act at ");
13661                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13662                    pw.print(", non-svc at ");
13663                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13664                    pw.println("):");
13665            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13666            needSep = true;
13667        }
13668
13669        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13670
13671        pw.println();
13672        pw.println("  mHomeProcess: " + mHomeProcess);
13673        pw.println("  mPreviousProcess: " + mPreviousProcess);
13674        if (mHeavyWeightProcess != null) {
13675            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13676        }
13677
13678        return true;
13679    }
13680
13681    /**
13682     * There are three ways to call this:
13683     *  - no provider specified: dump all the providers
13684     *  - a flattened component name that matched an existing provider was specified as the
13685     *    first arg: dump that one provider
13686     *  - the first arg isn't the flattened component name of an existing provider:
13687     *    dump all providers whose component contains the first arg as a substring
13688     */
13689    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13690            int opti, boolean dumpAll) {
13691        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13692    }
13693
13694    static class ItemMatcher {
13695        ArrayList<ComponentName> components;
13696        ArrayList<String> strings;
13697        ArrayList<Integer> objects;
13698        boolean all;
13699
13700        ItemMatcher() {
13701            all = true;
13702        }
13703
13704        void build(String name) {
13705            ComponentName componentName = ComponentName.unflattenFromString(name);
13706            if (componentName != null) {
13707                if (components == null) {
13708                    components = new ArrayList<ComponentName>();
13709                }
13710                components.add(componentName);
13711                all = false;
13712            } else {
13713                int objectId = 0;
13714                // Not a '/' separated full component name; maybe an object ID?
13715                try {
13716                    objectId = Integer.parseInt(name, 16);
13717                    if (objects == null) {
13718                        objects = new ArrayList<Integer>();
13719                    }
13720                    objects.add(objectId);
13721                    all = false;
13722                } catch (RuntimeException e) {
13723                    // Not an integer; just do string match.
13724                    if (strings == null) {
13725                        strings = new ArrayList<String>();
13726                    }
13727                    strings.add(name);
13728                    all = false;
13729                }
13730            }
13731        }
13732
13733        int build(String[] args, int opti) {
13734            for (; opti<args.length; opti++) {
13735                String name = args[opti];
13736                if ("--".equals(name)) {
13737                    return opti+1;
13738                }
13739                build(name);
13740            }
13741            return opti;
13742        }
13743
13744        boolean match(Object object, ComponentName comp) {
13745            if (all) {
13746                return true;
13747            }
13748            if (components != null) {
13749                for (int i=0; i<components.size(); i++) {
13750                    if (components.get(i).equals(comp)) {
13751                        return true;
13752                    }
13753                }
13754            }
13755            if (objects != null) {
13756                for (int i=0; i<objects.size(); i++) {
13757                    if (System.identityHashCode(object) == objects.get(i)) {
13758                        return true;
13759                    }
13760                }
13761            }
13762            if (strings != null) {
13763                String flat = comp.flattenToString();
13764                for (int i=0; i<strings.size(); i++) {
13765                    if (flat.contains(strings.get(i))) {
13766                        return true;
13767                    }
13768                }
13769            }
13770            return false;
13771        }
13772    }
13773
13774    /**
13775     * There are three things that cmd can be:
13776     *  - a flattened component name that matches an existing activity
13777     *  - the cmd arg isn't the flattened component name of an existing activity:
13778     *    dump all activity whose component contains the cmd as a substring
13779     *  - A hex number of the ActivityRecord object instance.
13780     */
13781    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13782            int opti, boolean dumpAll) {
13783        ArrayList<ActivityRecord> activities;
13784
13785        synchronized (this) {
13786            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13787        }
13788
13789        if (activities.size() <= 0) {
13790            return false;
13791        }
13792
13793        String[] newArgs = new String[args.length - opti];
13794        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13795
13796        TaskRecord lastTask = null;
13797        boolean needSep = false;
13798        for (int i=activities.size()-1; i>=0; i--) {
13799            ActivityRecord r = activities.get(i);
13800            if (needSep) {
13801                pw.println();
13802            }
13803            needSep = true;
13804            synchronized (this) {
13805                if (lastTask != r.task) {
13806                    lastTask = r.task;
13807                    pw.print("TASK "); pw.print(lastTask.affinity);
13808                            pw.print(" id="); pw.println(lastTask.taskId);
13809                    if (dumpAll) {
13810                        lastTask.dump(pw, "  ");
13811                    }
13812                }
13813            }
13814            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13815        }
13816        return true;
13817    }
13818
13819    /**
13820     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13821     * there is a thread associated with the activity.
13822     */
13823    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13824            final ActivityRecord r, String[] args, boolean dumpAll) {
13825        String innerPrefix = prefix + "  ";
13826        synchronized (this) {
13827            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13828                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13829                    pw.print(" pid=");
13830                    if (r.app != null) pw.println(r.app.pid);
13831                    else pw.println("(not running)");
13832            if (dumpAll) {
13833                r.dump(pw, innerPrefix);
13834            }
13835        }
13836        if (r.app != null && r.app.thread != null) {
13837            // flush anything that is already in the PrintWriter since the thread is going
13838            // to write to the file descriptor directly
13839            pw.flush();
13840            try {
13841                TransferPipe tp = new TransferPipe();
13842                try {
13843                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13844                            r.appToken, innerPrefix, args);
13845                    tp.go(fd);
13846                } finally {
13847                    tp.kill();
13848                }
13849            } catch (IOException e) {
13850                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13851            } catch (RemoteException e) {
13852                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13853            }
13854        }
13855    }
13856
13857    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13858            int opti, boolean dumpAll, String dumpPackage) {
13859        boolean needSep = false;
13860        boolean onlyHistory = false;
13861        boolean printedAnything = false;
13862
13863        if ("history".equals(dumpPackage)) {
13864            if (opti < args.length && "-s".equals(args[opti])) {
13865                dumpAll = false;
13866            }
13867            onlyHistory = true;
13868            dumpPackage = null;
13869        }
13870
13871        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13872        if (!onlyHistory && dumpAll) {
13873            if (mRegisteredReceivers.size() > 0) {
13874                boolean printed = false;
13875                Iterator it = mRegisteredReceivers.values().iterator();
13876                while (it.hasNext()) {
13877                    ReceiverList r = (ReceiverList)it.next();
13878                    if (dumpPackage != null && (r.app == null ||
13879                            !dumpPackage.equals(r.app.info.packageName))) {
13880                        continue;
13881                    }
13882                    if (!printed) {
13883                        pw.println("  Registered Receivers:");
13884                        needSep = true;
13885                        printed = true;
13886                        printedAnything = true;
13887                    }
13888                    pw.print("  * "); pw.println(r);
13889                    r.dump(pw, "    ");
13890                }
13891            }
13892
13893            if (mReceiverResolver.dump(pw, needSep ?
13894                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13895                    "    ", dumpPackage, false, false)) {
13896                needSep = true;
13897                printedAnything = true;
13898            }
13899        }
13900
13901        for (BroadcastQueue q : mBroadcastQueues) {
13902            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13903            printedAnything |= needSep;
13904        }
13905
13906        needSep = true;
13907
13908        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13909            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13910                if (needSep) {
13911                    pw.println();
13912                }
13913                needSep = true;
13914                printedAnything = true;
13915                pw.print("  Sticky broadcasts for user ");
13916                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13917                StringBuilder sb = new StringBuilder(128);
13918                for (Map.Entry<String, ArrayList<Intent>> ent
13919                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13920                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13921                    if (dumpAll) {
13922                        pw.println(":");
13923                        ArrayList<Intent> intents = ent.getValue();
13924                        final int N = intents.size();
13925                        for (int i=0; i<N; i++) {
13926                            sb.setLength(0);
13927                            sb.append("    Intent: ");
13928                            intents.get(i).toShortString(sb, false, true, false, false);
13929                            pw.println(sb.toString());
13930                            Bundle bundle = intents.get(i).getExtras();
13931                            if (bundle != null) {
13932                                pw.print("      ");
13933                                pw.println(bundle.toString());
13934                            }
13935                        }
13936                    } else {
13937                        pw.println("");
13938                    }
13939                }
13940            }
13941        }
13942
13943        if (!onlyHistory && dumpAll) {
13944            pw.println();
13945            for (BroadcastQueue queue : mBroadcastQueues) {
13946                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13947                        + queue.mBroadcastsScheduled);
13948            }
13949            pw.println("  mHandler:");
13950            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13951            needSep = true;
13952            printedAnything = true;
13953        }
13954
13955        if (!printedAnything) {
13956            pw.println("  (nothing)");
13957        }
13958    }
13959
13960    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13961            int opti, boolean dumpAll, String dumpPackage) {
13962        boolean needSep;
13963        boolean printedAnything = false;
13964
13965        ItemMatcher matcher = new ItemMatcher();
13966        matcher.build(args, opti);
13967
13968        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13969
13970        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13971        printedAnything |= needSep;
13972
13973        if (mLaunchingProviders.size() > 0) {
13974            boolean printed = false;
13975            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13976                ContentProviderRecord r = mLaunchingProviders.get(i);
13977                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13978                    continue;
13979                }
13980                if (!printed) {
13981                    if (needSep) pw.println();
13982                    needSep = true;
13983                    pw.println("  Launching content providers:");
13984                    printed = true;
13985                    printedAnything = true;
13986                }
13987                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13988                        pw.println(r);
13989            }
13990        }
13991
13992        if (mGrantedUriPermissions.size() > 0) {
13993            boolean printed = false;
13994            int dumpUid = -2;
13995            if (dumpPackage != null) {
13996                try {
13997                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13998                } catch (NameNotFoundException e) {
13999                    dumpUid = -1;
14000                }
14001            }
14002            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14003                int uid = mGrantedUriPermissions.keyAt(i);
14004                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14005                    continue;
14006                }
14007                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14008                if (!printed) {
14009                    if (needSep) pw.println();
14010                    needSep = true;
14011                    pw.println("  Granted Uri Permissions:");
14012                    printed = true;
14013                    printedAnything = true;
14014                }
14015                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14016                for (UriPermission perm : perms.values()) {
14017                    pw.print("    "); pw.println(perm);
14018                    if (dumpAll) {
14019                        perm.dump(pw, "      ");
14020                    }
14021                }
14022            }
14023        }
14024
14025        if (!printedAnything) {
14026            pw.println("  (nothing)");
14027        }
14028    }
14029
14030    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14031            int opti, boolean dumpAll, String dumpPackage) {
14032        boolean printed = false;
14033
14034        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14035
14036        if (mIntentSenderRecords.size() > 0) {
14037            Iterator<WeakReference<PendingIntentRecord>> it
14038                    = mIntentSenderRecords.values().iterator();
14039            while (it.hasNext()) {
14040                WeakReference<PendingIntentRecord> ref = it.next();
14041                PendingIntentRecord rec = ref != null ? ref.get(): null;
14042                if (dumpPackage != null && (rec == null
14043                        || !dumpPackage.equals(rec.key.packageName))) {
14044                    continue;
14045                }
14046                printed = true;
14047                if (rec != null) {
14048                    pw.print("  * "); pw.println(rec);
14049                    if (dumpAll) {
14050                        rec.dump(pw, "    ");
14051                    }
14052                } else {
14053                    pw.print("  * "); pw.println(ref);
14054                }
14055            }
14056        }
14057
14058        if (!printed) {
14059            pw.println("  (nothing)");
14060        }
14061    }
14062
14063    private static final int dumpProcessList(PrintWriter pw,
14064            ActivityManagerService service, List list,
14065            String prefix, String normalLabel, String persistentLabel,
14066            String dumpPackage) {
14067        int numPers = 0;
14068        final int N = list.size()-1;
14069        for (int i=N; i>=0; i--) {
14070            ProcessRecord r = (ProcessRecord)list.get(i);
14071            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14072                continue;
14073            }
14074            pw.println(String.format("%s%s #%2d: %s",
14075                    prefix, (r.persistent ? persistentLabel : normalLabel),
14076                    i, r.toString()));
14077            if (r.persistent) {
14078                numPers++;
14079            }
14080        }
14081        return numPers;
14082    }
14083
14084    private static final boolean dumpProcessOomList(PrintWriter pw,
14085            ActivityManagerService service, List<ProcessRecord> origList,
14086            String prefix, String normalLabel, String persistentLabel,
14087            boolean inclDetails, String dumpPackage) {
14088
14089        ArrayList<Pair<ProcessRecord, Integer>> list
14090                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14091        for (int i=0; i<origList.size(); i++) {
14092            ProcessRecord r = origList.get(i);
14093            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14094                continue;
14095            }
14096            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14097        }
14098
14099        if (list.size() <= 0) {
14100            return false;
14101        }
14102
14103        Comparator<Pair<ProcessRecord, Integer>> comparator
14104                = new Comparator<Pair<ProcessRecord, Integer>>() {
14105            @Override
14106            public int compare(Pair<ProcessRecord, Integer> object1,
14107                    Pair<ProcessRecord, Integer> object2) {
14108                if (object1.first.setAdj != object2.first.setAdj) {
14109                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14110                }
14111                if (object1.second.intValue() != object2.second.intValue()) {
14112                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14113                }
14114                return 0;
14115            }
14116        };
14117
14118        Collections.sort(list, comparator);
14119
14120        final long curRealtime = SystemClock.elapsedRealtime();
14121        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14122        final long curUptime = SystemClock.uptimeMillis();
14123        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14124
14125        for (int i=list.size()-1; i>=0; i--) {
14126            ProcessRecord r = list.get(i).first;
14127            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14128            char schedGroup;
14129            switch (r.setSchedGroup) {
14130                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
14131                    schedGroup = 'B';
14132                    break;
14133                case Process.THREAD_GROUP_DEFAULT:
14134                    schedGroup = 'F';
14135                    break;
14136                default:
14137                    schedGroup = '?';
14138                    break;
14139            }
14140            char foreground;
14141            if (r.foregroundActivities) {
14142                foreground = 'A';
14143            } else if (r.foregroundServices) {
14144                foreground = 'S';
14145            } else {
14146                foreground = ' ';
14147            }
14148            String procState = ProcessList.makeProcStateString(r.curProcState);
14149            pw.print(prefix);
14150            pw.print(r.persistent ? persistentLabel : normalLabel);
14151            pw.print(" #");
14152            int num = (origList.size()-1)-list.get(i).second;
14153            if (num < 10) pw.print(' ');
14154            pw.print(num);
14155            pw.print(": ");
14156            pw.print(oomAdj);
14157            pw.print(' ');
14158            pw.print(schedGroup);
14159            pw.print('/');
14160            pw.print(foreground);
14161            pw.print('/');
14162            pw.print(procState);
14163            pw.print(" trm:");
14164            if (r.trimMemoryLevel < 10) pw.print(' ');
14165            pw.print(r.trimMemoryLevel);
14166            pw.print(' ');
14167            pw.print(r.toShortString());
14168            pw.print(" (");
14169            pw.print(r.adjType);
14170            pw.println(')');
14171            if (r.adjSource != null || r.adjTarget != null) {
14172                pw.print(prefix);
14173                pw.print("    ");
14174                if (r.adjTarget instanceof ComponentName) {
14175                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14176                } else if (r.adjTarget != null) {
14177                    pw.print(r.adjTarget.toString());
14178                } else {
14179                    pw.print("{null}");
14180                }
14181                pw.print("<=");
14182                if (r.adjSource instanceof ProcessRecord) {
14183                    pw.print("Proc{");
14184                    pw.print(((ProcessRecord)r.adjSource).toShortString());
14185                    pw.println("}");
14186                } else if (r.adjSource != null) {
14187                    pw.println(r.adjSource.toString());
14188                } else {
14189                    pw.println("{null}");
14190                }
14191            }
14192            if (inclDetails) {
14193                pw.print(prefix);
14194                pw.print("    ");
14195                pw.print("oom: max="); pw.print(r.maxAdj);
14196                pw.print(" curRaw="); pw.print(r.curRawAdj);
14197                pw.print(" setRaw="); pw.print(r.setRawAdj);
14198                pw.print(" cur="); pw.print(r.curAdj);
14199                pw.print(" set="); pw.println(r.setAdj);
14200                pw.print(prefix);
14201                pw.print("    ");
14202                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14203                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14204                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14205                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14206                pw.println();
14207                pw.print(prefix);
14208                pw.print("    ");
14209                pw.print("cached="); pw.print(r.cached);
14210                pw.print(" empty="); pw.print(r.empty);
14211                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14212
14213                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14214                    if (r.lastWakeTime != 0) {
14215                        long wtime;
14216                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14217                        synchronized (stats) {
14218                            wtime = stats.getProcessWakeTime(r.info.uid,
14219                                    r.pid, curRealtime);
14220                        }
14221                        long timeUsed = wtime - r.lastWakeTime;
14222                        pw.print(prefix);
14223                        pw.print("    ");
14224                        pw.print("keep awake over ");
14225                        TimeUtils.formatDuration(realtimeSince, pw);
14226                        pw.print(" used ");
14227                        TimeUtils.formatDuration(timeUsed, pw);
14228                        pw.print(" (");
14229                        pw.print((timeUsed*100)/realtimeSince);
14230                        pw.println("%)");
14231                    }
14232                    if (r.lastCpuTime != 0) {
14233                        long timeUsed = r.curCpuTime - r.lastCpuTime;
14234                        pw.print(prefix);
14235                        pw.print("    ");
14236                        pw.print("run cpu over ");
14237                        TimeUtils.formatDuration(uptimeSince, pw);
14238                        pw.print(" used ");
14239                        TimeUtils.formatDuration(timeUsed, pw);
14240                        pw.print(" (");
14241                        pw.print((timeUsed*100)/uptimeSince);
14242                        pw.println("%)");
14243                    }
14244                }
14245            }
14246        }
14247        return true;
14248    }
14249
14250    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14251            String[] args) {
14252        ArrayList<ProcessRecord> procs;
14253        synchronized (this) {
14254            if (args != null && args.length > start
14255                    && args[start].charAt(0) != '-') {
14256                procs = new ArrayList<ProcessRecord>();
14257                int pid = -1;
14258                try {
14259                    pid = Integer.parseInt(args[start]);
14260                } catch (NumberFormatException e) {
14261                }
14262                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14263                    ProcessRecord proc = mLruProcesses.get(i);
14264                    if (proc.pid == pid) {
14265                        procs.add(proc);
14266                    } else if (allPkgs && proc.pkgList != null
14267                            && proc.pkgList.containsKey(args[start])) {
14268                        procs.add(proc);
14269                    } else if (proc.processName.equals(args[start])) {
14270                        procs.add(proc);
14271                    }
14272                }
14273                if (procs.size() <= 0) {
14274                    return null;
14275                }
14276            } else {
14277                procs = new ArrayList<ProcessRecord>(mLruProcesses);
14278            }
14279        }
14280        return procs;
14281    }
14282
14283    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
14284            PrintWriter pw, String[] args) {
14285        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14286        if (procs == null) {
14287            pw.println("No process found for: " + args[0]);
14288            return;
14289        }
14290
14291        long uptime = SystemClock.uptimeMillis();
14292        long realtime = SystemClock.elapsedRealtime();
14293        pw.println("Applications Graphics Acceleration Info:");
14294        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14295
14296        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14297            ProcessRecord r = procs.get(i);
14298            if (r.thread != null) {
14299                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
14300                pw.flush();
14301                try {
14302                    TransferPipe tp = new TransferPipe();
14303                    try {
14304                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
14305                        tp.go(fd);
14306                    } finally {
14307                        tp.kill();
14308                    }
14309                } catch (IOException e) {
14310                    pw.println("Failure while dumping the app: " + r);
14311                    pw.flush();
14312                } catch (RemoteException e) {
14313                    pw.println("Got a RemoteException while dumping the app " + r);
14314                    pw.flush();
14315                }
14316            }
14317        }
14318    }
14319
14320    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
14321        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14322        if (procs == null) {
14323            pw.println("No process found for: " + args[0]);
14324            return;
14325        }
14326
14327        pw.println("Applications Database Info:");
14328
14329        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14330            ProcessRecord r = procs.get(i);
14331            if (r.thread != null) {
14332                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
14333                pw.flush();
14334                try {
14335                    TransferPipe tp = new TransferPipe();
14336                    try {
14337                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
14338                        tp.go(fd);
14339                    } finally {
14340                        tp.kill();
14341                    }
14342                } catch (IOException e) {
14343                    pw.println("Failure while dumping the app: " + r);
14344                    pw.flush();
14345                } catch (RemoteException e) {
14346                    pw.println("Got a RemoteException while dumping the app " + r);
14347                    pw.flush();
14348                }
14349            }
14350        }
14351    }
14352
14353    final static class MemItem {
14354        final boolean isProc;
14355        final String label;
14356        final String shortLabel;
14357        final long pss;
14358        final int id;
14359        final boolean hasActivities;
14360        ArrayList<MemItem> subitems;
14361
14362        public MemItem(String _label, String _shortLabel, long _pss, int _id,
14363                boolean _hasActivities) {
14364            isProc = true;
14365            label = _label;
14366            shortLabel = _shortLabel;
14367            pss = _pss;
14368            id = _id;
14369            hasActivities = _hasActivities;
14370        }
14371
14372        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
14373            isProc = false;
14374            label = _label;
14375            shortLabel = _shortLabel;
14376            pss = _pss;
14377            id = _id;
14378            hasActivities = false;
14379        }
14380    }
14381
14382    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
14383            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
14384        if (sort && !isCompact) {
14385            Collections.sort(items, new Comparator<MemItem>() {
14386                @Override
14387                public int compare(MemItem lhs, MemItem rhs) {
14388                    if (lhs.pss < rhs.pss) {
14389                        return 1;
14390                    } else if (lhs.pss > rhs.pss) {
14391                        return -1;
14392                    }
14393                    return 0;
14394                }
14395            });
14396        }
14397
14398        for (int i=0; i<items.size(); i++) {
14399            MemItem mi = items.get(i);
14400            if (!isCompact) {
14401                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
14402            } else if (mi.isProc) {
14403                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
14404                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
14405                pw.println(mi.hasActivities ? ",a" : ",e");
14406            } else {
14407                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
14408                pw.println(mi.pss);
14409            }
14410            if (mi.subitems != null) {
14411                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
14412                        true, isCompact);
14413            }
14414        }
14415    }
14416
14417    // These are in KB.
14418    static final long[] DUMP_MEM_BUCKETS = new long[] {
14419        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
14420        120*1024, 160*1024, 200*1024,
14421        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
14422        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
14423    };
14424
14425    static final void appendMemBucket(StringBuilder out, long memKB, String label,
14426            boolean stackLike) {
14427        int start = label.lastIndexOf('.');
14428        if (start >= 0) start++;
14429        else start = 0;
14430        int end = label.length();
14431        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
14432            if (DUMP_MEM_BUCKETS[i] >= memKB) {
14433                long bucket = DUMP_MEM_BUCKETS[i]/1024;
14434                out.append(bucket);
14435                out.append(stackLike ? "MB." : "MB ");
14436                out.append(label, start, end);
14437                return;
14438            }
14439        }
14440        out.append(memKB/1024);
14441        out.append(stackLike ? "MB." : "MB ");
14442        out.append(label, start, end);
14443    }
14444
14445    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
14446            ProcessList.NATIVE_ADJ,
14447            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
14448            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
14449            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
14450            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
14451            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
14452            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
14453    };
14454    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
14455            "Native",
14456            "System", "Persistent", "Persistent Service", "Foreground",
14457            "Visible", "Perceptible",
14458            "Heavy Weight", "Backup",
14459            "A Services", "Home",
14460            "Previous", "B Services", "Cached"
14461    };
14462    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
14463            "native",
14464            "sys", "pers", "persvc", "fore",
14465            "vis", "percept",
14466            "heavy", "backup",
14467            "servicea", "home",
14468            "prev", "serviceb", "cached"
14469    };
14470
14471    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
14472            long realtime, boolean isCheckinRequest, boolean isCompact) {
14473        if (isCheckinRequest || isCompact) {
14474            // short checkin version
14475            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
14476        } else {
14477            pw.println("Applications Memory Usage (kB):");
14478            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14479        }
14480    }
14481
14482    private static final int KSM_SHARED = 0;
14483    private static final int KSM_SHARING = 1;
14484    private static final int KSM_UNSHARED = 2;
14485    private static final int KSM_VOLATILE = 3;
14486
14487    private final long[] getKsmInfo() {
14488        long[] longOut = new long[4];
14489        final int[] SINGLE_LONG_FORMAT = new int[] {
14490            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14491        };
14492        long[] longTmp = new long[1];
14493        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14494                SINGLE_LONG_FORMAT, null, longTmp, null);
14495        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14496        longTmp[0] = 0;
14497        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14498                SINGLE_LONG_FORMAT, null, longTmp, null);
14499        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14500        longTmp[0] = 0;
14501        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14502                SINGLE_LONG_FORMAT, null, longTmp, null);
14503        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14504        longTmp[0] = 0;
14505        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14506                SINGLE_LONG_FORMAT, null, longTmp, null);
14507        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14508        return longOut;
14509    }
14510
14511    final void dumpApplicationMemoryUsage(FileDescriptor fd,
14512            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
14513        boolean dumpDetails = false;
14514        boolean dumpFullDetails = false;
14515        boolean dumpDalvik = false;
14516        boolean dumpSummaryOnly = false;
14517        boolean oomOnly = false;
14518        boolean isCompact = false;
14519        boolean localOnly = false;
14520        boolean packages = false;
14521
14522        int opti = 0;
14523        while (opti < args.length) {
14524            String opt = args[opti];
14525            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14526                break;
14527            }
14528            opti++;
14529            if ("-a".equals(opt)) {
14530                dumpDetails = true;
14531                dumpFullDetails = true;
14532                dumpDalvik = true;
14533            } else if ("-d".equals(opt)) {
14534                dumpDalvik = true;
14535            } else if ("-c".equals(opt)) {
14536                isCompact = true;
14537            } else if ("-s".equals(opt)) {
14538                dumpDetails = true;
14539                dumpSummaryOnly = true;
14540            } else if ("--oom".equals(opt)) {
14541                oomOnly = true;
14542            } else if ("--local".equals(opt)) {
14543                localOnly = true;
14544            } else if ("--package".equals(opt)) {
14545                packages = true;
14546            } else if ("-h".equals(opt)) {
14547                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
14548                pw.println("  -a: include all available information for each process.");
14549                pw.println("  -d: include dalvik details.");
14550                pw.println("  -c: dump in a compact machine-parseable representation.");
14551                pw.println("  -s: dump only summary of application memory usage.");
14552                pw.println("  --oom: only show processes organized by oom adj.");
14553                pw.println("  --local: only collect details locally, don't call process.");
14554                pw.println("  --package: interpret process arg as package, dumping all");
14555                pw.println("             processes that have loaded that package.");
14556                pw.println("If [process] is specified it can be the name or ");
14557                pw.println("pid of a specific process to dump.");
14558                return;
14559            } else {
14560                pw.println("Unknown argument: " + opt + "; use -h for help");
14561            }
14562        }
14563
14564        final boolean isCheckinRequest = scanArgs(args, "--checkin");
14565        long uptime = SystemClock.uptimeMillis();
14566        long realtime = SystemClock.elapsedRealtime();
14567        final long[] tmpLong = new long[1];
14568
14569        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
14570        if (procs == null) {
14571            // No Java processes.  Maybe they want to print a native process.
14572            if (args != null && args.length > opti
14573                    && args[opti].charAt(0) != '-') {
14574                ArrayList<ProcessCpuTracker.Stats> nativeProcs
14575                        = new ArrayList<ProcessCpuTracker.Stats>();
14576                updateCpuStatsNow();
14577                int findPid = -1;
14578                try {
14579                    findPid = Integer.parseInt(args[opti]);
14580                } catch (NumberFormatException e) {
14581                }
14582                synchronized (mProcessCpuTracker) {
14583                    final int N = mProcessCpuTracker.countStats();
14584                    for (int i=0; i<N; i++) {
14585                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14586                        if (st.pid == findPid || (st.baseName != null
14587                                && st.baseName.equals(args[opti]))) {
14588                            nativeProcs.add(st);
14589                        }
14590                    }
14591                }
14592                if (nativeProcs.size() > 0) {
14593                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14594                            isCompact);
14595                    Debug.MemoryInfo mi = null;
14596                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14597                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14598                        final int pid = r.pid;
14599                        if (!isCheckinRequest && dumpDetails) {
14600                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14601                        }
14602                        if (mi == null) {
14603                            mi = new Debug.MemoryInfo();
14604                        }
14605                        if (dumpDetails || (!brief && !oomOnly)) {
14606                            Debug.getMemoryInfo(pid, mi);
14607                        } else {
14608                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14609                            mi.dalvikPrivateDirty = (int)tmpLong[0];
14610                        }
14611                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14612                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14613                        if (isCheckinRequest) {
14614                            pw.println();
14615                        }
14616                    }
14617                    return;
14618                }
14619            }
14620            pw.println("No process found for: " + args[opti]);
14621            return;
14622        }
14623
14624        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14625            dumpDetails = true;
14626        }
14627
14628        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14629
14630        String[] innerArgs = new String[args.length-opti];
14631        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14632
14633        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14634        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14635        long nativePss = 0;
14636        long dalvikPss = 0;
14637        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
14638                EmptyArray.LONG;
14639        long otherPss = 0;
14640        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14641
14642        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14643        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14644                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14645
14646        long totalPss = 0;
14647        long cachedPss = 0;
14648
14649        Debug.MemoryInfo mi = null;
14650        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14651            final ProcessRecord r = procs.get(i);
14652            final IApplicationThread thread;
14653            final int pid;
14654            final int oomAdj;
14655            final boolean hasActivities;
14656            synchronized (this) {
14657                thread = r.thread;
14658                pid = r.pid;
14659                oomAdj = r.getSetAdjWithServices();
14660                hasActivities = r.activities.size() > 0;
14661            }
14662            if (thread != null) {
14663                if (!isCheckinRequest && dumpDetails) {
14664                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14665                }
14666                if (mi == null) {
14667                    mi = new Debug.MemoryInfo();
14668                }
14669                if (dumpDetails || (!brief && !oomOnly)) {
14670                    Debug.getMemoryInfo(pid, mi);
14671                } else {
14672                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14673                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14674                }
14675                if (dumpDetails) {
14676                    if (localOnly) {
14677                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14678                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
14679                        if (isCheckinRequest) {
14680                            pw.println();
14681                        }
14682                    } else {
14683                        try {
14684                            pw.flush();
14685                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14686                                    dumpDalvik, dumpSummaryOnly, innerArgs);
14687                        } catch (RemoteException e) {
14688                            if (!isCheckinRequest) {
14689                                pw.println("Got RemoteException!");
14690                                pw.flush();
14691                            }
14692                        }
14693                    }
14694                }
14695
14696                final long myTotalPss = mi.getTotalPss();
14697                final long myTotalUss = mi.getTotalUss();
14698
14699                synchronized (this) {
14700                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14701                        // Record this for posterity if the process has been stable.
14702                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14703                    }
14704                }
14705
14706                if (!isCheckinRequest && mi != null) {
14707                    totalPss += myTotalPss;
14708                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14709                            (hasActivities ? " / activities)" : ")"),
14710                            r.processName, myTotalPss, pid, hasActivities);
14711                    procMems.add(pssItem);
14712                    procMemsMap.put(pid, pssItem);
14713
14714                    nativePss += mi.nativePss;
14715                    dalvikPss += mi.dalvikPss;
14716                    for (int j=0; j<dalvikSubitemPss.length; j++) {
14717                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
14718                    }
14719                    otherPss += mi.otherPss;
14720                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14721                        long mem = mi.getOtherPss(j);
14722                        miscPss[j] += mem;
14723                        otherPss -= mem;
14724                    }
14725
14726                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14727                        cachedPss += myTotalPss;
14728                    }
14729
14730                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14731                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14732                                || oomIndex == (oomPss.length-1)) {
14733                            oomPss[oomIndex] += myTotalPss;
14734                            if (oomProcs[oomIndex] == null) {
14735                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14736                            }
14737                            oomProcs[oomIndex].add(pssItem);
14738                            break;
14739                        }
14740                    }
14741                }
14742            }
14743        }
14744
14745        long nativeProcTotalPss = 0;
14746
14747        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14748            // If we are showing aggregations, also look for native processes to
14749            // include so that our aggregations are more accurate.
14750            updateCpuStatsNow();
14751            mi = null;
14752            synchronized (mProcessCpuTracker) {
14753                final int N = mProcessCpuTracker.countStats();
14754                for (int i=0; i<N; i++) {
14755                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14756                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14757                        if (mi == null) {
14758                            mi = new Debug.MemoryInfo();
14759                        }
14760                        if (!brief && !oomOnly) {
14761                            Debug.getMemoryInfo(st.pid, mi);
14762                        } else {
14763                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14764                            mi.nativePrivateDirty = (int)tmpLong[0];
14765                        }
14766
14767                        final long myTotalPss = mi.getTotalPss();
14768                        totalPss += myTotalPss;
14769                        nativeProcTotalPss += myTotalPss;
14770
14771                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14772                                st.name, myTotalPss, st.pid, false);
14773                        procMems.add(pssItem);
14774
14775                        nativePss += mi.nativePss;
14776                        dalvikPss += mi.dalvikPss;
14777                        for (int j=0; j<dalvikSubitemPss.length; j++) {
14778                            dalvikSubitemPss[j] += mi.getOtherPss(
14779                                    Debug.MemoryInfo.NUM_OTHER_STATS + j);
14780                        }
14781                        otherPss += mi.otherPss;
14782                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14783                            long mem = mi.getOtherPss(j);
14784                            miscPss[j] += mem;
14785                            otherPss -= mem;
14786                        }
14787                        oomPss[0] += myTotalPss;
14788                        if (oomProcs[0] == null) {
14789                            oomProcs[0] = new ArrayList<MemItem>();
14790                        }
14791                        oomProcs[0].add(pssItem);
14792                    }
14793                }
14794            }
14795
14796            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14797
14798            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14799            final MemItem dalvikItem = new MemItem("Dalvik", "Dalvik", dalvikPss, -2);
14800            if (dalvikSubitemPss.length > 0) {
14801                dalvikItem.subitems = new ArrayList<MemItem>();
14802                for (int j=0; j<dalvikSubitemPss.length; j++) {
14803                    final String name = Debug.MemoryInfo.getOtherLabel(
14804                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
14805                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j], j));
14806                }
14807            }
14808            catMems.add(dalvikItem);
14809            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14810            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14811                String label = Debug.MemoryInfo.getOtherLabel(j);
14812                catMems.add(new MemItem(label, label, miscPss[j], j));
14813            }
14814
14815            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14816            for (int j=0; j<oomPss.length; j++) {
14817                if (oomPss[j] != 0) {
14818                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14819                            : DUMP_MEM_OOM_LABEL[j];
14820                    MemItem item = new MemItem(label, label, oomPss[j],
14821                            DUMP_MEM_OOM_ADJ[j]);
14822                    item.subitems = oomProcs[j];
14823                    oomMems.add(item);
14824                }
14825            }
14826
14827            if (!brief && !oomOnly && !isCompact) {
14828                pw.println();
14829                pw.println("Total PSS by process:");
14830                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14831                pw.println();
14832            }
14833            if (!isCompact) {
14834                pw.println("Total PSS by OOM adjustment:");
14835            }
14836            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14837            if (!brief && !oomOnly) {
14838                PrintWriter out = categoryPw != null ? categoryPw : pw;
14839                if (!isCompact) {
14840                    out.println();
14841                    out.println("Total PSS by category:");
14842                }
14843                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14844            }
14845            if (!isCompact) {
14846                pw.println();
14847            }
14848            MemInfoReader memInfo = new MemInfoReader();
14849            memInfo.readMemInfo();
14850            if (nativeProcTotalPss > 0) {
14851                synchronized (this) {
14852                    final long cachedKb = memInfo.getCachedSizeKb();
14853                    final long freeKb = memInfo.getFreeSizeKb();
14854                    final long zramKb = memInfo.getZramTotalSizeKb();
14855                    final long kernelKb = memInfo.getKernelUsedSizeKb();
14856                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
14857                            kernelKb*1024, nativeProcTotalPss*1024);
14858                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
14859                            nativeProcTotalPss);
14860                }
14861            }
14862            if (!brief) {
14863                if (!isCompact) {
14864                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14865                    pw.print(" kB (status ");
14866                    switch (mLastMemoryLevel) {
14867                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14868                            pw.println("normal)");
14869                            break;
14870                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14871                            pw.println("moderate)");
14872                            break;
14873                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14874                            pw.println("low)");
14875                            break;
14876                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14877                            pw.println("critical)");
14878                            break;
14879                        default:
14880                            pw.print(mLastMemoryLevel);
14881                            pw.println(")");
14882                            break;
14883                    }
14884                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14885                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14886                            pw.print(cachedPss); pw.print(" cached pss + ");
14887                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14888                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14889                } else {
14890                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14891                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14892                            + memInfo.getFreeSizeKb()); pw.print(",");
14893                    pw.println(totalPss - cachedPss);
14894                }
14895            }
14896            if (!isCompact) {
14897                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14898                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14899                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14900                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14901                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14902                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14903                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14904            }
14905            if (!brief) {
14906                if (memInfo.getZramTotalSizeKb() != 0) {
14907                    if (!isCompact) {
14908                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14909                                pw.print(" kB physical used for ");
14910                                pw.print(memInfo.getSwapTotalSizeKb()
14911                                        - memInfo.getSwapFreeSizeKb());
14912                                pw.print(" kB in swap (");
14913                                pw.print(memInfo.getSwapTotalSizeKb());
14914                                pw.println(" kB total swap)");
14915                    } else {
14916                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14917                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14918                                pw.println(memInfo.getSwapFreeSizeKb());
14919                    }
14920                }
14921                final long[] ksm = getKsmInfo();
14922                if (!isCompact) {
14923                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14924                            || ksm[KSM_VOLATILE] != 0) {
14925                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14926                                pw.print(" kB saved from shared ");
14927                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14928                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14929                                pw.print(" kB unshared; ");
14930                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14931                    }
14932                    pw.print("   Tuning: ");
14933                    pw.print(ActivityManager.staticGetMemoryClass());
14934                    pw.print(" (large ");
14935                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14936                    pw.print("), oom ");
14937                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14938                    pw.print(" kB");
14939                    pw.print(", restore limit ");
14940                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14941                    pw.print(" kB");
14942                    if (ActivityManager.isLowRamDeviceStatic()) {
14943                        pw.print(" (low-ram)");
14944                    }
14945                    if (ActivityManager.isHighEndGfx()) {
14946                        pw.print(" (high-end-gfx)");
14947                    }
14948                    pw.println();
14949                } else {
14950                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14951                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14952                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14953                    pw.print("tuning,");
14954                    pw.print(ActivityManager.staticGetMemoryClass());
14955                    pw.print(',');
14956                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14957                    pw.print(',');
14958                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14959                    if (ActivityManager.isLowRamDeviceStatic()) {
14960                        pw.print(",low-ram");
14961                    }
14962                    if (ActivityManager.isHighEndGfx()) {
14963                        pw.print(",high-end-gfx");
14964                    }
14965                    pw.println();
14966                }
14967            }
14968        }
14969    }
14970
14971    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14972            long memtrack, String name) {
14973        sb.append("  ");
14974        sb.append(ProcessList.makeOomAdjString(oomAdj));
14975        sb.append(' ');
14976        sb.append(ProcessList.makeProcStateString(procState));
14977        sb.append(' ');
14978        ProcessList.appendRamKb(sb, pss);
14979        sb.append(" kB: ");
14980        sb.append(name);
14981        if (memtrack > 0) {
14982            sb.append(" (");
14983            sb.append(memtrack);
14984            sb.append(" kB memtrack)");
14985        }
14986    }
14987
14988    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14989        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
14990        sb.append(" (pid ");
14991        sb.append(mi.pid);
14992        sb.append(") ");
14993        sb.append(mi.adjType);
14994        sb.append('\n');
14995        if (mi.adjReason != null) {
14996            sb.append("                      ");
14997            sb.append(mi.adjReason);
14998            sb.append('\n');
14999        }
15000    }
15001
15002    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15003        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15004        for (int i=0, N=memInfos.size(); i<N; i++) {
15005            ProcessMemInfo mi = memInfos.get(i);
15006            infoMap.put(mi.pid, mi);
15007        }
15008        updateCpuStatsNow();
15009        long[] memtrackTmp = new long[1];
15010        synchronized (mProcessCpuTracker) {
15011            final int N = mProcessCpuTracker.countStats();
15012            for (int i=0; i<N; i++) {
15013                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15014                if (st.vsize > 0) {
15015                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
15016                    if (pss > 0) {
15017                        if (infoMap.indexOfKey(st.pid) < 0) {
15018                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15019                                    ProcessList.NATIVE_ADJ, -1, "native", null);
15020                            mi.pss = pss;
15021                            mi.memtrack = memtrackTmp[0];
15022                            memInfos.add(mi);
15023                        }
15024                    }
15025                }
15026            }
15027        }
15028
15029        long totalPss = 0;
15030        long totalMemtrack = 0;
15031        for (int i=0, N=memInfos.size(); i<N; i++) {
15032            ProcessMemInfo mi = memInfos.get(i);
15033            if (mi.pss == 0) {
15034                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15035                mi.memtrack = memtrackTmp[0];
15036            }
15037            totalPss += mi.pss;
15038            totalMemtrack += mi.memtrack;
15039        }
15040        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15041            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15042                if (lhs.oomAdj != rhs.oomAdj) {
15043                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15044                }
15045                if (lhs.pss != rhs.pss) {
15046                    return lhs.pss < rhs.pss ? 1 : -1;
15047                }
15048                return 0;
15049            }
15050        });
15051
15052        StringBuilder tag = new StringBuilder(128);
15053        StringBuilder stack = new StringBuilder(128);
15054        tag.append("Low on memory -- ");
15055        appendMemBucket(tag, totalPss, "total", false);
15056        appendMemBucket(stack, totalPss, "total", true);
15057
15058        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15059        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15060        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15061
15062        boolean firstLine = true;
15063        int lastOomAdj = Integer.MIN_VALUE;
15064        long extraNativeRam = 0;
15065        long extraNativeMemtrack = 0;
15066        long cachedPss = 0;
15067        for (int i=0, N=memInfos.size(); i<N; i++) {
15068            ProcessMemInfo mi = memInfos.get(i);
15069
15070            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15071                cachedPss += mi.pss;
15072            }
15073
15074            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15075                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15076                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15077                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15078                if (lastOomAdj != mi.oomAdj) {
15079                    lastOomAdj = mi.oomAdj;
15080                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15081                        tag.append(" / ");
15082                    }
15083                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15084                        if (firstLine) {
15085                            stack.append(":");
15086                            firstLine = false;
15087                        }
15088                        stack.append("\n\t at ");
15089                    } else {
15090                        stack.append("$");
15091                    }
15092                } else {
15093                    tag.append(" ");
15094                    stack.append("$");
15095                }
15096                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15097                    appendMemBucket(tag, mi.pss, mi.name, false);
15098                }
15099                appendMemBucket(stack, mi.pss, mi.name, true);
15100                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15101                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15102                    stack.append("(");
15103                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15104                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15105                            stack.append(DUMP_MEM_OOM_LABEL[k]);
15106                            stack.append(":");
15107                            stack.append(DUMP_MEM_OOM_ADJ[k]);
15108                        }
15109                    }
15110                    stack.append(")");
15111                }
15112            }
15113
15114            appendMemInfo(fullNativeBuilder, mi);
15115            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15116                // The short form only has native processes that are >= 512K.
15117                if (mi.pss >= 512) {
15118                    appendMemInfo(shortNativeBuilder, mi);
15119                } else {
15120                    extraNativeRam += mi.pss;
15121                    extraNativeMemtrack += mi.memtrack;
15122                }
15123            } else {
15124                // Short form has all other details, but if we have collected RAM
15125                // from smaller native processes let's dump a summary of that.
15126                if (extraNativeRam > 0) {
15127                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15128                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15129                    shortNativeBuilder.append('\n');
15130                    extraNativeRam = 0;
15131                }
15132                appendMemInfo(fullJavaBuilder, mi);
15133            }
15134        }
15135
15136        fullJavaBuilder.append("           ");
15137        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15138        fullJavaBuilder.append(" kB: TOTAL");
15139        if (totalMemtrack > 0) {
15140            fullJavaBuilder.append(" (");
15141            fullJavaBuilder.append(totalMemtrack);
15142            fullJavaBuilder.append(" kB memtrack)");
15143        } else {
15144        }
15145        fullJavaBuilder.append("\n");
15146
15147        MemInfoReader memInfo = new MemInfoReader();
15148        memInfo.readMemInfo();
15149        final long[] infos = memInfo.getRawInfo();
15150
15151        StringBuilder memInfoBuilder = new StringBuilder(1024);
15152        Debug.getMemInfo(infos);
15153        memInfoBuilder.append("  MemInfo: ");
15154        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
15155        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
15156        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
15157        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
15158        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
15159        memInfoBuilder.append("           ");
15160        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
15161        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
15162        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
15163        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
15164        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15165            memInfoBuilder.append("  ZRAM: ");
15166            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
15167            memInfoBuilder.append(" kB RAM, ");
15168            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
15169            memInfoBuilder.append(" kB swap total, ");
15170            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
15171            memInfoBuilder.append(" kB swap free\n");
15172        }
15173        final long[] ksm = getKsmInfo();
15174        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15175                || ksm[KSM_VOLATILE] != 0) {
15176            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
15177            memInfoBuilder.append(" kB saved from shared ");
15178            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
15179            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
15180            memInfoBuilder.append(" kB unshared; ");
15181            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
15182        }
15183        memInfoBuilder.append("  Free RAM: ");
15184        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
15185                + memInfo.getFreeSizeKb());
15186        memInfoBuilder.append(" kB\n");
15187        memInfoBuilder.append("  Used RAM: ");
15188        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
15189        memInfoBuilder.append(" kB\n");
15190        memInfoBuilder.append("  Lost RAM: ");
15191        memInfoBuilder.append(memInfo.getTotalSizeKb()
15192                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15193                - memInfo.getKernelUsedSizeKb());
15194        memInfoBuilder.append(" kB\n");
15195        Slog.i(TAG, "Low on memory:");
15196        Slog.i(TAG, shortNativeBuilder.toString());
15197        Slog.i(TAG, fullJavaBuilder.toString());
15198        Slog.i(TAG, memInfoBuilder.toString());
15199
15200        StringBuilder dropBuilder = new StringBuilder(1024);
15201        /*
15202        StringWriter oomSw = new StringWriter();
15203        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
15204        StringWriter catSw = new StringWriter();
15205        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15206        String[] emptyArgs = new String[] { };
15207        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
15208        oomPw.flush();
15209        String oomString = oomSw.toString();
15210        */
15211        dropBuilder.append("Low on memory:");
15212        dropBuilder.append(stack);
15213        dropBuilder.append('\n');
15214        dropBuilder.append(fullNativeBuilder);
15215        dropBuilder.append(fullJavaBuilder);
15216        dropBuilder.append('\n');
15217        dropBuilder.append(memInfoBuilder);
15218        dropBuilder.append('\n');
15219        /*
15220        dropBuilder.append(oomString);
15221        dropBuilder.append('\n');
15222        */
15223        StringWriter catSw = new StringWriter();
15224        synchronized (ActivityManagerService.this) {
15225            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15226            String[] emptyArgs = new String[] { };
15227            catPw.println();
15228            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
15229            catPw.println();
15230            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
15231                    false, false, null);
15232            catPw.println();
15233            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
15234            catPw.flush();
15235        }
15236        dropBuilder.append(catSw.toString());
15237        addErrorToDropBox("lowmem", null, "system_server", null,
15238                null, tag.toString(), dropBuilder.toString(), null, null);
15239        //Slog.i(TAG, "Sent to dropbox:");
15240        //Slog.i(TAG, dropBuilder.toString());
15241        synchronized (ActivityManagerService.this) {
15242            long now = SystemClock.uptimeMillis();
15243            if (mLastMemUsageReportTime < now) {
15244                mLastMemUsageReportTime = now;
15245            }
15246        }
15247    }
15248
15249    /**
15250     * Searches array of arguments for the specified string
15251     * @param args array of argument strings
15252     * @param value value to search for
15253     * @return true if the value is contained in the array
15254     */
15255    private static boolean scanArgs(String[] args, String value) {
15256        if (args != null) {
15257            for (String arg : args) {
15258                if (value.equals(arg)) {
15259                    return true;
15260                }
15261            }
15262        }
15263        return false;
15264    }
15265
15266    private final boolean removeDyingProviderLocked(ProcessRecord proc,
15267            ContentProviderRecord cpr, boolean always) {
15268        final boolean inLaunching = mLaunchingProviders.contains(cpr);
15269
15270        if (!inLaunching || always) {
15271            synchronized (cpr) {
15272                cpr.launchingApp = null;
15273                cpr.notifyAll();
15274            }
15275            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
15276            String names[] = cpr.info.authority.split(";");
15277            for (int j = 0; j < names.length; j++) {
15278                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
15279            }
15280        }
15281
15282        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
15283            ContentProviderConnection conn = cpr.connections.get(i);
15284            if (conn.waiting) {
15285                // If this connection is waiting for the provider, then we don't
15286                // need to mess with its process unless we are always removing
15287                // or for some reason the provider is not currently launching.
15288                if (inLaunching && !always) {
15289                    continue;
15290                }
15291            }
15292            ProcessRecord capp = conn.client;
15293            conn.dead = true;
15294            if (conn.stableCount > 0) {
15295                if (!capp.persistent && capp.thread != null
15296                        && capp.pid != 0
15297                        && capp.pid != MY_PID) {
15298                    capp.kill("depends on provider "
15299                            + cpr.name.flattenToShortString()
15300                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
15301                }
15302            } else if (capp.thread != null && conn.provider.provider != null) {
15303                try {
15304                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
15305                } catch (RemoteException e) {
15306                }
15307                // In the protocol here, we don't expect the client to correctly
15308                // clean up this connection, we'll just remove it.
15309                cpr.connections.remove(i);
15310                if (conn.client.conProviders.remove(conn)) {
15311                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
15312                }
15313            }
15314        }
15315
15316        if (inLaunching && always) {
15317            mLaunchingProviders.remove(cpr);
15318        }
15319        return inLaunching;
15320    }
15321
15322    /**
15323     * Main code for cleaning up a process when it has gone away.  This is
15324     * called both as a result of the process dying, or directly when stopping
15325     * a process when running in single process mode.
15326     *
15327     * @return Returns true if the given process has been restarted, so the
15328     * app that was passed in must remain on the process lists.
15329     */
15330    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
15331            boolean restarting, boolean allowRestart, int index) {
15332        if (index >= 0) {
15333            removeLruProcessLocked(app);
15334            ProcessList.remove(app.pid);
15335        }
15336
15337        mProcessesToGc.remove(app);
15338        mPendingPssProcesses.remove(app);
15339
15340        // Dismiss any open dialogs.
15341        if (app.crashDialog != null && !app.forceCrashReport) {
15342            app.crashDialog.dismiss();
15343            app.crashDialog = null;
15344        }
15345        if (app.anrDialog != null) {
15346            app.anrDialog.dismiss();
15347            app.anrDialog = null;
15348        }
15349        if (app.waitDialog != null) {
15350            app.waitDialog.dismiss();
15351            app.waitDialog = null;
15352        }
15353
15354        app.crashing = false;
15355        app.notResponding = false;
15356
15357        app.resetPackageList(mProcessStats);
15358        app.unlinkDeathRecipient();
15359        app.makeInactive(mProcessStats);
15360        app.waitingToKill = null;
15361        app.forcingToForeground = null;
15362        updateProcessForegroundLocked(app, false, false);
15363        app.foregroundActivities = false;
15364        app.hasShownUi = false;
15365        app.treatLikeActivity = false;
15366        app.hasAboveClient = false;
15367        app.hasClientActivities = false;
15368
15369        mServices.killServicesLocked(app, allowRestart);
15370
15371        boolean restart = false;
15372
15373        // Remove published content providers.
15374        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
15375            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
15376            final boolean always = app.bad || !allowRestart;
15377            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
15378            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
15379                // We left the provider in the launching list, need to
15380                // restart it.
15381                restart = true;
15382            }
15383
15384            cpr.provider = null;
15385            cpr.proc = null;
15386        }
15387        app.pubProviders.clear();
15388
15389        // Take care of any launching providers waiting for this process.
15390        if (checkAppInLaunchingProvidersLocked(app, false)) {
15391            restart = true;
15392        }
15393
15394        // Unregister from connected content providers.
15395        if (!app.conProviders.isEmpty()) {
15396            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
15397                ContentProviderConnection conn = app.conProviders.get(i);
15398                conn.provider.connections.remove(conn);
15399                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
15400                        conn.provider.name);
15401            }
15402            app.conProviders.clear();
15403        }
15404
15405        // At this point there may be remaining entries in mLaunchingProviders
15406        // where we were the only one waiting, so they are no longer of use.
15407        // Look for these and clean up if found.
15408        // XXX Commented out for now.  Trying to figure out a way to reproduce
15409        // the actual situation to identify what is actually going on.
15410        if (false) {
15411            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15412                ContentProviderRecord cpr = mLaunchingProviders.get(i);
15413                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
15414                    synchronized (cpr) {
15415                        cpr.launchingApp = null;
15416                        cpr.notifyAll();
15417                    }
15418                }
15419            }
15420        }
15421
15422        skipCurrentReceiverLocked(app);
15423
15424        // Unregister any receivers.
15425        for (int i = app.receivers.size() - 1; i >= 0; i--) {
15426            removeReceiverLocked(app.receivers.valueAt(i));
15427        }
15428        app.receivers.clear();
15429
15430        // If the app is undergoing backup, tell the backup manager about it
15431        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
15432            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
15433                    + mBackupTarget.appInfo + " died during backup");
15434            try {
15435                IBackupManager bm = IBackupManager.Stub.asInterface(
15436                        ServiceManager.getService(Context.BACKUP_SERVICE));
15437                bm.agentDisconnected(app.info.packageName);
15438            } catch (RemoteException e) {
15439                // can't happen; backup manager is local
15440            }
15441        }
15442
15443        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
15444            ProcessChangeItem item = mPendingProcessChanges.get(i);
15445            if (item.pid == app.pid) {
15446                mPendingProcessChanges.remove(i);
15447                mAvailProcessChanges.add(item);
15448            }
15449        }
15450        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
15451
15452        // If the caller is restarting this app, then leave it in its
15453        // current lists and let the caller take care of it.
15454        if (restarting) {
15455            return false;
15456        }
15457
15458        if (!app.persistent || app.isolated) {
15459            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
15460                    "Removing non-persistent process during cleanup: " + app);
15461            removeProcessNameLocked(app.processName, app.uid);
15462            if (mHeavyWeightProcess == app) {
15463                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
15464                        mHeavyWeightProcess.userId, 0));
15465                mHeavyWeightProcess = null;
15466            }
15467        } else if (!app.removed) {
15468            // This app is persistent, so we need to keep its record around.
15469            // If it is not already on the pending app list, add it there
15470            // and start a new process for it.
15471            if (mPersistentStartingProcesses.indexOf(app) < 0) {
15472                mPersistentStartingProcesses.add(app);
15473                restart = true;
15474            }
15475        }
15476        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
15477                TAG_CLEANUP, "Clean-up removing on hold: " + app);
15478        mProcessesOnHold.remove(app);
15479
15480        if (app == mHomeProcess) {
15481            mHomeProcess = null;
15482        }
15483        if (app == mPreviousProcess) {
15484            mPreviousProcess = null;
15485        }
15486
15487        if (restart && !app.isolated) {
15488            // We have components that still need to be running in the
15489            // process, so re-launch it.
15490            if (index < 0) {
15491                ProcessList.remove(app.pid);
15492            }
15493            addProcessNameLocked(app);
15494            startProcessLocked(app, "restart", app.processName);
15495            return true;
15496        } else if (app.pid > 0 && app.pid != MY_PID) {
15497            // Goodbye!
15498            boolean removed;
15499            synchronized (mPidsSelfLocked) {
15500                mPidsSelfLocked.remove(app.pid);
15501                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
15502            }
15503            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
15504            if (app.isolated) {
15505                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
15506            }
15507            app.setPid(0);
15508        }
15509        return false;
15510    }
15511
15512    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
15513        // Look through the content providers we are waiting to have launched,
15514        // and if any run in this process then either schedule a restart of
15515        // the process or kill the client waiting for it if this process has
15516        // gone bad.
15517        boolean restart = false;
15518        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15519            ContentProviderRecord cpr = mLaunchingProviders.get(i);
15520            if (cpr.launchingApp == app) {
15521                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
15522                    restart = true;
15523                } else {
15524                    removeDyingProviderLocked(app, cpr, true);
15525                }
15526            }
15527        }
15528        return restart;
15529    }
15530
15531    // =========================================================
15532    // SERVICES
15533    // =========================================================
15534
15535    @Override
15536    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
15537            int flags) {
15538        enforceNotIsolatedCaller("getServices");
15539        synchronized (this) {
15540            return mServices.getRunningServiceInfoLocked(maxNum, flags);
15541        }
15542    }
15543
15544    @Override
15545    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
15546        enforceNotIsolatedCaller("getRunningServiceControlPanel");
15547        synchronized (this) {
15548            return mServices.getRunningServiceControlPanelLocked(name);
15549        }
15550    }
15551
15552    @Override
15553    public ComponentName startService(IApplicationThread caller, Intent service,
15554            String resolvedType, int userId) throws TransactionTooLargeException {
15555        enforceNotIsolatedCaller("startService");
15556        // Refuse possible leaked file descriptors
15557        if (service != null && service.hasFileDescriptors() == true) {
15558            throw new IllegalArgumentException("File descriptors passed in Intent");
15559        }
15560
15561        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15562                "startService: " + service + " type=" + resolvedType);
15563        synchronized(this) {
15564            final int callingPid = Binder.getCallingPid();
15565            final int callingUid = Binder.getCallingUid();
15566            final long origId = Binder.clearCallingIdentity();
15567            ComponentName res = mServices.startServiceLocked(caller, service,
15568                    resolvedType, callingPid, callingUid, userId);
15569            Binder.restoreCallingIdentity(origId);
15570            return res;
15571        }
15572    }
15573
15574    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType, int userId)
15575            throws TransactionTooLargeException {
15576        synchronized(this) {
15577            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15578                    "startServiceInPackage: " + service + " type=" + resolvedType);
15579            final long origId = Binder.clearCallingIdentity();
15580            ComponentName res = mServices.startServiceLocked(null, service,
15581                    resolvedType, -1, uid, userId);
15582            Binder.restoreCallingIdentity(origId);
15583            return res;
15584        }
15585    }
15586
15587    @Override
15588    public int stopService(IApplicationThread caller, Intent service,
15589            String resolvedType, int userId) {
15590        enforceNotIsolatedCaller("stopService");
15591        // Refuse possible leaked file descriptors
15592        if (service != null && service.hasFileDescriptors() == true) {
15593            throw new IllegalArgumentException("File descriptors passed in Intent");
15594        }
15595
15596        synchronized(this) {
15597            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
15598        }
15599    }
15600
15601    @Override
15602    public IBinder peekService(Intent service, String resolvedType) {
15603        enforceNotIsolatedCaller("peekService");
15604        // Refuse possible leaked file descriptors
15605        if (service != null && service.hasFileDescriptors() == true) {
15606            throw new IllegalArgumentException("File descriptors passed in Intent");
15607        }
15608        synchronized(this) {
15609            return mServices.peekServiceLocked(service, resolvedType);
15610        }
15611    }
15612
15613    @Override
15614    public boolean stopServiceToken(ComponentName className, IBinder token,
15615            int startId) {
15616        synchronized(this) {
15617            return mServices.stopServiceTokenLocked(className, token, startId);
15618        }
15619    }
15620
15621    @Override
15622    public void setServiceForeground(ComponentName className, IBinder token,
15623            int id, Notification notification, boolean removeNotification) {
15624        synchronized(this) {
15625            mServices.setServiceForegroundLocked(className, token, id, notification,
15626                    removeNotification);
15627        }
15628    }
15629
15630    @Override
15631    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15632            boolean requireFull, String name, String callerPackage) {
15633        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15634                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15635    }
15636
15637    int unsafeConvertIncomingUser(int userId) {
15638        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15639                ? mCurrentUserId : userId;
15640    }
15641
15642    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15643            int allowMode, String name, String callerPackage) {
15644        final int callingUserId = UserHandle.getUserId(callingUid);
15645        if (callingUserId == userId) {
15646            return userId;
15647        }
15648
15649        // Note that we may be accessing mCurrentUserId outside of a lock...
15650        // shouldn't be a big deal, if this is being called outside
15651        // of a locked context there is intrinsically a race with
15652        // the value the caller will receive and someone else changing it.
15653        // We assume that USER_CURRENT_OR_SELF will use the current user; later
15654        // we will switch to the calling user if access to the current user fails.
15655        int targetUserId = unsafeConvertIncomingUser(userId);
15656
15657        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15658            final boolean allow;
15659            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15660                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15661                // If the caller has this permission, they always pass go.  And collect $200.
15662                allow = true;
15663            } else if (allowMode == ALLOW_FULL_ONLY) {
15664                // We require full access, sucks to be you.
15665                allow = false;
15666            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15667                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15668                // If the caller does not have either permission, they are always doomed.
15669                allow = false;
15670            } else if (allowMode == ALLOW_NON_FULL) {
15671                // We are blanket allowing non-full access, you lucky caller!
15672                allow = true;
15673            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15674                // We may or may not allow this depending on whether the two users are
15675                // in the same profile.
15676                synchronized (mUserProfileGroupIdsSelfLocked) {
15677                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15678                            UserInfo.NO_PROFILE_GROUP_ID);
15679                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15680                            UserInfo.NO_PROFILE_GROUP_ID);
15681                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15682                            && callingProfile == targetProfile;
15683                }
15684            } else {
15685                throw new IllegalArgumentException("Unknown mode: " + allowMode);
15686            }
15687            if (!allow) {
15688                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15689                    // In this case, they would like to just execute as their
15690                    // owner user instead of failing.
15691                    targetUserId = callingUserId;
15692                } else {
15693                    StringBuilder builder = new StringBuilder(128);
15694                    builder.append("Permission Denial: ");
15695                    builder.append(name);
15696                    if (callerPackage != null) {
15697                        builder.append(" from ");
15698                        builder.append(callerPackage);
15699                    }
15700                    builder.append(" asks to run as user ");
15701                    builder.append(userId);
15702                    builder.append(" but is calling from user ");
15703                    builder.append(UserHandle.getUserId(callingUid));
15704                    builder.append("; this requires ");
15705                    builder.append(INTERACT_ACROSS_USERS_FULL);
15706                    if (allowMode != ALLOW_FULL_ONLY) {
15707                        builder.append(" or ");
15708                        builder.append(INTERACT_ACROSS_USERS);
15709                    }
15710                    String msg = builder.toString();
15711                    Slog.w(TAG, msg);
15712                    throw new SecurityException(msg);
15713                }
15714            }
15715        }
15716        if (!allowAll && targetUserId < 0) {
15717            throw new IllegalArgumentException(
15718                    "Call does not support special user #" + targetUserId);
15719        }
15720        // Check shell permission
15721        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15722            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15723                    targetUserId)) {
15724                throw new SecurityException("Shell does not have permission to access user "
15725                        + targetUserId + "\n " + Debug.getCallers(3));
15726            }
15727        }
15728        return targetUserId;
15729    }
15730
15731    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15732            String className, int flags) {
15733        boolean result = false;
15734        // For apps that don't have pre-defined UIDs, check for permission
15735        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15736            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15737                if (ActivityManager.checkUidPermission(
15738                        INTERACT_ACROSS_USERS,
15739                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15740                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15741                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15742                            + " requests FLAG_SINGLE_USER, but app does not hold "
15743                            + INTERACT_ACROSS_USERS;
15744                    Slog.w(TAG, msg);
15745                    throw new SecurityException(msg);
15746                }
15747                // Permission passed
15748                result = true;
15749            }
15750        } else if ("system".equals(componentProcessName)) {
15751            result = true;
15752        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15753            // Phone app and persistent apps are allowed to export singleuser providers.
15754            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15755                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15756        }
15757        if (DEBUG_MU) Slog.v(TAG_MU,
15758                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
15759                + Integer.toHexString(flags) + ") = " + result);
15760        return result;
15761    }
15762
15763    /**
15764     * Checks to see if the caller is in the same app as the singleton
15765     * component, or the component is in a special app. It allows special apps
15766     * to export singleton components but prevents exporting singleton
15767     * components for regular apps.
15768     */
15769    boolean isValidSingletonCall(int callingUid, int componentUid) {
15770        int componentAppId = UserHandle.getAppId(componentUid);
15771        return UserHandle.isSameApp(callingUid, componentUid)
15772                || componentAppId == Process.SYSTEM_UID
15773                || componentAppId == Process.PHONE_UID
15774                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15775                        == PackageManager.PERMISSION_GRANTED;
15776    }
15777
15778    public int bindService(IApplicationThread caller, IBinder token, Intent service,
15779            String resolvedType, IServiceConnection connection, int flags, int userId)
15780            throws TransactionTooLargeException {
15781        enforceNotIsolatedCaller("bindService");
15782
15783        // Refuse possible leaked file descriptors
15784        if (service != null && service.hasFileDescriptors() == true) {
15785            throw new IllegalArgumentException("File descriptors passed in Intent");
15786        }
15787
15788        synchronized(this) {
15789            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15790                    connection, flags, userId);
15791        }
15792    }
15793
15794    public boolean unbindService(IServiceConnection connection) {
15795        synchronized (this) {
15796            return mServices.unbindServiceLocked(connection);
15797        }
15798    }
15799
15800    public void publishService(IBinder token, Intent intent, IBinder service) {
15801        // Refuse possible leaked file descriptors
15802        if (intent != null && intent.hasFileDescriptors() == true) {
15803            throw new IllegalArgumentException("File descriptors passed in Intent");
15804        }
15805
15806        synchronized(this) {
15807            if (!(token instanceof ServiceRecord)) {
15808                throw new IllegalArgumentException("Invalid service token");
15809            }
15810            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15811        }
15812    }
15813
15814    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15815        // Refuse possible leaked file descriptors
15816        if (intent != null && intent.hasFileDescriptors() == true) {
15817            throw new IllegalArgumentException("File descriptors passed in Intent");
15818        }
15819
15820        synchronized(this) {
15821            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15822        }
15823    }
15824
15825    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15826        synchronized(this) {
15827            if (!(token instanceof ServiceRecord)) {
15828                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
15829                throw new IllegalArgumentException("Invalid service token");
15830            }
15831            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15832        }
15833    }
15834
15835    // =========================================================
15836    // BACKUP AND RESTORE
15837    // =========================================================
15838
15839    // Cause the target app to be launched if necessary and its backup agent
15840    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15841    // activity manager to announce its creation.
15842    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15843        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
15844                "bindBackupAgent: app=" + app + " mode=" + backupMode);
15845        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15846
15847        synchronized(this) {
15848            // !!! TODO: currently no check here that we're already bound
15849            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15850            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15851            synchronized (stats) {
15852                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15853            }
15854
15855            // Backup agent is now in use, its package can't be stopped.
15856            try {
15857                AppGlobals.getPackageManager().setPackageStoppedState(
15858                        app.packageName, false, UserHandle.getUserId(app.uid));
15859            } catch (RemoteException e) {
15860            } catch (IllegalArgumentException e) {
15861                Slog.w(TAG, "Failed trying to unstop package "
15862                        + app.packageName + ": " + e);
15863            }
15864
15865            BackupRecord r = new BackupRecord(ss, app, backupMode);
15866            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15867                    ? new ComponentName(app.packageName, app.backupAgentName)
15868                    : new ComponentName("android", "FullBackupAgent");
15869            // startProcessLocked() returns existing proc's record if it's already running
15870            ProcessRecord proc = startProcessLocked(app.processName, app,
15871                    false, 0, "backup", hostingName, false, false, false);
15872            if (proc == null) {
15873                Slog.e(TAG, "Unable to start backup agent process " + r);
15874                return false;
15875            }
15876
15877            r.app = proc;
15878            mBackupTarget = r;
15879            mBackupAppName = app.packageName;
15880
15881            // Try not to kill the process during backup
15882            updateOomAdjLocked(proc);
15883
15884            // If the process is already attached, schedule the creation of the backup agent now.
15885            // If it is not yet live, this will be done when it attaches to the framework.
15886            if (proc.thread != null) {
15887                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
15888                try {
15889                    proc.thread.scheduleCreateBackupAgent(app,
15890                            compatibilityInfoForPackageLocked(app), backupMode);
15891                } catch (RemoteException e) {
15892                    // Will time out on the backup manager side
15893                }
15894            } else {
15895                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
15896            }
15897            // Invariants: at this point, the target app process exists and the application
15898            // is either already running or in the process of coming up.  mBackupTarget and
15899            // mBackupAppName describe the app, so that when it binds back to the AM we
15900            // know that it's scheduled for a backup-agent operation.
15901        }
15902
15903        return true;
15904    }
15905
15906    @Override
15907    public void clearPendingBackup() {
15908        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
15909        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15910
15911        synchronized (this) {
15912            mBackupTarget = null;
15913            mBackupAppName = null;
15914        }
15915    }
15916
15917    // A backup agent has just come up
15918    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15919        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
15920                + " = " + agent);
15921
15922        synchronized(this) {
15923            if (!agentPackageName.equals(mBackupAppName)) {
15924                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15925                return;
15926            }
15927        }
15928
15929        long oldIdent = Binder.clearCallingIdentity();
15930        try {
15931            IBackupManager bm = IBackupManager.Stub.asInterface(
15932                    ServiceManager.getService(Context.BACKUP_SERVICE));
15933            bm.agentConnected(agentPackageName, agent);
15934        } catch (RemoteException e) {
15935            // can't happen; the backup manager service is local
15936        } catch (Exception e) {
15937            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15938            e.printStackTrace();
15939        } finally {
15940            Binder.restoreCallingIdentity(oldIdent);
15941        }
15942    }
15943
15944    // done with this agent
15945    public void unbindBackupAgent(ApplicationInfo appInfo) {
15946        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
15947        if (appInfo == null) {
15948            Slog.w(TAG, "unbind backup agent for null app");
15949            return;
15950        }
15951
15952        synchronized(this) {
15953            try {
15954                if (mBackupAppName == null) {
15955                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15956                    return;
15957                }
15958
15959                if (!mBackupAppName.equals(appInfo.packageName)) {
15960                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15961                    return;
15962                }
15963
15964                // Not backing this app up any more; reset its OOM adjustment
15965                final ProcessRecord proc = mBackupTarget.app;
15966                updateOomAdjLocked(proc);
15967
15968                // If the app crashed during backup, 'thread' will be null here
15969                if (proc.thread != null) {
15970                    try {
15971                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15972                                compatibilityInfoForPackageLocked(appInfo));
15973                    } catch (Exception e) {
15974                        Slog.e(TAG, "Exception when unbinding backup agent:");
15975                        e.printStackTrace();
15976                    }
15977                }
15978            } finally {
15979                mBackupTarget = null;
15980                mBackupAppName = null;
15981            }
15982        }
15983    }
15984    // =========================================================
15985    // BROADCASTS
15986    // =========================================================
15987
15988    boolean isPendingBroadcastProcessLocked(int pid) {
15989        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15990                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15991    }
15992
15993    void skipPendingBroadcastLocked(int pid) {
15994            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15995            for (BroadcastQueue queue : mBroadcastQueues) {
15996                queue.skipPendingBroadcastLocked(pid);
15997            }
15998    }
15999
16000    // The app just attached; send any pending broadcasts that it should receive
16001    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16002        boolean didSomething = false;
16003        for (BroadcastQueue queue : mBroadcastQueues) {
16004            didSomething |= queue.sendPendingBroadcastsLocked(app);
16005        }
16006        return didSomething;
16007    }
16008
16009    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16010            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16011        enforceNotIsolatedCaller("registerReceiver");
16012        ArrayList<Intent> stickyIntents = null;
16013        ProcessRecord callerApp = null;
16014        int callingUid;
16015        int callingPid;
16016        synchronized(this) {
16017            if (caller != null) {
16018                callerApp = getRecordForAppLocked(caller);
16019                if (callerApp == null) {
16020                    throw new SecurityException(
16021                            "Unable to find app for caller " + caller
16022                            + " (pid=" + Binder.getCallingPid()
16023                            + ") when registering receiver " + receiver);
16024                }
16025                if (callerApp.info.uid != Process.SYSTEM_UID &&
16026                        !callerApp.pkgList.containsKey(callerPackage) &&
16027                        !"android".equals(callerPackage)) {
16028                    throw new SecurityException("Given caller package " + callerPackage
16029                            + " is not running in process " + callerApp);
16030                }
16031                callingUid = callerApp.info.uid;
16032                callingPid = callerApp.pid;
16033            } else {
16034                callerPackage = null;
16035                callingUid = Binder.getCallingUid();
16036                callingPid = Binder.getCallingPid();
16037            }
16038
16039            userId = handleIncomingUser(callingPid, callingUid, userId,
16040                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16041
16042            Iterator<String> actions = filter.actionsIterator();
16043            if (actions == null) {
16044                ArrayList<String> noAction = new ArrayList<String>(1);
16045                noAction.add(null);
16046                actions = noAction.iterator();
16047            }
16048
16049            // Collect stickies of users
16050            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16051            while (actions.hasNext()) {
16052                String action = actions.next();
16053                for (int id : userIds) {
16054                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16055                    if (stickies != null) {
16056                        ArrayList<Intent> intents = stickies.get(action);
16057                        if (intents != null) {
16058                            if (stickyIntents == null) {
16059                                stickyIntents = new ArrayList<Intent>();
16060                            }
16061                            stickyIntents.addAll(intents);
16062                        }
16063                    }
16064                }
16065            }
16066        }
16067
16068        ArrayList<Intent> allSticky = null;
16069        if (stickyIntents != null) {
16070            final ContentResolver resolver = mContext.getContentResolver();
16071            // Look for any matching sticky broadcasts...
16072            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16073                Intent intent = stickyIntents.get(i);
16074                // If intent has scheme "content", it will need to acccess
16075                // provider that needs to lock mProviderMap in ActivityThread
16076                // and also it may need to wait application response, so we
16077                // cannot lock ActivityManagerService here.
16078                if (filter.match(resolver, intent, true, TAG) >= 0) {
16079                    if (allSticky == null) {
16080                        allSticky = new ArrayList<Intent>();
16081                    }
16082                    allSticky.add(intent);
16083                }
16084            }
16085        }
16086
16087        // The first sticky in the list is returned directly back to the client.
16088        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16089        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16090        if (receiver == null) {
16091            return sticky;
16092        }
16093
16094        synchronized (this) {
16095            if (callerApp != null && (callerApp.thread == null
16096                    || callerApp.thread.asBinder() != caller.asBinder())) {
16097                // Original caller already died
16098                return null;
16099            }
16100            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16101            if (rl == null) {
16102                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16103                        userId, receiver);
16104                if (rl.app != null) {
16105                    rl.app.receivers.add(rl);
16106                } else {
16107                    try {
16108                        receiver.asBinder().linkToDeath(rl, 0);
16109                    } catch (RemoteException e) {
16110                        return sticky;
16111                    }
16112                    rl.linkedToDeath = true;
16113                }
16114                mRegisteredReceivers.put(receiver.asBinder(), rl);
16115            } else if (rl.uid != callingUid) {
16116                throw new IllegalArgumentException(
16117                        "Receiver requested to register for uid " + callingUid
16118                        + " was previously registered for uid " + rl.uid);
16119            } else if (rl.pid != callingPid) {
16120                throw new IllegalArgumentException(
16121                        "Receiver requested to register for pid " + callingPid
16122                        + " was previously registered for pid " + rl.pid);
16123            } else if (rl.userId != userId) {
16124                throw new IllegalArgumentException(
16125                        "Receiver requested to register for user " + userId
16126                        + " was previously registered for user " + rl.userId);
16127            }
16128            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16129                    permission, callingUid, userId);
16130            rl.add(bf);
16131            if (!bf.debugCheck()) {
16132                Slog.w(TAG, "==> For Dynamic broadcast");
16133            }
16134            mReceiverResolver.addFilter(bf);
16135
16136            // Enqueue broadcasts for all existing stickies that match
16137            // this filter.
16138            if (allSticky != null) {
16139                ArrayList receivers = new ArrayList();
16140                receivers.add(bf);
16141
16142                final int stickyCount = allSticky.size();
16143                for (int i = 0; i < stickyCount; i++) {
16144                    Intent intent = allSticky.get(i);
16145                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16146                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16147                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16148                            null, 0, null, null, false, true, true, -1);
16149                    queue.enqueueParallelBroadcastLocked(r);
16150                    queue.scheduleBroadcastsLocked();
16151                }
16152            }
16153
16154            return sticky;
16155        }
16156    }
16157
16158    public void unregisterReceiver(IIntentReceiver receiver) {
16159        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16160
16161        final long origId = Binder.clearCallingIdentity();
16162        try {
16163            boolean doTrim = false;
16164
16165            synchronized(this) {
16166                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16167                if (rl != null) {
16168                    final BroadcastRecord r = rl.curBroadcast;
16169                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16170                        final boolean doNext = r.queue.finishReceiverLocked(
16171                                r, r.resultCode, r.resultData, r.resultExtras,
16172                                r.resultAbort, false);
16173                        if (doNext) {
16174                            doTrim = true;
16175                            r.queue.processNextBroadcast(false);
16176                        }
16177                    }
16178
16179                    if (rl.app != null) {
16180                        rl.app.receivers.remove(rl);
16181                    }
16182                    removeReceiverLocked(rl);
16183                    if (rl.linkedToDeath) {
16184                        rl.linkedToDeath = false;
16185                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
16186                    }
16187                }
16188            }
16189
16190            // If we actually concluded any broadcasts, we might now be able
16191            // to trim the recipients' apps from our working set
16192            if (doTrim) {
16193                trimApplications();
16194                return;
16195            }
16196
16197        } finally {
16198            Binder.restoreCallingIdentity(origId);
16199        }
16200    }
16201
16202    void removeReceiverLocked(ReceiverList rl) {
16203        mRegisteredReceivers.remove(rl.receiver.asBinder());
16204        for (int i = rl.size() - 1; i >= 0; i--) {
16205            mReceiverResolver.removeFilter(rl.get(i));
16206        }
16207    }
16208
16209    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16210        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16211            ProcessRecord r = mLruProcesses.get(i);
16212            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16213                try {
16214                    r.thread.dispatchPackageBroadcast(cmd, packages);
16215                } catch (RemoteException ex) {
16216                }
16217            }
16218        }
16219    }
16220
16221    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16222            int callingUid, int[] users) {
16223        List<ResolveInfo> receivers = null;
16224        try {
16225            HashSet<ComponentName> singleUserReceivers = null;
16226            boolean scannedFirstReceivers = false;
16227            for (int user : users) {
16228                // Skip users that have Shell restrictions
16229                if (callingUid == Process.SHELL_UID
16230                        && getUserManagerLocked().hasUserRestriction(
16231                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
16232                    continue;
16233                }
16234                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16235                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
16236                if (user != UserHandle.USER_OWNER && newReceivers != null) {
16237                    // If this is not the primary user, we need to check for
16238                    // any receivers that should be filtered out.
16239                    for (int i=0; i<newReceivers.size(); i++) {
16240                        ResolveInfo ri = newReceivers.get(i);
16241                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
16242                            newReceivers.remove(i);
16243                            i--;
16244                        }
16245                    }
16246                }
16247                if (newReceivers != null && newReceivers.size() == 0) {
16248                    newReceivers = null;
16249                }
16250                if (receivers == null) {
16251                    receivers = newReceivers;
16252                } else if (newReceivers != null) {
16253                    // We need to concatenate the additional receivers
16254                    // found with what we have do far.  This would be easy,
16255                    // but we also need to de-dup any receivers that are
16256                    // singleUser.
16257                    if (!scannedFirstReceivers) {
16258                        // Collect any single user receivers we had already retrieved.
16259                        scannedFirstReceivers = true;
16260                        for (int i=0; i<receivers.size(); i++) {
16261                            ResolveInfo ri = receivers.get(i);
16262                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16263                                ComponentName cn = new ComponentName(
16264                                        ri.activityInfo.packageName, ri.activityInfo.name);
16265                                if (singleUserReceivers == null) {
16266                                    singleUserReceivers = new HashSet<ComponentName>();
16267                                }
16268                                singleUserReceivers.add(cn);
16269                            }
16270                        }
16271                    }
16272                    // Add the new results to the existing results, tracking
16273                    // and de-dupping single user receivers.
16274                    for (int i=0; i<newReceivers.size(); i++) {
16275                        ResolveInfo ri = newReceivers.get(i);
16276                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16277                            ComponentName cn = new ComponentName(
16278                                    ri.activityInfo.packageName, ri.activityInfo.name);
16279                            if (singleUserReceivers == null) {
16280                                singleUserReceivers = new HashSet<ComponentName>();
16281                            }
16282                            if (!singleUserReceivers.contains(cn)) {
16283                                singleUserReceivers.add(cn);
16284                                receivers.add(ri);
16285                            }
16286                        } else {
16287                            receivers.add(ri);
16288                        }
16289                    }
16290                }
16291            }
16292        } catch (RemoteException ex) {
16293            // pm is in same process, this will never happen.
16294        }
16295        return receivers;
16296    }
16297
16298    private final int broadcastIntentLocked(ProcessRecord callerApp,
16299            String callerPackage, Intent intent, String resolvedType,
16300            IIntentReceiver resultTo, int resultCode, String resultData,
16301            Bundle resultExtras, String requiredPermission, int appOp, Bundle options,
16302            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
16303        intent = new Intent(intent);
16304
16305        // By default broadcasts do not go to stopped apps.
16306        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
16307
16308        // If we have not finished booting, don't allow this to launch new processes.
16309        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
16310            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16311        }
16312
16313        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
16314                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
16315                + " ordered=" + ordered + " userid=" + userId);
16316        if ((resultTo != null) && !ordered) {
16317            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
16318        }
16319
16320        userId = handleIncomingUser(callingPid, callingUid, userId,
16321                true, ALLOW_NON_FULL, "broadcast", callerPackage);
16322
16323        // Make sure that the user who is receiving this broadcast is running.
16324        // If not, we will just skip it. Make an exception for shutdown broadcasts
16325        // and upgrade steps.
16326
16327        if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
16328            if ((callingUid != Process.SYSTEM_UID
16329                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
16330                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
16331                Slog.w(TAG, "Skipping broadcast of " + intent
16332                        + ": user " + userId + " is stopped");
16333                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
16334            }
16335        }
16336
16337        BroadcastOptions brOptions = null;
16338        if (options != null) {
16339            brOptions = new BroadcastOptions(options);
16340            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
16341                // See if the caller is allowed to do this.  Note we are checking against
16342                // the actual real caller (not whoever provided the operation as say a
16343                // PendingIntent), because that who is actually supplied the arguments.
16344                if (checkComponentPermission(
16345                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
16346                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
16347                        != PackageManager.PERMISSION_GRANTED) {
16348                    String msg = "Permission Denial: " + intent.getAction()
16349                            + " broadcast from " + callerPackage + " (pid=" + callingPid
16350                            + ", uid=" + callingUid + ")"
16351                            + " requires "
16352                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
16353                    Slog.w(TAG, msg);
16354                    throw new SecurityException(msg);
16355                }
16356            }
16357        }
16358
16359        /*
16360         * Prevent non-system code (defined here to be non-persistent
16361         * processes) from sending protected broadcasts.
16362         */
16363        int callingAppId = UserHandle.getAppId(callingUid);
16364        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
16365            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
16366            || callingAppId == Process.NFC_UID || callingUid == 0) {
16367            // Always okay.
16368        } else if (callerApp == null || !callerApp.persistent) {
16369            try {
16370                if (AppGlobals.getPackageManager().isProtectedBroadcast(
16371                        intent.getAction())) {
16372                    String msg = "Permission Denial: not allowed to send broadcast "
16373                            + intent.getAction() + " from pid="
16374                            + callingPid + ", uid=" + callingUid;
16375                    Slog.w(TAG, msg);
16376                    throw new SecurityException(msg);
16377                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
16378                    // Special case for compatibility: we don't want apps to send this,
16379                    // but historically it has not been protected and apps may be using it
16380                    // to poke their own app widget.  So, instead of making it protected,
16381                    // just limit it to the caller.
16382                    if (callerApp == null) {
16383                        String msg = "Permission Denial: not allowed to send broadcast "
16384                                + intent.getAction() + " from unknown caller.";
16385                        Slog.w(TAG, msg);
16386                        throw new SecurityException(msg);
16387                    } else if (intent.getComponent() != null) {
16388                        // They are good enough to send to an explicit component...  verify
16389                        // it is being sent to the calling app.
16390                        if (!intent.getComponent().getPackageName().equals(
16391                                callerApp.info.packageName)) {
16392                            String msg = "Permission Denial: not allowed to send broadcast "
16393                                    + intent.getAction() + " to "
16394                                    + intent.getComponent().getPackageName() + " from "
16395                                    + callerApp.info.packageName;
16396                            Slog.w(TAG, msg);
16397                            throw new SecurityException(msg);
16398                        }
16399                    } else {
16400                        // Limit broadcast to their own package.
16401                        intent.setPackage(callerApp.info.packageName);
16402                    }
16403                }
16404            } catch (RemoteException e) {
16405                Slog.w(TAG, "Remote exception", e);
16406                return ActivityManager.BROADCAST_SUCCESS;
16407            }
16408        }
16409
16410        final String action = intent.getAction();
16411        if (action != null) {
16412            switch (action) {
16413                case Intent.ACTION_UID_REMOVED:
16414                case Intent.ACTION_PACKAGE_REMOVED:
16415                case Intent.ACTION_PACKAGE_CHANGED:
16416                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16417                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16418                    // Handle special intents: if this broadcast is from the package
16419                    // manager about a package being removed, we need to remove all of
16420                    // its activities from the history stack.
16421                    if (checkComponentPermission(
16422                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
16423                            callingPid, callingUid, -1, true)
16424                            != PackageManager.PERMISSION_GRANTED) {
16425                        String msg = "Permission Denial: " + intent.getAction()
16426                                + " broadcast from " + callerPackage + " (pid=" + callingPid
16427                                + ", uid=" + callingUid + ")"
16428                                + " requires "
16429                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
16430                        Slog.w(TAG, msg);
16431                        throw new SecurityException(msg);
16432                    }
16433                    switch (action) {
16434                        case Intent.ACTION_UID_REMOVED:
16435                            final Bundle intentExtras = intent.getExtras();
16436                            final int uid = intentExtras != null
16437                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
16438                            if (uid >= 0) {
16439                                mBatteryStatsService.removeUid(uid);
16440                                mAppOpsService.uidRemoved(uid);
16441                            }
16442                            break;
16443                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16444                            // If resources are unavailable just force stop all those packages
16445                            // and flush the attribute cache as well.
16446                            String list[] =
16447                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16448                            if (list != null && list.length > 0) {
16449                                for (int i = 0; i < list.length; i++) {
16450                                    forceStopPackageLocked(list[i], -1, false, true, true,
16451                                            false, false, userId, "storage unmount");
16452                                }
16453                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16454                                sendPackageBroadcastLocked(
16455                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
16456                                        userId);
16457                            }
16458                            break;
16459                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16460                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16461                            break;
16462                        case Intent.ACTION_PACKAGE_REMOVED:
16463                        case Intent.ACTION_PACKAGE_CHANGED:
16464                            Uri data = intent.getData();
16465                            String ssp;
16466                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
16467                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
16468                                boolean fullUninstall = removed &&
16469                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16470                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
16471                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
16472                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
16473                                            false, true, true, false, fullUninstall, userId,
16474                                            removed ? "pkg removed" : "pkg changed");
16475                                }
16476                                if (removed) {
16477                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
16478                                            new String[] {ssp}, userId);
16479                                    if (fullUninstall) {
16480                                        mAppOpsService.packageRemoved(
16481                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
16482
16483                                        // Remove all permissions granted from/to this package
16484                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
16485
16486                                        removeTasksByPackageNameLocked(ssp, userId);
16487                                        mBatteryStatsService.notePackageUninstalled(ssp);
16488                                    }
16489                                } else {
16490                                    cleanupDisabledPackageComponentsLocked(ssp, userId,
16491                                            intent.getStringArrayExtra(
16492                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
16493                                }
16494                            }
16495                            break;
16496                    }
16497                    break;
16498                case Intent.ACTION_PACKAGE_ADDED:
16499                    // Special case for adding a package: by default turn on compatibility mode.
16500                    Uri data = intent.getData();
16501                    String ssp;
16502                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
16503                        final boolean replacing =
16504                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16505                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
16506
16507                        try {
16508                            ApplicationInfo ai = AppGlobals.getPackageManager().
16509                                    getApplicationInfo(ssp, 0, 0);
16510                            mBatteryStatsService.notePackageInstalled(ssp,
16511                                    ai != null ? ai.versionCode : 0);
16512                        } catch (RemoteException e) {
16513                        }
16514                    }
16515                    break;
16516                case Intent.ACTION_TIMEZONE_CHANGED:
16517                    // If this is the time zone changed action, queue up a message that will reset
16518                    // the timezone of all currently running processes. This message will get
16519                    // queued up before the broadcast happens.
16520                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
16521                    break;
16522                case Intent.ACTION_TIME_CHANGED:
16523                    // If the user set the time, let all running processes know.
16524                    final int is24Hour =
16525                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
16526                                    : 0;
16527                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
16528                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16529                    synchronized (stats) {
16530                        stats.noteCurrentTimeChangedLocked();
16531                    }
16532                    break;
16533                case Intent.ACTION_CLEAR_DNS_CACHE:
16534                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
16535                    break;
16536                case Proxy.PROXY_CHANGE_ACTION:
16537                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
16538                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
16539                    break;
16540            }
16541        }
16542
16543        // Add to the sticky list if requested.
16544        if (sticky) {
16545            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
16546                    callingPid, callingUid)
16547                    != PackageManager.PERMISSION_GRANTED) {
16548                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
16549                        + callingPid + ", uid=" + callingUid
16550                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16551                Slog.w(TAG, msg);
16552                throw new SecurityException(msg);
16553            }
16554            if (requiredPermission != null) {
16555                Slog.w(TAG, "Can't broadcast sticky intent " + intent
16556                        + " and enforce permission " + requiredPermission);
16557                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
16558            }
16559            if (intent.getComponent() != null) {
16560                throw new SecurityException(
16561                        "Sticky broadcasts can't target a specific component");
16562            }
16563            // We use userId directly here, since the "all" target is maintained
16564            // as a separate set of sticky broadcasts.
16565            if (userId != UserHandle.USER_ALL) {
16566                // But first, if this is not a broadcast to all users, then
16567                // make sure it doesn't conflict with an existing broadcast to
16568                // all users.
16569                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
16570                        UserHandle.USER_ALL);
16571                if (stickies != null) {
16572                    ArrayList<Intent> list = stickies.get(intent.getAction());
16573                    if (list != null) {
16574                        int N = list.size();
16575                        int i;
16576                        for (i=0; i<N; i++) {
16577                            if (intent.filterEquals(list.get(i))) {
16578                                throw new IllegalArgumentException(
16579                                        "Sticky broadcast " + intent + " for user "
16580                                        + userId + " conflicts with existing global broadcast");
16581                            }
16582                        }
16583                    }
16584                }
16585            }
16586            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16587            if (stickies == null) {
16588                stickies = new ArrayMap<>();
16589                mStickyBroadcasts.put(userId, stickies);
16590            }
16591            ArrayList<Intent> list = stickies.get(intent.getAction());
16592            if (list == null) {
16593                list = new ArrayList<>();
16594                stickies.put(intent.getAction(), list);
16595            }
16596            final int stickiesCount = list.size();
16597            int i;
16598            for (i = 0; i < stickiesCount; i++) {
16599                if (intent.filterEquals(list.get(i))) {
16600                    // This sticky already exists, replace it.
16601                    list.set(i, new Intent(intent));
16602                    break;
16603                }
16604            }
16605            if (i >= stickiesCount) {
16606                list.add(new Intent(intent));
16607            }
16608        }
16609
16610        int[] users;
16611        if (userId == UserHandle.USER_ALL) {
16612            // Caller wants broadcast to go to all started users.
16613            users = mStartedUserArray;
16614        } else {
16615            // Caller wants broadcast to go to one specific user.
16616            users = new int[] {userId};
16617        }
16618
16619        // Figure out who all will receive this broadcast.
16620        List receivers = null;
16621        List<BroadcastFilter> registeredReceivers = null;
16622        // Need to resolve the intent to interested receivers...
16623        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
16624                 == 0) {
16625            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
16626        }
16627        if (intent.getComponent() == null) {
16628            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
16629                // Query one target user at a time, excluding shell-restricted users
16630                UserManagerService ums = getUserManagerLocked();
16631                for (int i = 0; i < users.length; i++) {
16632                    if (ums.hasUserRestriction(
16633                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
16634                        continue;
16635                    }
16636                    List<BroadcastFilter> registeredReceiversForUser =
16637                            mReceiverResolver.queryIntent(intent,
16638                                    resolvedType, false, users[i]);
16639                    if (registeredReceivers == null) {
16640                        registeredReceivers = registeredReceiversForUser;
16641                    } else if (registeredReceiversForUser != null) {
16642                        registeredReceivers.addAll(registeredReceiversForUser);
16643                    }
16644                }
16645            } else {
16646                registeredReceivers = mReceiverResolver.queryIntent(intent,
16647                        resolvedType, false, userId);
16648            }
16649        }
16650
16651        final boolean replacePending =
16652                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16653
16654        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
16655                + " replacePending=" + replacePending);
16656
16657        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16658        if (!ordered && NR > 0) {
16659            // If we are not serializing this broadcast, then send the
16660            // registered receivers separately so they don't wait for the
16661            // components to be launched.
16662            final BroadcastQueue queue = broadcastQueueForIntent(intent);
16663            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16664                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
16665                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
16666                    resultExtras, ordered, sticky, false, userId);
16667            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
16668            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16669            if (!replaced) {
16670                queue.enqueueParallelBroadcastLocked(r);
16671                queue.scheduleBroadcastsLocked();
16672            }
16673            registeredReceivers = null;
16674            NR = 0;
16675        }
16676
16677        // Merge into one list.
16678        int ir = 0;
16679        if (receivers != null) {
16680            // A special case for PACKAGE_ADDED: do not allow the package
16681            // being added to see this broadcast.  This prevents them from
16682            // using this as a back door to get run as soon as they are
16683            // installed.  Maybe in the future we want to have a special install
16684            // broadcast or such for apps, but we'd like to deliberately make
16685            // this decision.
16686            String skipPackages[] = null;
16687            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16688                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16689                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16690                Uri data = intent.getData();
16691                if (data != null) {
16692                    String pkgName = data.getSchemeSpecificPart();
16693                    if (pkgName != null) {
16694                        skipPackages = new String[] { pkgName };
16695                    }
16696                }
16697            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16698                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16699            }
16700            if (skipPackages != null && (skipPackages.length > 0)) {
16701                for (String skipPackage : skipPackages) {
16702                    if (skipPackage != null) {
16703                        int NT = receivers.size();
16704                        for (int it=0; it<NT; it++) {
16705                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
16706                            if (curt.activityInfo.packageName.equals(skipPackage)) {
16707                                receivers.remove(it);
16708                                it--;
16709                                NT--;
16710                            }
16711                        }
16712                    }
16713                }
16714            }
16715
16716            int NT = receivers != null ? receivers.size() : 0;
16717            int it = 0;
16718            ResolveInfo curt = null;
16719            BroadcastFilter curr = null;
16720            while (it < NT && ir < NR) {
16721                if (curt == null) {
16722                    curt = (ResolveInfo)receivers.get(it);
16723                }
16724                if (curr == null) {
16725                    curr = registeredReceivers.get(ir);
16726                }
16727                if (curr.getPriority() >= curt.priority) {
16728                    // Insert this broadcast record into the final list.
16729                    receivers.add(it, curr);
16730                    ir++;
16731                    curr = null;
16732                    it++;
16733                    NT++;
16734                } else {
16735                    // Skip to the next ResolveInfo in the final list.
16736                    it++;
16737                    curt = null;
16738                }
16739            }
16740        }
16741        while (ir < NR) {
16742            if (receivers == null) {
16743                receivers = new ArrayList();
16744            }
16745            receivers.add(registeredReceivers.get(ir));
16746            ir++;
16747        }
16748
16749        if ((receivers != null && receivers.size() > 0)
16750                || resultTo != null) {
16751            BroadcastQueue queue = broadcastQueueForIntent(intent);
16752            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16753                    callerPackage, callingPid, callingUid, resolvedType,
16754                    requiredPermission, appOp, brOptions, receivers, resultTo, resultCode,
16755                    resultData, resultExtras, ordered, sticky, false, userId);
16756
16757            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
16758                    + ": prev had " + queue.mOrderedBroadcasts.size());
16759            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
16760                    "Enqueueing broadcast " + r.intent.getAction());
16761
16762            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16763            if (!replaced) {
16764                queue.enqueueOrderedBroadcastLocked(r);
16765                queue.scheduleBroadcastsLocked();
16766            }
16767        }
16768
16769        return ActivityManager.BROADCAST_SUCCESS;
16770    }
16771
16772    final Intent verifyBroadcastLocked(Intent intent) {
16773        // Refuse possible leaked file descriptors
16774        if (intent != null && intent.hasFileDescriptors() == true) {
16775            throw new IllegalArgumentException("File descriptors passed in Intent");
16776        }
16777
16778        int flags = intent.getFlags();
16779
16780        if (!mProcessesReady) {
16781            // if the caller really truly claims to know what they're doing, go
16782            // ahead and allow the broadcast without launching any receivers
16783            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16784                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
16785            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16786                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16787                        + " before boot completion");
16788                throw new IllegalStateException("Cannot broadcast before boot completed");
16789            }
16790        }
16791
16792        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16793            throw new IllegalArgumentException(
16794                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16795        }
16796
16797        return intent;
16798    }
16799
16800    public final int broadcastIntent(IApplicationThread caller,
16801            Intent intent, String resolvedType, IIntentReceiver resultTo,
16802            int resultCode, String resultData, Bundle resultExtras,
16803            String requiredPermission, int appOp, Bundle options,
16804            boolean serialized, boolean sticky, int userId) {
16805        enforceNotIsolatedCaller("broadcastIntent");
16806        synchronized(this) {
16807            intent = verifyBroadcastLocked(intent);
16808
16809            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16810            final int callingPid = Binder.getCallingPid();
16811            final int callingUid = Binder.getCallingUid();
16812            final long origId = Binder.clearCallingIdentity();
16813            int res = broadcastIntentLocked(callerApp,
16814                    callerApp != null ? callerApp.info.packageName : null,
16815                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
16816                    requiredPermission, appOp, null, serialized, sticky,
16817                    callingPid, callingUid, userId);
16818            Binder.restoreCallingIdentity(origId);
16819            return res;
16820        }
16821    }
16822
16823    int broadcastIntentInPackage(String packageName, int uid,
16824            Intent intent, String resolvedType, IIntentReceiver resultTo,
16825            int resultCode, String resultData, Bundle resultExtras,
16826            String requiredPermission, Bundle options, boolean serialized, boolean sticky,
16827            int userId) {
16828        synchronized(this) {
16829            intent = verifyBroadcastLocked(intent);
16830
16831            final long origId = Binder.clearCallingIdentity();
16832            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16833                    resultTo, resultCode, resultData, resultExtras, requiredPermission,
16834                    AppOpsManager.OP_NONE, options, serialized, sticky, -1, uid, userId);
16835            Binder.restoreCallingIdentity(origId);
16836            return res;
16837        }
16838    }
16839
16840    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16841        // Refuse possible leaked file descriptors
16842        if (intent != null && intent.hasFileDescriptors() == true) {
16843            throw new IllegalArgumentException("File descriptors passed in Intent");
16844        }
16845
16846        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16847                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16848
16849        synchronized(this) {
16850            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16851                    != PackageManager.PERMISSION_GRANTED) {
16852                String msg = "Permission Denial: unbroadcastIntent() from pid="
16853                        + Binder.getCallingPid()
16854                        + ", uid=" + Binder.getCallingUid()
16855                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16856                Slog.w(TAG, msg);
16857                throw new SecurityException(msg);
16858            }
16859            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16860            if (stickies != null) {
16861                ArrayList<Intent> list = stickies.get(intent.getAction());
16862                if (list != null) {
16863                    int N = list.size();
16864                    int i;
16865                    for (i=0; i<N; i++) {
16866                        if (intent.filterEquals(list.get(i))) {
16867                            list.remove(i);
16868                            break;
16869                        }
16870                    }
16871                    if (list.size() <= 0) {
16872                        stickies.remove(intent.getAction());
16873                    }
16874                }
16875                if (stickies.size() <= 0) {
16876                    mStickyBroadcasts.remove(userId);
16877                }
16878            }
16879        }
16880    }
16881
16882    void backgroundServicesFinishedLocked(int userId) {
16883        for (BroadcastQueue queue : mBroadcastQueues) {
16884            queue.backgroundServicesFinishedLocked(userId);
16885        }
16886    }
16887
16888    public void finishReceiver(IBinder who, int resultCode, String resultData,
16889            Bundle resultExtras, boolean resultAbort, int flags) {
16890        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
16891
16892        // Refuse possible leaked file descriptors
16893        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16894            throw new IllegalArgumentException("File descriptors passed in Bundle");
16895        }
16896
16897        final long origId = Binder.clearCallingIdentity();
16898        try {
16899            boolean doNext = false;
16900            BroadcastRecord r;
16901
16902            synchronized(this) {
16903                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
16904                        ? mFgBroadcastQueue : mBgBroadcastQueue;
16905                r = queue.getMatchingOrderedReceiver(who);
16906                if (r != null) {
16907                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16908                        resultData, resultExtras, resultAbort, true);
16909                }
16910            }
16911
16912            if (doNext) {
16913                r.queue.processNextBroadcast(false);
16914            }
16915            trimApplications();
16916        } finally {
16917            Binder.restoreCallingIdentity(origId);
16918        }
16919    }
16920
16921    // =========================================================
16922    // INSTRUMENTATION
16923    // =========================================================
16924
16925    public boolean startInstrumentation(ComponentName className,
16926            String profileFile, int flags, Bundle arguments,
16927            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16928            int userId, String abiOverride) {
16929        enforceNotIsolatedCaller("startInstrumentation");
16930        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16931                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16932        // Refuse possible leaked file descriptors
16933        if (arguments != null && arguments.hasFileDescriptors()) {
16934            throw new IllegalArgumentException("File descriptors passed in Bundle");
16935        }
16936
16937        synchronized(this) {
16938            InstrumentationInfo ii = null;
16939            ApplicationInfo ai = null;
16940            try {
16941                ii = mContext.getPackageManager().getInstrumentationInfo(
16942                    className, STOCK_PM_FLAGS);
16943                ai = AppGlobals.getPackageManager().getApplicationInfo(
16944                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16945            } catch (PackageManager.NameNotFoundException e) {
16946            } catch (RemoteException e) {
16947            }
16948            if (ii == null) {
16949                reportStartInstrumentationFailure(watcher, className,
16950                        "Unable to find instrumentation info for: " + className);
16951                return false;
16952            }
16953            if (ai == null) {
16954                reportStartInstrumentationFailure(watcher, className,
16955                        "Unable to find instrumentation target package: " + ii.targetPackage);
16956                return false;
16957            }
16958
16959            int match = mContext.getPackageManager().checkSignatures(
16960                    ii.targetPackage, ii.packageName);
16961            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16962                String msg = "Permission Denial: starting instrumentation "
16963                        + className + " from pid="
16964                        + Binder.getCallingPid()
16965                        + ", uid=" + Binder.getCallingPid()
16966                        + " not allowed because package " + ii.packageName
16967                        + " does not have a signature matching the target "
16968                        + ii.targetPackage;
16969                reportStartInstrumentationFailure(watcher, className, msg);
16970                throw new SecurityException(msg);
16971            }
16972
16973            final long origId = Binder.clearCallingIdentity();
16974            // Instrumentation can kill and relaunch even persistent processes
16975            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16976                    "start instr");
16977            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16978            app.instrumentationClass = className;
16979            app.instrumentationInfo = ai;
16980            app.instrumentationProfileFile = profileFile;
16981            app.instrumentationArguments = arguments;
16982            app.instrumentationWatcher = watcher;
16983            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16984            app.instrumentationResultClass = className;
16985            Binder.restoreCallingIdentity(origId);
16986        }
16987
16988        return true;
16989    }
16990
16991    /**
16992     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16993     * error to the logs, but if somebody is watching, send the report there too.  This enables
16994     * the "am" command to report errors with more information.
16995     *
16996     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16997     * @param cn The component name of the instrumentation.
16998     * @param report The error report.
16999     */
17000    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
17001            ComponentName cn, String report) {
17002        Slog.w(TAG, report);
17003        try {
17004            if (watcher != null) {
17005                Bundle results = new Bundle();
17006                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17007                results.putString("Error", report);
17008                watcher.instrumentationStatus(cn, -1, results);
17009            }
17010        } catch (RemoteException e) {
17011            Slog.w(TAG, e);
17012        }
17013    }
17014
17015    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17016        if (app.instrumentationWatcher != null) {
17017            try {
17018                // NOTE:  IInstrumentationWatcher *must* be oneway here
17019                app.instrumentationWatcher.instrumentationFinished(
17020                    app.instrumentationClass,
17021                    resultCode,
17022                    results);
17023            } catch (RemoteException e) {
17024            }
17025        }
17026        if (app.instrumentationUiAutomationConnection != null) {
17027            try {
17028                app.instrumentationUiAutomationConnection.shutdown();
17029            } catch (RemoteException re) {
17030                /* ignore */
17031            }
17032            // Only a UiAutomation can set this flag and now that
17033            // it is finished we make sure it is reset to its default.
17034            mUserIsMonkey = false;
17035        }
17036        app.instrumentationWatcher = null;
17037        app.instrumentationUiAutomationConnection = null;
17038        app.instrumentationClass = null;
17039        app.instrumentationInfo = null;
17040        app.instrumentationProfileFile = null;
17041        app.instrumentationArguments = null;
17042
17043        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17044                "finished inst");
17045    }
17046
17047    public void finishInstrumentation(IApplicationThread target,
17048            int resultCode, Bundle results) {
17049        int userId = UserHandle.getCallingUserId();
17050        // Refuse possible leaked file descriptors
17051        if (results != null && results.hasFileDescriptors()) {
17052            throw new IllegalArgumentException("File descriptors passed in Intent");
17053        }
17054
17055        synchronized(this) {
17056            ProcessRecord app = getRecordForAppLocked(target);
17057            if (app == null) {
17058                Slog.w(TAG, "finishInstrumentation: no app for " + target);
17059                return;
17060            }
17061            final long origId = Binder.clearCallingIdentity();
17062            finishInstrumentationLocked(app, resultCode, results);
17063            Binder.restoreCallingIdentity(origId);
17064        }
17065    }
17066
17067    // =========================================================
17068    // CONFIGURATION
17069    // =========================================================
17070
17071    public ConfigurationInfo getDeviceConfigurationInfo() {
17072        ConfigurationInfo config = new ConfigurationInfo();
17073        synchronized (this) {
17074            config.reqTouchScreen = mConfiguration.touchscreen;
17075            config.reqKeyboardType = mConfiguration.keyboard;
17076            config.reqNavigation = mConfiguration.navigation;
17077            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17078                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17079                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17080            }
17081            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17082                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17083                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17084            }
17085            config.reqGlEsVersion = GL_ES_VERSION;
17086        }
17087        return config;
17088    }
17089
17090    ActivityStack getFocusedStack() {
17091        return mStackSupervisor.getFocusedStack();
17092    }
17093
17094    @Override
17095    public int getFocusedStackId() throws RemoteException {
17096        ActivityStack focusedStack = getFocusedStack();
17097        if (focusedStack != null) {
17098            return focusedStack.getStackId();
17099        }
17100        return -1;
17101    }
17102
17103    public Configuration getConfiguration() {
17104        Configuration ci;
17105        synchronized(this) {
17106            ci = new Configuration(mConfiguration);
17107            ci.userSetLocale = false;
17108        }
17109        return ci;
17110    }
17111
17112    public void updatePersistentConfiguration(Configuration values) {
17113        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17114                "updateConfiguration()");
17115        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
17116                "updateConfiguration()");
17117        if (values == null) {
17118            throw new NullPointerException("Configuration must not be null");
17119        }
17120
17121        synchronized(this) {
17122            final long origId = Binder.clearCallingIdentity();
17123            updateConfigurationLocked(values, null, true, false);
17124            Binder.restoreCallingIdentity(origId);
17125        }
17126    }
17127
17128    public void updateConfiguration(Configuration values) {
17129        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17130                "updateConfiguration()");
17131
17132        synchronized(this) {
17133            if (values == null && mWindowManager != null) {
17134                // sentinel: fetch the current configuration from the window manager
17135                values = mWindowManager.computeNewConfiguration();
17136            }
17137
17138            if (mWindowManager != null) {
17139                mProcessList.applyDisplaySize(mWindowManager);
17140            }
17141
17142            final long origId = Binder.clearCallingIdentity();
17143            if (values != null) {
17144                Settings.System.clearConfiguration(values);
17145            }
17146            updateConfigurationLocked(values, null, false, false);
17147            Binder.restoreCallingIdentity(origId);
17148        }
17149    }
17150
17151    /**
17152     * Do either or both things: (1) change the current configuration, and (2)
17153     * make sure the given activity is running with the (now) current
17154     * configuration.  Returns true if the activity has been left running, or
17155     * false if <var>starting</var> is being destroyed to match the new
17156     * configuration.
17157     * @param persistent TODO
17158     */
17159    boolean updateConfigurationLocked(Configuration values,
17160            ActivityRecord starting, boolean persistent, boolean initLocale) {
17161        int changes = 0;
17162
17163        if (values != null) {
17164            Configuration newConfig = new Configuration(mConfiguration);
17165            changes = newConfig.updateFrom(values);
17166            if (changes != 0) {
17167                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
17168                        "Updating configuration to: " + values);
17169
17170                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
17171
17172                if (!initLocale && values.locale != null && values.userSetLocale) {
17173                    final String languageTag = values.locale.toLanguageTag();
17174                    SystemProperties.set("persist.sys.locale", languageTag);
17175                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
17176                            values.locale));
17177                }
17178
17179                mConfigurationSeq++;
17180                if (mConfigurationSeq <= 0) {
17181                    mConfigurationSeq = 1;
17182                }
17183                newConfig.seq = mConfigurationSeq;
17184                mConfiguration = newConfig;
17185                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
17186                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
17187                //mUsageStatsService.noteStartConfig(newConfig);
17188
17189                final Configuration configCopy = new Configuration(mConfiguration);
17190
17191                // TODO: If our config changes, should we auto dismiss any currently
17192                // showing dialogs?
17193                mShowDialogs = shouldShowDialogs(newConfig);
17194
17195                AttributeCache ac = AttributeCache.instance();
17196                if (ac != null) {
17197                    ac.updateConfiguration(configCopy);
17198                }
17199
17200                // Make sure all resources in our process are updated
17201                // right now, so that anyone who is going to retrieve
17202                // resource values after we return will be sure to get
17203                // the new ones.  This is especially important during
17204                // boot, where the first config change needs to guarantee
17205                // all resources have that config before following boot
17206                // code is executed.
17207                mSystemThread.applyConfigurationToResources(configCopy);
17208
17209                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
17210                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
17211                    msg.obj = new Configuration(configCopy);
17212                    mHandler.sendMessage(msg);
17213                }
17214
17215                for (int i=mLruProcesses.size()-1; i>=0; i--) {
17216                    ProcessRecord app = mLruProcesses.get(i);
17217                    try {
17218                        if (app.thread != null) {
17219                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
17220                                    + app.processName + " new config " + mConfiguration);
17221                            app.thread.scheduleConfigurationChanged(configCopy);
17222                        }
17223                    } catch (Exception e) {
17224                    }
17225                }
17226                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
17227                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17228                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
17229                        | Intent.FLAG_RECEIVER_FOREGROUND);
17230                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
17231                        null, AppOpsManager.OP_NONE, null, false, false,
17232                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17233                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
17234                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
17235                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17236                    if (!mProcessesReady) {
17237                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17238                    }
17239                    broadcastIntentLocked(null, null, intent,
17240                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17241                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17242                }
17243            }
17244        }
17245
17246        boolean kept = true;
17247        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
17248        // mainStack is null during startup.
17249        if (mainStack != null) {
17250            if (changes != 0 && starting == null) {
17251                // If the configuration changed, and the caller is not already
17252                // in the process of starting an activity, then find the top
17253                // activity to check if its configuration needs to change.
17254                starting = mainStack.topRunningActivityLocked(null);
17255            }
17256
17257            if (starting != null) {
17258                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
17259                // And we need to make sure at this point that all other activities
17260                // are made visible with the correct configuration.
17261                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
17262            }
17263        }
17264
17265        if (values != null && mWindowManager != null) {
17266            mWindowManager.setNewConfiguration(mConfiguration);
17267        }
17268
17269        return kept;
17270    }
17271
17272    /**
17273     * Decide based on the configuration whether we should shouw the ANR,
17274     * crash, etc dialogs.  The idea is that if there is no affordnace to
17275     * press the on-screen buttons, we shouldn't show the dialog.
17276     *
17277     * A thought: SystemUI might also want to get told about this, the Power
17278     * dialog / global actions also might want different behaviors.
17279     */
17280    private static final boolean shouldShowDialogs(Configuration config) {
17281        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
17282                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
17283                && config.navigation == Configuration.NAVIGATION_NONAV);
17284    }
17285
17286    @Override
17287    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
17288        synchronized (this) {
17289            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
17290            if (srec != null) {
17291                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
17292            }
17293        }
17294        return false;
17295    }
17296
17297    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
17298            Intent resultData) {
17299
17300        synchronized (this) {
17301            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
17302            if (r != null) {
17303                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
17304            }
17305            return false;
17306        }
17307    }
17308
17309    public int getLaunchedFromUid(IBinder activityToken) {
17310        ActivityRecord srec;
17311        synchronized (this) {
17312            srec = ActivityRecord.forTokenLocked(activityToken);
17313        }
17314        if (srec == null) {
17315            return -1;
17316        }
17317        return srec.launchedFromUid;
17318    }
17319
17320    public String getLaunchedFromPackage(IBinder activityToken) {
17321        ActivityRecord srec;
17322        synchronized (this) {
17323            srec = ActivityRecord.forTokenLocked(activityToken);
17324        }
17325        if (srec == null) {
17326            return null;
17327        }
17328        return srec.launchedFromPackage;
17329    }
17330
17331    // =========================================================
17332    // LIFETIME MANAGEMENT
17333    // =========================================================
17334
17335    // Returns which broadcast queue the app is the current [or imminent] receiver
17336    // on, or 'null' if the app is not an active broadcast recipient.
17337    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
17338        BroadcastRecord r = app.curReceiver;
17339        if (r != null) {
17340            return r.queue;
17341        }
17342
17343        // It's not the current receiver, but it might be starting up to become one
17344        synchronized (this) {
17345            for (BroadcastQueue queue : mBroadcastQueues) {
17346                r = queue.mPendingBroadcast;
17347                if (r != null && r.curApp == app) {
17348                    // found it; report which queue it's in
17349                    return queue;
17350                }
17351            }
17352        }
17353
17354        return null;
17355    }
17356
17357    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17358            ComponentName targetComponent, String targetProcess) {
17359        if (!mTrackingAssociations) {
17360            return null;
17361        }
17362        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17363                = mAssociations.get(targetUid);
17364        if (components == null) {
17365            components = new ArrayMap<>();
17366            mAssociations.put(targetUid, components);
17367        }
17368        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17369        if (sourceUids == null) {
17370            sourceUids = new SparseArray<>();
17371            components.put(targetComponent, sourceUids);
17372        }
17373        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17374        if (sourceProcesses == null) {
17375            sourceProcesses = new ArrayMap<>();
17376            sourceUids.put(sourceUid, sourceProcesses);
17377        }
17378        Association ass = sourceProcesses.get(sourceProcess);
17379        if (ass == null) {
17380            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
17381                    targetProcess);
17382            sourceProcesses.put(sourceProcess, ass);
17383        }
17384        ass.mCount++;
17385        ass.mNesting++;
17386        if (ass.mNesting == 1) {
17387            ass.mStartTime = SystemClock.uptimeMillis();
17388        }
17389        return ass;
17390    }
17391
17392    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17393            ComponentName targetComponent) {
17394        if (!mTrackingAssociations) {
17395            return;
17396        }
17397        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17398                = mAssociations.get(targetUid);
17399        if (components == null) {
17400            return;
17401        }
17402        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17403        if (sourceUids == null) {
17404            return;
17405        }
17406        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17407        if (sourceProcesses == null) {
17408            return;
17409        }
17410        Association ass = sourceProcesses.get(sourceProcess);
17411        if (ass == null || ass.mNesting <= 0) {
17412            return;
17413        }
17414        ass.mNesting--;
17415        if (ass.mNesting == 0) {
17416            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
17417        }
17418    }
17419
17420    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
17421            boolean doingAll, long now) {
17422        if (mAdjSeq == app.adjSeq) {
17423            // This adjustment has already been computed.
17424            return app.curRawAdj;
17425        }
17426
17427        if (app.thread == null) {
17428            app.adjSeq = mAdjSeq;
17429            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17430            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17431            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
17432        }
17433
17434        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
17435        app.adjSource = null;
17436        app.adjTarget = null;
17437        app.empty = false;
17438        app.cached = false;
17439
17440        final int activitiesSize = app.activities.size();
17441
17442        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17443            // The max adjustment doesn't allow this app to be anything
17444            // below foreground, so it is not worth doing work for it.
17445            app.adjType = "fixed";
17446            app.adjSeq = mAdjSeq;
17447            app.curRawAdj = app.maxAdj;
17448            app.foregroundActivities = false;
17449            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
17450            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
17451            // System processes can do UI, and when they do we want to have
17452            // them trim their memory after the user leaves the UI.  To
17453            // facilitate this, here we need to determine whether or not it
17454            // is currently showing UI.
17455            app.systemNoUi = true;
17456            if (app == TOP_APP) {
17457                app.systemNoUi = false;
17458            } else if (activitiesSize > 0) {
17459                for (int j = 0; j < activitiesSize; j++) {
17460                    final ActivityRecord r = app.activities.get(j);
17461                    if (r.visible) {
17462                        app.systemNoUi = false;
17463                    }
17464                }
17465            }
17466            if (!app.systemNoUi) {
17467                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
17468            }
17469            return (app.curAdj=app.maxAdj);
17470        }
17471
17472        app.systemNoUi = false;
17473
17474        final int PROCESS_STATE_TOP = mTopProcessState;
17475
17476        // Determine the importance of the process, starting with most
17477        // important to least, and assign an appropriate OOM adjustment.
17478        int adj;
17479        int schedGroup;
17480        int procState;
17481        boolean foregroundActivities = false;
17482        BroadcastQueue queue;
17483        if (app == TOP_APP) {
17484            // The last app on the list is the foreground app.
17485            adj = ProcessList.FOREGROUND_APP_ADJ;
17486            schedGroup = Process.THREAD_GROUP_DEFAULT;
17487            app.adjType = "top-activity";
17488            foregroundActivities = true;
17489            procState = PROCESS_STATE_TOP;
17490        } else if (app.instrumentationClass != null) {
17491            // Don't want to kill running instrumentation.
17492            adj = ProcessList.FOREGROUND_APP_ADJ;
17493            schedGroup = Process.THREAD_GROUP_DEFAULT;
17494            app.adjType = "instrumentation";
17495            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17496        } else if ((queue = isReceivingBroadcast(app)) != null) {
17497            // An app that is currently receiving a broadcast also
17498            // counts as being in the foreground for OOM killer purposes.
17499            // It's placed in a sched group based on the nature of the
17500            // broadcast as reflected by which queue it's active in.
17501            adj = ProcessList.FOREGROUND_APP_ADJ;
17502            schedGroup = (queue == mFgBroadcastQueue)
17503                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17504            app.adjType = "broadcast";
17505            procState = ActivityManager.PROCESS_STATE_RECEIVER;
17506        } else if (app.executingServices.size() > 0) {
17507            // An app that is currently executing a service callback also
17508            // counts as being in the foreground.
17509            adj = ProcessList.FOREGROUND_APP_ADJ;
17510            schedGroup = app.execServicesFg ?
17511                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17512            app.adjType = "exec-service";
17513            procState = ActivityManager.PROCESS_STATE_SERVICE;
17514            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
17515        } else {
17516            // As far as we know the process is empty.  We may change our mind later.
17517            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17518            // At this point we don't actually know the adjustment.  Use the cached adj
17519            // value that the caller wants us to.
17520            adj = cachedAdj;
17521            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17522            app.cached = true;
17523            app.empty = true;
17524            app.adjType = "cch-empty";
17525        }
17526
17527        // Examine all activities if not already foreground.
17528        if (!foregroundActivities && activitiesSize > 0) {
17529            for (int j = 0; j < activitiesSize; j++) {
17530                final ActivityRecord r = app.activities.get(j);
17531                if (r.app != app) {
17532                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
17533                            + app + "?!? Using " + r.app + " instead.");
17534                    continue;
17535                }
17536                if (r.visible) {
17537                    // App has a visible activity; only upgrade adjustment.
17538                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17539                        adj = ProcessList.VISIBLE_APP_ADJ;
17540                        app.adjType = "visible";
17541                    }
17542                    if (procState > PROCESS_STATE_TOP) {
17543                        procState = PROCESS_STATE_TOP;
17544                    }
17545                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17546                    app.cached = false;
17547                    app.empty = false;
17548                    foregroundActivities = true;
17549                    break;
17550                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
17551                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17552                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17553                        app.adjType = "pausing";
17554                    }
17555                    if (procState > PROCESS_STATE_TOP) {
17556                        procState = PROCESS_STATE_TOP;
17557                    }
17558                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17559                    app.cached = false;
17560                    app.empty = false;
17561                    foregroundActivities = true;
17562                } else if (r.state == ActivityState.STOPPING) {
17563                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17564                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17565                        app.adjType = "stopping";
17566                    }
17567                    // For the process state, we will at this point consider the
17568                    // process to be cached.  It will be cached either as an activity
17569                    // or empty depending on whether the activity is finishing.  We do
17570                    // this so that we can treat the process as cached for purposes of
17571                    // memory trimming (determing current memory level, trim command to
17572                    // send to process) since there can be an arbitrary number of stopping
17573                    // processes and they should soon all go into the cached state.
17574                    if (!r.finishing) {
17575                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17576                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17577                        }
17578                    }
17579                    app.cached = false;
17580                    app.empty = false;
17581                    foregroundActivities = true;
17582                } else {
17583                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17584                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17585                        app.adjType = "cch-act";
17586                    }
17587                }
17588            }
17589        }
17590
17591        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17592            if (app.foregroundServices) {
17593                // The user is aware of this app, so make it visible.
17594                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17595                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17596                app.cached = false;
17597                app.adjType = "fg-service";
17598                schedGroup = Process.THREAD_GROUP_DEFAULT;
17599            } else if (app.forcingToForeground != null) {
17600                // The user is aware of this app, so make it visible.
17601                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17602                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17603                app.cached = false;
17604                app.adjType = "force-fg";
17605                app.adjSource = app.forcingToForeground;
17606                schedGroup = Process.THREAD_GROUP_DEFAULT;
17607            }
17608        }
17609
17610        if (app == mHeavyWeightProcess) {
17611            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
17612                // We don't want to kill the current heavy-weight process.
17613                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
17614                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17615                app.cached = false;
17616                app.adjType = "heavy";
17617            }
17618            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17619                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
17620            }
17621        }
17622
17623        if (app == mHomeProcess) {
17624            if (adj > ProcessList.HOME_APP_ADJ) {
17625                // This process is hosting what we currently consider to be the
17626                // home app, so we don't want to let it go into the background.
17627                adj = ProcessList.HOME_APP_ADJ;
17628                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17629                app.cached = false;
17630                app.adjType = "home";
17631            }
17632            if (procState > ActivityManager.PROCESS_STATE_HOME) {
17633                procState = ActivityManager.PROCESS_STATE_HOME;
17634            }
17635        }
17636
17637        if (app == mPreviousProcess && app.activities.size() > 0) {
17638            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
17639                // This was the previous process that showed UI to the user.
17640                // We want to try to keep it around more aggressively, to give
17641                // a good experience around switching between two apps.
17642                adj = ProcessList.PREVIOUS_APP_ADJ;
17643                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17644                app.cached = false;
17645                app.adjType = "previous";
17646            }
17647            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17648                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17649            }
17650        }
17651
17652        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
17653                + " reason=" + app.adjType);
17654
17655        // By default, we use the computed adjustment.  It may be changed if
17656        // there are applications dependent on our services or providers, but
17657        // this gives us a baseline and makes sure we don't get into an
17658        // infinite recursion.
17659        app.adjSeq = mAdjSeq;
17660        app.curRawAdj = adj;
17661        app.hasStartedServices = false;
17662
17663        if (mBackupTarget != null && app == mBackupTarget.app) {
17664            // If possible we want to avoid killing apps while they're being backed up
17665            if (adj > ProcessList.BACKUP_APP_ADJ) {
17666                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
17667                adj = ProcessList.BACKUP_APP_ADJ;
17668                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17669                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17670                }
17671                app.adjType = "backup";
17672                app.cached = false;
17673            }
17674            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
17675                procState = ActivityManager.PROCESS_STATE_BACKUP;
17676            }
17677        }
17678
17679        boolean mayBeTop = false;
17680
17681        for (int is = app.services.size()-1;
17682                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17683                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17684                        || procState > ActivityManager.PROCESS_STATE_TOP);
17685                is--) {
17686            ServiceRecord s = app.services.valueAt(is);
17687            if (s.startRequested) {
17688                app.hasStartedServices = true;
17689                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
17690                    procState = ActivityManager.PROCESS_STATE_SERVICE;
17691                }
17692                if (app.hasShownUi && app != mHomeProcess) {
17693                    // If this process has shown some UI, let it immediately
17694                    // go to the LRU list because it may be pretty heavy with
17695                    // UI stuff.  We'll tag it with a label just to help
17696                    // debug and understand what is going on.
17697                    if (adj > ProcessList.SERVICE_ADJ) {
17698                        app.adjType = "cch-started-ui-services";
17699                    }
17700                } else {
17701                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17702                        // This service has seen some activity within
17703                        // recent memory, so we will keep its process ahead
17704                        // of the background processes.
17705                        if (adj > ProcessList.SERVICE_ADJ) {
17706                            adj = ProcessList.SERVICE_ADJ;
17707                            app.adjType = "started-services";
17708                            app.cached = false;
17709                        }
17710                    }
17711                    // If we have let the service slide into the background
17712                    // state, still have some text describing what it is doing
17713                    // even though the service no longer has an impact.
17714                    if (adj > ProcessList.SERVICE_ADJ) {
17715                        app.adjType = "cch-started-services";
17716                    }
17717                }
17718            }
17719            for (int conni = s.connections.size()-1;
17720                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17721                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17722                            || procState > ActivityManager.PROCESS_STATE_TOP);
17723                    conni--) {
17724                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17725                for (int i = 0;
17726                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17727                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17728                                || procState > ActivityManager.PROCESS_STATE_TOP);
17729                        i++) {
17730                    // XXX should compute this based on the max of
17731                    // all connected clients.
17732                    ConnectionRecord cr = clist.get(i);
17733                    if (cr.binding.client == app) {
17734                        // Binding to ourself is not interesting.
17735                        continue;
17736                    }
17737                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17738                        ProcessRecord client = cr.binding.client;
17739                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
17740                                TOP_APP, doingAll, now);
17741                        int clientProcState = client.curProcState;
17742                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17743                            // If the other app is cached for any reason, for purposes here
17744                            // we are going to consider it empty.  The specific cached state
17745                            // doesn't propagate except under certain conditions.
17746                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17747                        }
17748                        String adjType = null;
17749                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17750                            // Not doing bind OOM management, so treat
17751                            // this guy more like a started service.
17752                            if (app.hasShownUi && app != mHomeProcess) {
17753                                // If this process has shown some UI, let it immediately
17754                                // go to the LRU list because it may be pretty heavy with
17755                                // UI stuff.  We'll tag it with a label just to help
17756                                // debug and understand what is going on.
17757                                if (adj > clientAdj) {
17758                                    adjType = "cch-bound-ui-services";
17759                                }
17760                                app.cached = false;
17761                                clientAdj = adj;
17762                                clientProcState = procState;
17763                            } else {
17764                                if (now >= (s.lastActivity
17765                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17766                                    // This service has not seen activity within
17767                                    // recent memory, so allow it to drop to the
17768                                    // LRU list if there is no other reason to keep
17769                                    // it around.  We'll also tag it with a label just
17770                                    // to help debug and undertand what is going on.
17771                                    if (adj > clientAdj) {
17772                                        adjType = "cch-bound-services";
17773                                    }
17774                                    clientAdj = adj;
17775                                }
17776                            }
17777                        }
17778                        if (adj > clientAdj) {
17779                            // If this process has recently shown UI, and
17780                            // the process that is binding to it is less
17781                            // important than being visible, then we don't
17782                            // care about the binding as much as we care
17783                            // about letting this process get into the LRU
17784                            // list to be killed and restarted if needed for
17785                            // memory.
17786                            if (app.hasShownUi && app != mHomeProcess
17787                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17788                                adjType = "cch-bound-ui-services";
17789                            } else {
17790                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17791                                        |Context.BIND_IMPORTANT)) != 0) {
17792                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17793                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17794                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17795                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17796                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17797                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17798                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17799                                    adj = clientAdj;
17800                                } else {
17801                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17802                                        adj = ProcessList.VISIBLE_APP_ADJ;
17803                                    }
17804                                }
17805                                if (!client.cached) {
17806                                    app.cached = false;
17807                                }
17808                                adjType = "service";
17809                            }
17810                        }
17811                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17812                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17813                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17814                            }
17815                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17816                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17817                                    // Special handling of clients who are in the top state.
17818                                    // We *may* want to consider this process to be in the
17819                                    // top state as well, but only if there is not another
17820                                    // reason for it to be running.  Being on the top is a
17821                                    // special state, meaning you are specifically running
17822                                    // for the current top app.  If the process is already
17823                                    // running in the background for some other reason, it
17824                                    // is more important to continue considering it to be
17825                                    // in the background state.
17826                                    mayBeTop = true;
17827                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17828                                } else {
17829                                    // Special handling for above-top states (persistent
17830                                    // processes).  These should not bring the current process
17831                                    // into the top state, since they are not on top.  Instead
17832                                    // give them the best state after that.
17833                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
17834                                        clientProcState =
17835                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
17836                                    } else if (mWakefulness
17837                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
17838                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
17839                                                    != 0) {
17840                                        clientProcState =
17841                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
17842                                    } else {
17843                                        clientProcState =
17844                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17845                                    }
17846                                }
17847                            }
17848                        } else {
17849                            if (clientProcState <
17850                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17851                                clientProcState =
17852                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17853                            }
17854                        }
17855                        if (procState > clientProcState) {
17856                            procState = clientProcState;
17857                        }
17858                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17859                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17860                            app.pendingUiClean = true;
17861                        }
17862                        if (adjType != null) {
17863                            app.adjType = adjType;
17864                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17865                                    .REASON_SERVICE_IN_USE;
17866                            app.adjSource = cr.binding.client;
17867                            app.adjSourceProcState = clientProcState;
17868                            app.adjTarget = s.name;
17869                        }
17870                    }
17871                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17872                        app.treatLikeActivity = true;
17873                    }
17874                    final ActivityRecord a = cr.activity;
17875                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17876                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17877                                (a.visible || a.state == ActivityState.RESUMED
17878                                 || a.state == ActivityState.PAUSING)) {
17879                            adj = ProcessList.FOREGROUND_APP_ADJ;
17880                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17881                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17882                            }
17883                            app.cached = false;
17884                            app.adjType = "service";
17885                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17886                                    .REASON_SERVICE_IN_USE;
17887                            app.adjSource = a;
17888                            app.adjSourceProcState = procState;
17889                            app.adjTarget = s.name;
17890                        }
17891                    }
17892                }
17893            }
17894        }
17895
17896        for (int provi = app.pubProviders.size()-1;
17897                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17898                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17899                        || procState > ActivityManager.PROCESS_STATE_TOP);
17900                provi--) {
17901            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17902            for (int i = cpr.connections.size()-1;
17903                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17904                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17905                            || procState > ActivityManager.PROCESS_STATE_TOP);
17906                    i--) {
17907                ContentProviderConnection conn = cpr.connections.get(i);
17908                ProcessRecord client = conn.client;
17909                if (client == app) {
17910                    // Being our own client is not interesting.
17911                    continue;
17912                }
17913                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17914                int clientProcState = client.curProcState;
17915                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17916                    // If the other app is cached for any reason, for purposes here
17917                    // we are going to consider it empty.
17918                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17919                }
17920                if (adj > clientAdj) {
17921                    if (app.hasShownUi && app != mHomeProcess
17922                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17923                        app.adjType = "cch-ui-provider";
17924                    } else {
17925                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17926                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17927                        app.adjType = "provider";
17928                    }
17929                    app.cached &= client.cached;
17930                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17931                            .REASON_PROVIDER_IN_USE;
17932                    app.adjSource = client;
17933                    app.adjSourceProcState = clientProcState;
17934                    app.adjTarget = cpr.name;
17935                }
17936                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17937                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17938                        // Special handling of clients who are in the top state.
17939                        // We *may* want to consider this process to be in the
17940                        // top state as well, but only if there is not another
17941                        // reason for it to be running.  Being on the top is a
17942                        // special state, meaning you are specifically running
17943                        // for the current top app.  If the process is already
17944                        // running in the background for some other reason, it
17945                        // is more important to continue considering it to be
17946                        // in the background state.
17947                        mayBeTop = true;
17948                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17949                    } else {
17950                        // Special handling for above-top states (persistent
17951                        // processes).  These should not bring the current process
17952                        // into the top state, since they are not on top.  Instead
17953                        // give them the best state after that.
17954                        clientProcState =
17955                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
17956                    }
17957                }
17958                if (procState > clientProcState) {
17959                    procState = clientProcState;
17960                }
17961                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17962                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17963                }
17964            }
17965            // If the provider has external (non-framework) process
17966            // dependencies, ensure that its adjustment is at least
17967            // FOREGROUND_APP_ADJ.
17968            if (cpr.hasExternalProcessHandles()) {
17969                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17970                    adj = ProcessList.FOREGROUND_APP_ADJ;
17971                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17972                    app.cached = false;
17973                    app.adjType = "provider";
17974                    app.adjTarget = cpr.name;
17975                }
17976                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17977                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17978                }
17979            }
17980        }
17981
17982        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17983            // A client of one of our services or providers is in the top state.  We
17984            // *may* want to be in the top state, but not if we are already running in
17985            // the background for some other reason.  For the decision here, we are going
17986            // to pick out a few specific states that we want to remain in when a client
17987            // is top (states that tend to be longer-term) and otherwise allow it to go
17988            // to the top state.
17989            switch (procState) {
17990                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17991                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17992                case ActivityManager.PROCESS_STATE_SERVICE:
17993                    // These all are longer-term states, so pull them up to the top
17994                    // of the background states, but not all the way to the top state.
17995                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
17996                    break;
17997                default:
17998                    // Otherwise, top is a better choice, so take it.
17999                    procState = ActivityManager.PROCESS_STATE_TOP;
18000                    break;
18001            }
18002        }
18003
18004        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
18005            if (app.hasClientActivities) {
18006                // This is a cached process, but with client activities.  Mark it so.
18007                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
18008                app.adjType = "cch-client-act";
18009            } else if (app.treatLikeActivity) {
18010                // This is a cached process, but somebody wants us to treat it like it has
18011                // an activity, okay!
18012                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18013                app.adjType = "cch-as-act";
18014            }
18015        }
18016
18017        if (adj == ProcessList.SERVICE_ADJ) {
18018            if (doingAll) {
18019                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
18020                mNewNumServiceProcs++;
18021                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
18022                if (!app.serviceb) {
18023                    // This service isn't far enough down on the LRU list to
18024                    // normally be a B service, but if we are low on RAM and it
18025                    // is large we want to force it down since we would prefer to
18026                    // keep launcher over it.
18027                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
18028                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
18029                        app.serviceHighRam = true;
18030                        app.serviceb = true;
18031                        //Slog.i(TAG, "ADJ " + app + " high ram!");
18032                    } else {
18033                        mNewNumAServiceProcs++;
18034                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
18035                    }
18036                } else {
18037                    app.serviceHighRam = false;
18038                }
18039            }
18040            if (app.serviceb) {
18041                adj = ProcessList.SERVICE_B_ADJ;
18042            }
18043        }
18044
18045        app.curRawAdj = adj;
18046
18047        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
18048        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
18049        if (adj > app.maxAdj) {
18050            adj = app.maxAdj;
18051            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
18052                schedGroup = Process.THREAD_GROUP_DEFAULT;
18053            }
18054        }
18055
18056        // Do final modification to adj.  Everything we do between here and applying
18057        // the final setAdj must be done in this function, because we will also use
18058        // it when computing the final cached adj later.  Note that we don't need to
18059        // worry about this for max adj above, since max adj will always be used to
18060        // keep it out of the cached vaues.
18061        app.curAdj = app.modifyRawOomAdj(adj);
18062        app.curSchedGroup = schedGroup;
18063        app.curProcState = procState;
18064        app.foregroundActivities = foregroundActivities;
18065
18066        return app.curRawAdj;
18067    }
18068
18069    /**
18070     * Record new PSS sample for a process.
18071     */
18072    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long now) {
18073        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024);
18074        proc.lastPssTime = now;
18075        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
18076        if (DEBUG_PSS) Slog.d(TAG_PSS,
18077                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
18078                + " state=" + ProcessList.makeProcStateString(procState));
18079        if (proc.initialIdlePss == 0) {
18080            proc.initialIdlePss = pss;
18081        }
18082        proc.lastPss = pss;
18083        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
18084            proc.lastCachedPss = pss;
18085        }
18086
18087        final SparseArray<Pair<Long, String>> watchUids
18088                = mMemWatchProcesses.getMap().get(proc.processName);
18089        Long check = null;
18090        if (watchUids != null) {
18091            Pair<Long, String> val = watchUids.get(proc.uid);
18092            if (val == null) {
18093                val = watchUids.get(0);
18094            }
18095            if (val != null) {
18096                check = val.first;
18097            }
18098        }
18099        if (check != null) {
18100            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
18101                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18102                if (!isDebuggable) {
18103                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
18104                        isDebuggable = true;
18105                    }
18106                }
18107                if (isDebuggable) {
18108                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
18109                    final ProcessRecord myProc = proc;
18110                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
18111                    mMemWatchDumpProcName = proc.processName;
18112                    mMemWatchDumpFile = heapdumpFile.toString();
18113                    mMemWatchDumpPid = proc.pid;
18114                    mMemWatchDumpUid = proc.uid;
18115                    BackgroundThread.getHandler().post(new Runnable() {
18116                        @Override
18117                        public void run() {
18118                            revokeUriPermission(ActivityThread.currentActivityThread()
18119                                            .getApplicationThread(),
18120                                    DumpHeapActivity.JAVA_URI,
18121                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
18122                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
18123                                    UserHandle.myUserId());
18124                            ParcelFileDescriptor fd = null;
18125                            try {
18126                                heapdumpFile.delete();
18127                                fd = ParcelFileDescriptor.open(heapdumpFile,
18128                                        ParcelFileDescriptor.MODE_CREATE |
18129                                                ParcelFileDescriptor.MODE_TRUNCATE |
18130                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
18131                                                ParcelFileDescriptor.MODE_APPEND);
18132                                IApplicationThread thread = myProc.thread;
18133                                if (thread != null) {
18134                                    try {
18135                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
18136                                                "Requesting dump heap from "
18137                                                + myProc + " to " + heapdumpFile);
18138                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
18139                                    } catch (RemoteException e) {
18140                                    }
18141                                }
18142                            } catch (FileNotFoundException e) {
18143                                e.printStackTrace();
18144                            } finally {
18145                                if (fd != null) {
18146                                    try {
18147                                        fd.close();
18148                                    } catch (IOException e) {
18149                                    }
18150                                }
18151                            }
18152                        }
18153                    });
18154                } else {
18155                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
18156                            + ", but debugging not enabled");
18157                }
18158            }
18159        }
18160    }
18161
18162    /**
18163     * Schedule PSS collection of a process.
18164     */
18165    void requestPssLocked(ProcessRecord proc, int procState) {
18166        if (mPendingPssProcesses.contains(proc)) {
18167            return;
18168        }
18169        if (mPendingPssProcesses.size() == 0) {
18170            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18171        }
18172        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
18173        proc.pssProcState = procState;
18174        mPendingPssProcesses.add(proc);
18175    }
18176
18177    /**
18178     * Schedule PSS collection of all processes.
18179     */
18180    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
18181        if (!always) {
18182            if (now < (mLastFullPssTime +
18183                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
18184                return;
18185            }
18186        }
18187        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
18188        mLastFullPssTime = now;
18189        mFullPssPending = true;
18190        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
18191        mPendingPssProcesses.clear();
18192        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18193            ProcessRecord app = mLruProcesses.get(i);
18194            if (app.thread == null
18195                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
18196                continue;
18197            }
18198            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
18199                app.pssProcState = app.setProcState;
18200                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18201                        mTestPssMode, isSleeping(), now);
18202                mPendingPssProcesses.add(app);
18203            }
18204        }
18205        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18206    }
18207
18208    public void setTestPssMode(boolean enabled) {
18209        synchronized (this) {
18210            mTestPssMode = enabled;
18211            if (enabled) {
18212                // Whenever we enable the mode, we want to take a snapshot all of current
18213                // process mem use.
18214                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
18215            }
18216        }
18217    }
18218
18219    /**
18220     * Ask a given process to GC right now.
18221     */
18222    final void performAppGcLocked(ProcessRecord app) {
18223        try {
18224            app.lastRequestedGc = SystemClock.uptimeMillis();
18225            if (app.thread != null) {
18226                if (app.reportLowMemory) {
18227                    app.reportLowMemory = false;
18228                    app.thread.scheduleLowMemory();
18229                } else {
18230                    app.thread.processInBackground();
18231                }
18232            }
18233        } catch (Exception e) {
18234            // whatever.
18235        }
18236    }
18237
18238    /**
18239     * Returns true if things are idle enough to perform GCs.
18240     */
18241    private final boolean canGcNowLocked() {
18242        boolean processingBroadcasts = false;
18243        for (BroadcastQueue q : mBroadcastQueues) {
18244            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
18245                processingBroadcasts = true;
18246            }
18247        }
18248        return !processingBroadcasts
18249                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
18250    }
18251
18252    /**
18253     * Perform GCs on all processes that are waiting for it, but only
18254     * if things are idle.
18255     */
18256    final void performAppGcsLocked() {
18257        final int N = mProcessesToGc.size();
18258        if (N <= 0) {
18259            return;
18260        }
18261        if (canGcNowLocked()) {
18262            while (mProcessesToGc.size() > 0) {
18263                ProcessRecord proc = mProcessesToGc.remove(0);
18264                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
18265                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
18266                            <= SystemClock.uptimeMillis()) {
18267                        // To avoid spamming the system, we will GC processes one
18268                        // at a time, waiting a few seconds between each.
18269                        performAppGcLocked(proc);
18270                        scheduleAppGcsLocked();
18271                        return;
18272                    } else {
18273                        // It hasn't been long enough since we last GCed this
18274                        // process...  put it in the list to wait for its time.
18275                        addProcessToGcListLocked(proc);
18276                        break;
18277                    }
18278                }
18279            }
18280
18281            scheduleAppGcsLocked();
18282        }
18283    }
18284
18285    /**
18286     * If all looks good, perform GCs on all processes waiting for them.
18287     */
18288    final void performAppGcsIfAppropriateLocked() {
18289        if (canGcNowLocked()) {
18290            performAppGcsLocked();
18291            return;
18292        }
18293        // Still not idle, wait some more.
18294        scheduleAppGcsLocked();
18295    }
18296
18297    /**
18298     * Schedule the execution of all pending app GCs.
18299     */
18300    final void scheduleAppGcsLocked() {
18301        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
18302
18303        if (mProcessesToGc.size() > 0) {
18304            // Schedule a GC for the time to the next process.
18305            ProcessRecord proc = mProcessesToGc.get(0);
18306            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
18307
18308            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
18309            long now = SystemClock.uptimeMillis();
18310            if (when < (now+GC_TIMEOUT)) {
18311                when = now + GC_TIMEOUT;
18312            }
18313            mHandler.sendMessageAtTime(msg, when);
18314        }
18315    }
18316
18317    /**
18318     * Add a process to the array of processes waiting to be GCed.  Keeps the
18319     * list in sorted order by the last GC time.  The process can't already be
18320     * on the list.
18321     */
18322    final void addProcessToGcListLocked(ProcessRecord proc) {
18323        boolean added = false;
18324        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
18325            if (mProcessesToGc.get(i).lastRequestedGc <
18326                    proc.lastRequestedGc) {
18327                added = true;
18328                mProcessesToGc.add(i+1, proc);
18329                break;
18330            }
18331        }
18332        if (!added) {
18333            mProcessesToGc.add(0, proc);
18334        }
18335    }
18336
18337    /**
18338     * Set up to ask a process to GC itself.  This will either do it
18339     * immediately, or put it on the list of processes to gc the next
18340     * time things are idle.
18341     */
18342    final void scheduleAppGcLocked(ProcessRecord app) {
18343        long now = SystemClock.uptimeMillis();
18344        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
18345            return;
18346        }
18347        if (!mProcessesToGc.contains(app)) {
18348            addProcessToGcListLocked(app);
18349            scheduleAppGcsLocked();
18350        }
18351    }
18352
18353    final void checkExcessivePowerUsageLocked(boolean doKills) {
18354        updateCpuStatsNow();
18355
18356        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18357        boolean doWakeKills = doKills;
18358        boolean doCpuKills = doKills;
18359        if (mLastPowerCheckRealtime == 0) {
18360            doWakeKills = false;
18361        }
18362        if (mLastPowerCheckUptime == 0) {
18363            doCpuKills = false;
18364        }
18365        if (stats.isScreenOn()) {
18366            doWakeKills = false;
18367        }
18368        final long curRealtime = SystemClock.elapsedRealtime();
18369        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
18370        final long curUptime = SystemClock.uptimeMillis();
18371        final long uptimeSince = curUptime - mLastPowerCheckUptime;
18372        mLastPowerCheckRealtime = curRealtime;
18373        mLastPowerCheckUptime = curUptime;
18374        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
18375            doWakeKills = false;
18376        }
18377        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
18378            doCpuKills = false;
18379        }
18380        int i = mLruProcesses.size();
18381        while (i > 0) {
18382            i--;
18383            ProcessRecord app = mLruProcesses.get(i);
18384            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18385                long wtime;
18386                synchronized (stats) {
18387                    wtime = stats.getProcessWakeTime(app.info.uid,
18388                            app.pid, curRealtime);
18389                }
18390                long wtimeUsed = wtime - app.lastWakeTime;
18391                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
18392                if (DEBUG_POWER) {
18393                    StringBuilder sb = new StringBuilder(128);
18394                    sb.append("Wake for ");
18395                    app.toShortString(sb);
18396                    sb.append(": over ");
18397                    TimeUtils.formatDuration(realtimeSince, sb);
18398                    sb.append(" used ");
18399                    TimeUtils.formatDuration(wtimeUsed, sb);
18400                    sb.append(" (");
18401                    sb.append((wtimeUsed*100)/realtimeSince);
18402                    sb.append("%)");
18403                    Slog.i(TAG_POWER, sb.toString());
18404                    sb.setLength(0);
18405                    sb.append("CPU for ");
18406                    app.toShortString(sb);
18407                    sb.append(": over ");
18408                    TimeUtils.formatDuration(uptimeSince, sb);
18409                    sb.append(" used ");
18410                    TimeUtils.formatDuration(cputimeUsed, sb);
18411                    sb.append(" (");
18412                    sb.append((cputimeUsed*100)/uptimeSince);
18413                    sb.append("%)");
18414                    Slog.i(TAG_POWER, sb.toString());
18415                }
18416                // If a process has held a wake lock for more
18417                // than 50% of the time during this period,
18418                // that sounds bad.  Kill!
18419                if (doWakeKills && realtimeSince > 0
18420                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
18421                    synchronized (stats) {
18422                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
18423                                realtimeSince, wtimeUsed);
18424                    }
18425                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
18426                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
18427                } else if (doCpuKills && uptimeSince > 0
18428                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
18429                    synchronized (stats) {
18430                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
18431                                uptimeSince, cputimeUsed);
18432                    }
18433                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
18434                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
18435                } else {
18436                    app.lastWakeTime = wtime;
18437                    app.lastCpuTime = app.curCpuTime;
18438                }
18439            }
18440        }
18441    }
18442
18443    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now) {
18444        boolean success = true;
18445
18446        if (app.curRawAdj != app.setRawAdj) {
18447            app.setRawAdj = app.curRawAdj;
18448        }
18449
18450        int changes = 0;
18451
18452        if (app.curAdj != app.setAdj) {
18453            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
18454            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18455                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
18456                    + app.adjType);
18457            app.setAdj = app.curAdj;
18458        }
18459
18460        if (app.setSchedGroup != app.curSchedGroup) {
18461            app.setSchedGroup = app.curSchedGroup;
18462            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18463                    "Setting process group of " + app.processName
18464                    + " to " + app.curSchedGroup);
18465            if (app.waitingToKill != null && app.curReceiver == null
18466                    && app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
18467                app.kill(app.waitingToKill, true);
18468                success = false;
18469            } else {
18470                if (true) {
18471                    long oldId = Binder.clearCallingIdentity();
18472                    try {
18473                        Process.setProcessGroup(app.pid, app.curSchedGroup);
18474                    } catch (Exception e) {
18475                        Slog.w(TAG, "Failed setting process group of " + app.pid
18476                                + " to " + app.curSchedGroup);
18477                        e.printStackTrace();
18478                    } finally {
18479                        Binder.restoreCallingIdentity(oldId);
18480                    }
18481                } else {
18482                    if (app.thread != null) {
18483                        try {
18484                            app.thread.setSchedulingGroup(app.curSchedGroup);
18485                        } catch (RemoteException e) {
18486                        }
18487                    }
18488                }
18489                Process.setSwappiness(app.pid,
18490                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
18491            }
18492        }
18493        if (app.repForegroundActivities != app.foregroundActivities) {
18494            app.repForegroundActivities = app.foregroundActivities;
18495            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
18496        }
18497        if (app.repProcState != app.curProcState) {
18498            app.repProcState = app.curProcState;
18499            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
18500            if (app.thread != null) {
18501                try {
18502                    if (false) {
18503                        //RuntimeException h = new RuntimeException("here");
18504                        Slog.i(TAG, "Sending new process state " + app.repProcState
18505                                + " to " + app /*, h*/);
18506                    }
18507                    app.thread.setProcessState(app.repProcState);
18508                } catch (RemoteException e) {
18509                }
18510            }
18511        }
18512        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
18513                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
18514            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
18515                // Experimental code to more aggressively collect pss while
18516                // running test...  the problem is that this tends to collect
18517                // the data right when a process is transitioning between process
18518                // states, which well tend to give noisy data.
18519                long start = SystemClock.uptimeMillis();
18520                long pss = Debug.getPss(app.pid, mTmpLong, null);
18521                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], now);
18522                mPendingPssProcesses.remove(app);
18523                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
18524                        + " to " + app.curProcState + ": "
18525                        + (SystemClock.uptimeMillis()-start) + "ms");
18526            }
18527            app.lastStateTime = now;
18528            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18529                    mTestPssMode, isSleeping(), now);
18530            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
18531                    + ProcessList.makeProcStateString(app.setProcState) + " to "
18532                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
18533                    + (app.nextPssTime-now) + ": " + app);
18534        } else {
18535            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
18536                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
18537                    mTestPssMode)))) {
18538                requestPssLocked(app, app.setProcState);
18539                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
18540                        mTestPssMode, isSleeping(), now);
18541            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
18542                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
18543        }
18544        if (app.setProcState != app.curProcState) {
18545            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18546                    "Proc state change of " + app.processName
18547                    + " to " + app.curProcState);
18548            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
18549            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
18550            if (setImportant && !curImportant) {
18551                // This app is no longer something we consider important enough to allow to
18552                // use arbitrary amounts of battery power.  Note
18553                // its current wake lock time to later know to kill it if
18554                // it is not behaving well.
18555                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18556                synchronized (stats) {
18557                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
18558                            app.pid, SystemClock.elapsedRealtime());
18559                }
18560                app.lastCpuTime = app.curCpuTime;
18561
18562            }
18563            // Inform UsageStats of important process state change
18564            // Must be called before updating setProcState
18565            maybeUpdateUsageStatsLocked(app);
18566
18567            app.setProcState = app.curProcState;
18568            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18569                app.notCachedSinceIdle = false;
18570            }
18571            if (!doingAll) {
18572                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
18573            } else {
18574                app.procStateChanged = true;
18575            }
18576        }
18577
18578        if (changes != 0) {
18579            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18580                    "Changes in " + app + ": " + changes);
18581            int i = mPendingProcessChanges.size()-1;
18582            ProcessChangeItem item = null;
18583            while (i >= 0) {
18584                item = mPendingProcessChanges.get(i);
18585                if (item.pid == app.pid) {
18586                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18587                            "Re-using existing item: " + item);
18588                    break;
18589                }
18590                i--;
18591            }
18592            if (i < 0) {
18593                // No existing item in pending changes; need a new one.
18594                final int NA = mAvailProcessChanges.size();
18595                if (NA > 0) {
18596                    item = mAvailProcessChanges.remove(NA-1);
18597                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18598                            "Retrieving available item: " + item);
18599                } else {
18600                    item = new ProcessChangeItem();
18601                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18602                            "Allocating new item: " + item);
18603                }
18604                item.changes = 0;
18605                item.pid = app.pid;
18606                item.uid = app.info.uid;
18607                if (mPendingProcessChanges.size() == 0) {
18608                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18609                            "*** Enqueueing dispatch processes changed!");
18610                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
18611                }
18612                mPendingProcessChanges.add(item);
18613            }
18614            item.changes |= changes;
18615            item.processState = app.repProcState;
18616            item.foregroundActivities = app.repForegroundActivities;
18617            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18618                    "Item " + Integer.toHexString(System.identityHashCode(item))
18619                    + " " + app.toShortString() + ": changes=" + item.changes
18620                    + " procState=" + item.processState
18621                    + " foreground=" + item.foregroundActivities
18622                    + " type=" + app.adjType + " source=" + app.adjSource
18623                    + " target=" + app.adjTarget);
18624        }
18625
18626        return success;
18627    }
18628
18629    private final void enqueueUidChangeLocked(UidRecord uidRec, boolean gone) {
18630        if (uidRec.pendingChange == null) {
18631            if (mPendingUidChanges.size() == 0) {
18632                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18633                        "*** Enqueueing dispatch uid changed!");
18634                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_MSG).sendToTarget();
18635            }
18636            final int NA = mAvailUidChanges.size();
18637            if (NA > 0) {
18638                uidRec.pendingChange = mAvailUidChanges.remove(NA-1);
18639                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18640                        "Retrieving available item: " + uidRec.pendingChange);
18641            } else {
18642                uidRec.pendingChange = new UidRecord.ChangeItem();
18643                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18644                        "Allocating new item: " + uidRec.pendingChange);
18645            }
18646            uidRec.pendingChange.uidRecord = uidRec;
18647            uidRec.pendingChange.uid = uidRec.uid;
18648            mPendingUidChanges.add(uidRec.pendingChange);
18649        }
18650        uidRec.pendingChange.gone = gone;
18651        uidRec.pendingChange.processState = uidRec.setProcState;
18652    }
18653
18654    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
18655            String authority) {
18656        if (app == null) return;
18657        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18658            UserState userState = mStartedUsers.get(app.userId);
18659            if (userState == null) return;
18660            final long now = SystemClock.elapsedRealtime();
18661            Long lastReported = userState.mProviderLastReportedFg.get(authority);
18662            if (lastReported == null || lastReported < now - 60 * 1000L) {
18663                mUsageStatsService.reportContentProviderUsage(
18664                        authority, providerPkgName, app.userId);
18665                userState.mProviderLastReportedFg.put(authority, now);
18666            }
18667        }
18668    }
18669
18670    private void maybeUpdateUsageStatsLocked(ProcessRecord app) {
18671        if (DEBUG_USAGE_STATS) {
18672            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
18673                    + "] state changes: old = " + app.setProcState + ", new = "
18674                    + app.curProcState);
18675        }
18676        if (mUsageStatsService == null) {
18677            return;
18678        }
18679        boolean isInteraction;
18680        // To avoid some abuse patterns, we are going to be careful about what we consider
18681        // to be an app interaction.  Being the top activity doesn't count while the display
18682        // is sleeping, nor do short foreground services.
18683        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
18684            isInteraction = true;
18685            app.fgInteractionTime = 0;
18686        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
18687            final long now = SystemClock.elapsedRealtime();
18688            if (app.fgInteractionTime == 0) {
18689                app.fgInteractionTime = now;
18690                isInteraction = false;
18691            } else {
18692                isInteraction = now > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
18693            }
18694        } else {
18695            isInteraction = app.curProcState
18696                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18697            app.fgInteractionTime = 0;
18698        }
18699        if (isInteraction && !app.reportedInteraction) {
18700            String[] packages = app.getPackageList();
18701            if (packages != null) {
18702                for (int i = 0; i < packages.length; i++) {
18703                    mUsageStatsService.reportEvent(packages[i], app.userId,
18704                            UsageEvents.Event.SYSTEM_INTERACTION);
18705                }
18706            }
18707        }
18708        app.reportedInteraction = isInteraction;
18709    }
18710
18711    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
18712        if (proc.thread != null) {
18713            if (proc.baseProcessTracker != null) {
18714                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
18715            }
18716            if (proc.repProcState >= 0) {
18717                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
18718                        proc.repProcState);
18719            }
18720        }
18721    }
18722
18723    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
18724            ProcessRecord TOP_APP, boolean doingAll, long now) {
18725        if (app.thread == null) {
18726            return false;
18727        }
18728
18729        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
18730
18731        return applyOomAdjLocked(app, doingAll, now);
18732    }
18733
18734    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
18735            boolean oomAdj) {
18736        if (isForeground != proc.foregroundServices) {
18737            proc.foregroundServices = isForeground;
18738            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
18739                    proc.info.uid);
18740            if (isForeground) {
18741                if (curProcs == null) {
18742                    curProcs = new ArrayList<ProcessRecord>();
18743                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
18744                }
18745                if (!curProcs.contains(proc)) {
18746                    curProcs.add(proc);
18747                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
18748                            proc.info.packageName, proc.info.uid);
18749                }
18750            } else {
18751                if (curProcs != null) {
18752                    if (curProcs.remove(proc)) {
18753                        mBatteryStatsService.noteEvent(
18754                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
18755                                proc.info.packageName, proc.info.uid);
18756                        if (curProcs.size() <= 0) {
18757                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
18758                        }
18759                    }
18760                }
18761            }
18762            if (oomAdj) {
18763                updateOomAdjLocked();
18764            }
18765        }
18766    }
18767
18768    private final ActivityRecord resumedAppLocked() {
18769        ActivityRecord act = mStackSupervisor.resumedAppLocked();
18770        String pkg;
18771        int uid;
18772        if (act != null) {
18773            pkg = act.packageName;
18774            uid = act.info.applicationInfo.uid;
18775        } else {
18776            pkg = null;
18777            uid = -1;
18778        }
18779        // Has the UID or resumed package name changed?
18780        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
18781                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
18782            if (mCurResumedPackage != null) {
18783                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
18784                        mCurResumedPackage, mCurResumedUid);
18785            }
18786            mCurResumedPackage = pkg;
18787            mCurResumedUid = uid;
18788            if (mCurResumedPackage != null) {
18789                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
18790                        mCurResumedPackage, mCurResumedUid);
18791            }
18792        }
18793        return act;
18794    }
18795
18796    final boolean updateOomAdjLocked(ProcessRecord app) {
18797        final ActivityRecord TOP_ACT = resumedAppLocked();
18798        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18799        final boolean wasCached = app.cached;
18800
18801        mAdjSeq++;
18802
18803        // This is the desired cached adjusment we want to tell it to use.
18804        // If our app is currently cached, we know it, and that is it.  Otherwise,
18805        // we don't know it yet, and it needs to now be cached we will then
18806        // need to do a complete oom adj.
18807        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
18808                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
18809        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
18810                SystemClock.uptimeMillis());
18811        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
18812            // Changed to/from cached state, so apps after it in the LRU
18813            // list may also be changed.
18814            updateOomAdjLocked();
18815        }
18816        return success;
18817    }
18818
18819    final void updateOomAdjLocked() {
18820        final ActivityRecord TOP_ACT = resumedAppLocked();
18821        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18822        final long now = SystemClock.uptimeMillis();
18823        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
18824        final int N = mLruProcesses.size();
18825
18826        if (false) {
18827            RuntimeException e = new RuntimeException();
18828            e.fillInStackTrace();
18829            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
18830        }
18831
18832        // Reset state in all uid records.
18833        for (int i=mActiveUids.size()-1; i>=0; i--) {
18834            final UidRecord uidRec = mActiveUids.valueAt(i);
18835            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18836                    "Starting update of " + uidRec);
18837            uidRec.reset();
18838        }
18839
18840        mAdjSeq++;
18841        mNewNumServiceProcs = 0;
18842        mNewNumAServiceProcs = 0;
18843
18844        final int emptyProcessLimit;
18845        final int cachedProcessLimit;
18846        if (mProcessLimit <= 0) {
18847            emptyProcessLimit = cachedProcessLimit = 0;
18848        } else if (mProcessLimit == 1) {
18849            emptyProcessLimit = 1;
18850            cachedProcessLimit = 0;
18851        } else {
18852            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
18853            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
18854        }
18855
18856        // Let's determine how many processes we have running vs.
18857        // how many slots we have for background processes; we may want
18858        // to put multiple processes in a slot of there are enough of
18859        // them.
18860        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
18861                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
18862        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
18863        if (numEmptyProcs > cachedProcessLimit) {
18864            // If there are more empty processes than our limit on cached
18865            // processes, then use the cached process limit for the factor.
18866            // This ensures that the really old empty processes get pushed
18867            // down to the bottom, so if we are running low on memory we will
18868            // have a better chance at keeping around more cached processes
18869            // instead of a gazillion empty processes.
18870            numEmptyProcs = cachedProcessLimit;
18871        }
18872        int emptyFactor = numEmptyProcs/numSlots;
18873        if (emptyFactor < 1) emptyFactor = 1;
18874        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
18875        if (cachedFactor < 1) cachedFactor = 1;
18876        int stepCached = 0;
18877        int stepEmpty = 0;
18878        int numCached = 0;
18879        int numEmpty = 0;
18880        int numTrimming = 0;
18881
18882        mNumNonCachedProcs = 0;
18883        mNumCachedHiddenProcs = 0;
18884
18885        // First update the OOM adjustment for each of the
18886        // application processes based on their current state.
18887        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
18888        int nextCachedAdj = curCachedAdj+1;
18889        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
18890        int nextEmptyAdj = curEmptyAdj+2;
18891        for (int i=N-1; i>=0; i--) {
18892            ProcessRecord app = mLruProcesses.get(i);
18893            if (!app.killedByAm && app.thread != null) {
18894                app.procStateChanged = false;
18895                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
18896
18897                // If we haven't yet assigned the final cached adj
18898                // to the process, do that now.
18899                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
18900                    switch (app.curProcState) {
18901                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18902                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18903                            // This process is a cached process holding activities...
18904                            // assign it the next cached value for that type, and then
18905                            // step that cached level.
18906                            app.curRawAdj = curCachedAdj;
18907                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
18908                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
18909                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
18910                                    + ")");
18911                            if (curCachedAdj != nextCachedAdj) {
18912                                stepCached++;
18913                                if (stepCached >= cachedFactor) {
18914                                    stepCached = 0;
18915                                    curCachedAdj = nextCachedAdj;
18916                                    nextCachedAdj += 2;
18917                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18918                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
18919                                    }
18920                                }
18921                            }
18922                            break;
18923                        default:
18924                            // For everything else, assign next empty cached process
18925                            // level and bump that up.  Note that this means that
18926                            // long-running services that have dropped down to the
18927                            // cached level will be treated as empty (since their process
18928                            // state is still as a service), which is what we want.
18929                            app.curRawAdj = curEmptyAdj;
18930                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
18931                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
18932                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
18933                                    + ")");
18934                            if (curEmptyAdj != nextEmptyAdj) {
18935                                stepEmpty++;
18936                                if (stepEmpty >= emptyFactor) {
18937                                    stepEmpty = 0;
18938                                    curEmptyAdj = nextEmptyAdj;
18939                                    nextEmptyAdj += 2;
18940                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18941                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
18942                                    }
18943                                }
18944                            }
18945                            break;
18946                    }
18947                }
18948
18949                applyOomAdjLocked(app, true, now);
18950
18951                // Count the number of process types.
18952                switch (app.curProcState) {
18953                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18954                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18955                        mNumCachedHiddenProcs++;
18956                        numCached++;
18957                        if (numCached > cachedProcessLimit) {
18958                            app.kill("cached #" + numCached, true);
18959                        }
18960                        break;
18961                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
18962                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
18963                                && app.lastActivityTime < oldTime) {
18964                            app.kill("empty for "
18965                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
18966                                    / 1000) + "s", true);
18967                        } else {
18968                            numEmpty++;
18969                            if (numEmpty > emptyProcessLimit) {
18970                                app.kill("empty #" + numEmpty, true);
18971                            }
18972                        }
18973                        break;
18974                    default:
18975                        mNumNonCachedProcs++;
18976                        break;
18977                }
18978
18979                if (app.isolated && app.services.size() <= 0) {
18980                    // If this is an isolated process, and there are no
18981                    // services running in it, then the process is no longer
18982                    // needed.  We agressively kill these because we can by
18983                    // definition not re-use the same process again, and it is
18984                    // good to avoid having whatever code was running in them
18985                    // left sitting around after no longer needed.
18986                    app.kill("isolated not needed", true);
18987                } else {
18988                    // Keeping this process, update its uid.
18989                    final UidRecord uidRec = app.uidRecord;
18990                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
18991                        uidRec.curProcState = app.curProcState;
18992                    }
18993                }
18994
18995                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18996                        && !app.killedByAm) {
18997                    numTrimming++;
18998                }
18999            }
19000        }
19001
19002        mNumServiceProcs = mNewNumServiceProcs;
19003
19004        // Now determine the memory trimming level of background processes.
19005        // Unfortunately we need to start at the back of the list to do this
19006        // properly.  We only do this if the number of background apps we
19007        // are managing to keep around is less than half the maximum we desire;
19008        // if we are keeping a good number around, we'll let them use whatever
19009        // memory they want.
19010        final int numCachedAndEmpty = numCached + numEmpty;
19011        int memFactor;
19012        if (numCached <= ProcessList.TRIM_CACHED_APPS
19013                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
19014            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
19015                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
19016            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
19017                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
19018            } else {
19019                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
19020            }
19021        } else {
19022            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
19023        }
19024        // We always allow the memory level to go up (better).  We only allow it to go
19025        // down if we are in a state where that is allowed, *and* the total number of processes
19026        // has gone down since last time.
19027        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
19028                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
19029                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
19030        if (memFactor > mLastMemoryLevel) {
19031            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
19032                memFactor = mLastMemoryLevel;
19033                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
19034            }
19035        }
19036        mLastMemoryLevel = memFactor;
19037        mLastNumProcesses = mLruProcesses.size();
19038        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
19039        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
19040        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
19041            if (mLowRamStartTime == 0) {
19042                mLowRamStartTime = now;
19043            }
19044            int step = 0;
19045            int fgTrimLevel;
19046            switch (memFactor) {
19047                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
19048                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
19049                    break;
19050                case ProcessStats.ADJ_MEM_FACTOR_LOW:
19051                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
19052                    break;
19053                default:
19054                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
19055                    break;
19056            }
19057            int factor = numTrimming/3;
19058            int minFactor = 2;
19059            if (mHomeProcess != null) minFactor++;
19060            if (mPreviousProcess != null) minFactor++;
19061            if (factor < minFactor) factor = minFactor;
19062            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
19063            for (int i=N-1; i>=0; i--) {
19064                ProcessRecord app = mLruProcesses.get(i);
19065                if (allChanged || app.procStateChanged) {
19066                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
19067                    app.procStateChanged = false;
19068                }
19069                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19070                        && !app.killedByAm) {
19071                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
19072                        try {
19073                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19074                                    "Trimming memory of " + app.processName + " to " + curLevel);
19075                            app.thread.scheduleTrimMemory(curLevel);
19076                        } catch (RemoteException e) {
19077                        }
19078                        if (false) {
19079                            // For now we won't do this; our memory trimming seems
19080                            // to be good enough at this point that destroying
19081                            // activities causes more harm than good.
19082                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
19083                                    && app != mHomeProcess && app != mPreviousProcess) {
19084                                // Need to do this on its own message because the stack may not
19085                                // be in a consistent state at this point.
19086                                // For these apps we will also finish their activities
19087                                // to help them free memory.
19088                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
19089                            }
19090                        }
19091                    }
19092                    app.trimMemoryLevel = curLevel;
19093                    step++;
19094                    if (step >= factor) {
19095                        step = 0;
19096                        switch (curLevel) {
19097                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
19098                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
19099                                break;
19100                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
19101                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19102                                break;
19103                        }
19104                    }
19105                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19106                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
19107                            && app.thread != null) {
19108                        try {
19109                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19110                                    "Trimming memory of heavy-weight " + app.processName
19111                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19112                            app.thread.scheduleTrimMemory(
19113                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19114                        } catch (RemoteException e) {
19115                        }
19116                    }
19117                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19118                } else {
19119                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19120                            || app.systemNoUi) && app.pendingUiClean) {
19121                        // If this application is now in the background and it
19122                        // had done UI, then give it the special trim level to
19123                        // have it free UI resources.
19124                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
19125                        if (app.trimMemoryLevel < level && app.thread != null) {
19126                            try {
19127                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19128                                        "Trimming memory of bg-ui " + app.processName
19129                                        + " to " + level);
19130                                app.thread.scheduleTrimMemory(level);
19131                            } catch (RemoteException e) {
19132                            }
19133                        }
19134                        app.pendingUiClean = false;
19135                    }
19136                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
19137                        try {
19138                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19139                                    "Trimming memory of fg " + app.processName
19140                                    + " to " + fgTrimLevel);
19141                            app.thread.scheduleTrimMemory(fgTrimLevel);
19142                        } catch (RemoteException e) {
19143                        }
19144                    }
19145                    app.trimMemoryLevel = fgTrimLevel;
19146                }
19147            }
19148        } else {
19149            if (mLowRamStartTime != 0) {
19150                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
19151                mLowRamStartTime = 0;
19152            }
19153            for (int i=N-1; i>=0; i--) {
19154                ProcessRecord app = mLruProcesses.get(i);
19155                if (allChanged || app.procStateChanged) {
19156                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
19157                    app.procStateChanged = false;
19158                }
19159                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19160                        || app.systemNoUi) && app.pendingUiClean) {
19161                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
19162                            && app.thread != null) {
19163                        try {
19164                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19165                                    "Trimming memory of ui hidden " + app.processName
19166                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19167                            app.thread.scheduleTrimMemory(
19168                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19169                        } catch (RemoteException e) {
19170                        }
19171                    }
19172                    app.pendingUiClean = false;
19173                }
19174                app.trimMemoryLevel = 0;
19175            }
19176        }
19177
19178        if (mAlwaysFinishActivities) {
19179            // Need to do this on its own message because the stack may not
19180            // be in a consistent state at this point.
19181            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
19182        }
19183
19184        if (allChanged) {
19185            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
19186        }
19187
19188        // Update from any uid changes.
19189        for (int i=mActiveUids.size()-1; i>=0; i--) {
19190            final UidRecord uidRec = mActiveUids.valueAt(i);
19191            if (uidRec.setProcState != uidRec.curProcState) {
19192                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19193                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
19194                        + " to " + uidRec.curProcState);
19195                uidRec.setProcState = uidRec.curProcState;
19196                enqueueUidChangeLocked(uidRec, false);
19197            }
19198        }
19199
19200        if (mProcessStats.shouldWriteNowLocked(now)) {
19201            mHandler.post(new Runnable() {
19202                @Override public void run() {
19203                    synchronized (ActivityManagerService.this) {
19204                        mProcessStats.writeStateAsyncLocked();
19205                    }
19206                }
19207            });
19208        }
19209
19210        if (DEBUG_OOM_ADJ) {
19211            final long duration = SystemClock.uptimeMillis() - now;
19212            if (false) {
19213                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
19214                        new RuntimeException("here").fillInStackTrace());
19215            } else {
19216                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
19217            }
19218        }
19219    }
19220
19221    final void trimApplications() {
19222        synchronized (this) {
19223            int i;
19224
19225            // First remove any unused application processes whose package
19226            // has been removed.
19227            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
19228                final ProcessRecord app = mRemovedProcesses.get(i);
19229                if (app.activities.size() == 0
19230                        && app.curReceiver == null && app.services.size() == 0) {
19231                    Slog.i(
19232                        TAG, "Exiting empty application process "
19233                        + app.processName + " ("
19234                        + (app.thread != null ? app.thread.asBinder() : null)
19235                        + ")\n");
19236                    if (app.pid > 0 && app.pid != MY_PID) {
19237                        app.kill("empty", false);
19238                    } else {
19239                        try {
19240                            app.thread.scheduleExit();
19241                        } catch (Exception e) {
19242                            // Ignore exceptions.
19243                        }
19244                    }
19245                    cleanUpApplicationRecordLocked(app, false, true, -1);
19246                    mRemovedProcesses.remove(i);
19247
19248                    if (app.persistent) {
19249                        addAppLocked(app.info, false, null /* ABI override */);
19250                    }
19251                }
19252            }
19253
19254            // Now update the oom adj for all processes.
19255            updateOomAdjLocked();
19256        }
19257    }
19258
19259    /** This method sends the specified signal to each of the persistent apps */
19260    public void signalPersistentProcesses(int sig) throws RemoteException {
19261        if (sig != Process.SIGNAL_USR1) {
19262            throw new SecurityException("Only SIGNAL_USR1 is allowed");
19263        }
19264
19265        synchronized (this) {
19266            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
19267                    != PackageManager.PERMISSION_GRANTED) {
19268                throw new SecurityException("Requires permission "
19269                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
19270            }
19271
19272            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
19273                ProcessRecord r = mLruProcesses.get(i);
19274                if (r.thread != null && r.persistent) {
19275                    Process.sendSignal(r.pid, sig);
19276                }
19277            }
19278        }
19279    }
19280
19281    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
19282        if (proc == null || proc == mProfileProc) {
19283            proc = mProfileProc;
19284            profileType = mProfileType;
19285            clearProfilerLocked();
19286        }
19287        if (proc == null) {
19288            return;
19289        }
19290        try {
19291            proc.thread.profilerControl(false, null, profileType);
19292        } catch (RemoteException e) {
19293            throw new IllegalStateException("Process disappeared");
19294        }
19295    }
19296
19297    private void clearProfilerLocked() {
19298        if (mProfileFd != null) {
19299            try {
19300                mProfileFd.close();
19301            } catch (IOException e) {
19302            }
19303        }
19304        mProfileApp = null;
19305        mProfileProc = null;
19306        mProfileFile = null;
19307        mProfileType = 0;
19308        mAutoStopProfiler = false;
19309        mSamplingInterval = 0;
19310    }
19311
19312    public boolean profileControl(String process, int userId, boolean start,
19313            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
19314
19315        try {
19316            synchronized (this) {
19317                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19318                // its own permission.
19319                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19320                        != PackageManager.PERMISSION_GRANTED) {
19321                    throw new SecurityException("Requires permission "
19322                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19323                }
19324
19325                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
19326                    throw new IllegalArgumentException("null profile info or fd");
19327                }
19328
19329                ProcessRecord proc = null;
19330                if (process != null) {
19331                    proc = findProcessLocked(process, userId, "profileControl");
19332                }
19333
19334                if (start && (proc == null || proc.thread == null)) {
19335                    throw new IllegalArgumentException("Unknown process: " + process);
19336                }
19337
19338                if (start) {
19339                    stopProfilerLocked(null, 0);
19340                    setProfileApp(proc.info, proc.processName, profilerInfo);
19341                    mProfileProc = proc;
19342                    mProfileType = profileType;
19343                    ParcelFileDescriptor fd = profilerInfo.profileFd;
19344                    try {
19345                        fd = fd.dup();
19346                    } catch (IOException e) {
19347                        fd = null;
19348                    }
19349                    profilerInfo.profileFd = fd;
19350                    proc.thread.profilerControl(start, profilerInfo, profileType);
19351                    fd = null;
19352                    mProfileFd = null;
19353                } else {
19354                    stopProfilerLocked(proc, profileType);
19355                    if (profilerInfo != null && profilerInfo.profileFd != null) {
19356                        try {
19357                            profilerInfo.profileFd.close();
19358                        } catch (IOException e) {
19359                        }
19360                    }
19361                }
19362
19363                return true;
19364            }
19365        } catch (RemoteException e) {
19366            throw new IllegalStateException("Process disappeared");
19367        } finally {
19368            if (profilerInfo != null && profilerInfo.profileFd != null) {
19369                try {
19370                    profilerInfo.profileFd.close();
19371                } catch (IOException e) {
19372                }
19373            }
19374        }
19375    }
19376
19377    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
19378        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19379                userId, true, ALLOW_FULL_ONLY, callName, null);
19380        ProcessRecord proc = null;
19381        try {
19382            int pid = Integer.parseInt(process);
19383            synchronized (mPidsSelfLocked) {
19384                proc = mPidsSelfLocked.get(pid);
19385            }
19386        } catch (NumberFormatException e) {
19387        }
19388
19389        if (proc == null) {
19390            ArrayMap<String, SparseArray<ProcessRecord>> all
19391                    = mProcessNames.getMap();
19392            SparseArray<ProcessRecord> procs = all.get(process);
19393            if (procs != null && procs.size() > 0) {
19394                proc = procs.valueAt(0);
19395                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
19396                    for (int i=1; i<procs.size(); i++) {
19397                        ProcessRecord thisProc = procs.valueAt(i);
19398                        if (thisProc.userId == userId) {
19399                            proc = thisProc;
19400                            break;
19401                        }
19402                    }
19403                }
19404            }
19405        }
19406
19407        return proc;
19408    }
19409
19410    public boolean dumpHeap(String process, int userId, boolean managed,
19411            String path, ParcelFileDescriptor fd) throws RemoteException {
19412
19413        try {
19414            synchronized (this) {
19415                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19416                // its own permission (same as profileControl).
19417                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19418                        != PackageManager.PERMISSION_GRANTED) {
19419                    throw new SecurityException("Requires permission "
19420                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19421                }
19422
19423                if (fd == null) {
19424                    throw new IllegalArgumentException("null fd");
19425                }
19426
19427                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
19428                if (proc == null || proc.thread == null) {
19429                    throw new IllegalArgumentException("Unknown process: " + process);
19430                }
19431
19432                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19433                if (!isDebuggable) {
19434                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19435                        throw new SecurityException("Process not debuggable: " + proc);
19436                    }
19437                }
19438
19439                proc.thread.dumpHeap(managed, path, fd);
19440                fd = null;
19441                return true;
19442            }
19443        } catch (RemoteException e) {
19444            throw new IllegalStateException("Process disappeared");
19445        } finally {
19446            if (fd != null) {
19447                try {
19448                    fd.close();
19449                } catch (IOException e) {
19450                }
19451            }
19452        }
19453    }
19454
19455    @Override
19456    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
19457            String reportPackage) {
19458        if (processName != null) {
19459            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
19460                    "setDumpHeapDebugLimit()");
19461        } else {
19462            synchronized (mPidsSelfLocked) {
19463                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
19464                if (proc == null) {
19465                    throw new SecurityException("No process found for calling pid "
19466                            + Binder.getCallingPid());
19467                }
19468                if (!Build.IS_DEBUGGABLE
19469                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19470                    throw new SecurityException("Not running a debuggable build");
19471                }
19472                processName = proc.processName;
19473                uid = proc.uid;
19474                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
19475                    throw new SecurityException("Package " + reportPackage + " is not running in "
19476                            + proc);
19477                }
19478            }
19479        }
19480        synchronized (this) {
19481            if (maxMemSize > 0) {
19482                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
19483            } else {
19484                if (uid != 0) {
19485                    mMemWatchProcesses.remove(processName, uid);
19486                } else {
19487                    mMemWatchProcesses.getMap().remove(processName);
19488                }
19489            }
19490        }
19491    }
19492
19493    @Override
19494    public void dumpHeapFinished(String path) {
19495        synchronized (this) {
19496            if (Binder.getCallingPid() != mMemWatchDumpPid) {
19497                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
19498                        + " does not match last pid " + mMemWatchDumpPid);
19499                return;
19500            }
19501            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
19502                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
19503                        + " does not match last path " + mMemWatchDumpFile);
19504                return;
19505            }
19506            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
19507            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
19508        }
19509    }
19510
19511    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
19512    public void monitor() {
19513        synchronized (this) { }
19514    }
19515
19516    void onCoreSettingsChange(Bundle settings) {
19517        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19518            ProcessRecord processRecord = mLruProcesses.get(i);
19519            try {
19520                if (processRecord.thread != null) {
19521                    processRecord.thread.setCoreSettings(settings);
19522                }
19523            } catch (RemoteException re) {
19524                /* ignore */
19525            }
19526        }
19527    }
19528
19529    // Multi-user methods
19530
19531    /**
19532     * Start user, if its not already running, but don't bring it to foreground.
19533     */
19534    @Override
19535    public boolean startUserInBackground(final int userId) {
19536        return startUser(userId, /* foreground */ false);
19537    }
19538
19539    /**
19540     * Start user, if its not already running, and bring it to foreground.
19541     */
19542    boolean startUserInForeground(final int userId, Dialog dlg) {
19543        boolean result = startUser(userId, /* foreground */ true);
19544        dlg.dismiss();
19545        return result;
19546    }
19547
19548    /**
19549     * Refreshes the list of users related to the current user when either a
19550     * user switch happens or when a new related user is started in the
19551     * background.
19552     */
19553    private void updateCurrentProfileIdsLocked() {
19554        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19555                mCurrentUserId, false /* enabledOnly */);
19556        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
19557        for (int i = 0; i < currentProfileIds.length; i++) {
19558            currentProfileIds[i] = profiles.get(i).id;
19559        }
19560        mCurrentProfileIds = currentProfileIds;
19561
19562        synchronized (mUserProfileGroupIdsSelfLocked) {
19563            mUserProfileGroupIdsSelfLocked.clear();
19564            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
19565            for (int i = 0; i < users.size(); i++) {
19566                UserInfo user = users.get(i);
19567                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
19568                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
19569                }
19570            }
19571        }
19572    }
19573
19574    private Set<Integer> getProfileIdsLocked(int userId) {
19575        Set<Integer> userIds = new HashSet<Integer>();
19576        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19577                userId, false /* enabledOnly */);
19578        for (UserInfo user : profiles) {
19579            userIds.add(Integer.valueOf(user.id));
19580        }
19581        return userIds;
19582    }
19583
19584    @Override
19585    public boolean switchUser(final int userId) {
19586        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19587        String userName;
19588        synchronized (this) {
19589            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19590            if (userInfo == null) {
19591                Slog.w(TAG, "No user info for user #" + userId);
19592                return false;
19593            }
19594            if (userInfo.isManagedProfile()) {
19595                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19596                return false;
19597            }
19598            userName = userInfo.name;
19599            mTargetUserId = userId;
19600        }
19601        mUiHandler.removeMessages(START_USER_SWITCH_MSG);
19602        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
19603        return true;
19604    }
19605
19606    private void showUserSwitchDialog(int userId, String userName) {
19607        // The dialog will show and then initiate the user switch by calling startUserInForeground
19608        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
19609                true /* above system */);
19610        d.show();
19611    }
19612
19613    private boolean startUser(final int userId, final boolean foreground) {
19614        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19615                != PackageManager.PERMISSION_GRANTED) {
19616            String msg = "Permission Denial: switchUser() from pid="
19617                    + Binder.getCallingPid()
19618                    + ", uid=" + Binder.getCallingUid()
19619                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19620            Slog.w(TAG, msg);
19621            throw new SecurityException(msg);
19622        }
19623
19624        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
19625
19626        final long ident = Binder.clearCallingIdentity();
19627        try {
19628            synchronized (this) {
19629                final int oldUserId = mCurrentUserId;
19630                if (oldUserId == userId) {
19631                    return true;
19632                }
19633
19634                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
19635                        "startUser", false);
19636
19637                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19638                if (userInfo == null) {
19639                    Slog.w(TAG, "No user info for user #" + userId);
19640                    return false;
19641                }
19642                if (foreground && userInfo.isManagedProfile()) {
19643                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19644                    return false;
19645                }
19646
19647                if (foreground) {
19648                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
19649                            R.anim.screen_user_enter);
19650                }
19651
19652                boolean needStart = false;
19653
19654                // If the user we are switching to is not currently started, then
19655                // we need to start it now.
19656                if (mStartedUsers.get(userId) == null) {
19657                    mStartedUsers.put(userId, new UserState(new UserHandle(userId), false));
19658                    updateStartedUserArrayLocked();
19659                    needStart = true;
19660                }
19661
19662                final Integer userIdInt = Integer.valueOf(userId);
19663                mUserLru.remove(userIdInt);
19664                mUserLru.add(userIdInt);
19665
19666                if (foreground) {
19667                    mCurrentUserId = userId;
19668                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
19669                    updateCurrentProfileIdsLocked();
19670                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
19671                    // Once the internal notion of the active user has switched, we lock the device
19672                    // with the option to show the user switcher on the keyguard.
19673                    mWindowManager.lockNow(null);
19674                } else {
19675                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
19676                    updateCurrentProfileIdsLocked();
19677                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
19678                    mUserLru.remove(currentUserIdInt);
19679                    mUserLru.add(currentUserIdInt);
19680                }
19681
19682                final UserState uss = mStartedUsers.get(userId);
19683
19684                // Make sure user is in the started state.  If it is currently
19685                // stopping, we need to knock that off.
19686                if (uss.mState == UserState.STATE_STOPPING) {
19687                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
19688                    // so we can just fairly silently bring the user back from
19689                    // the almost-dead.
19690                    uss.mState = UserState.STATE_RUNNING;
19691                    updateStartedUserArrayLocked();
19692                    needStart = true;
19693                } else if (uss.mState == UserState.STATE_SHUTDOWN) {
19694                    // This means ACTION_SHUTDOWN has been sent, so we will
19695                    // need to treat this as a new boot of the user.
19696                    uss.mState = UserState.STATE_BOOTING;
19697                    updateStartedUserArrayLocked();
19698                    needStart = true;
19699                }
19700
19701                if (uss.mState == UserState.STATE_BOOTING) {
19702                    // Booting up a new user, need to tell system services about it.
19703                    // Note that this is on the same handler as scheduling of broadcasts,
19704                    // which is important because it needs to go first.
19705                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
19706                }
19707
19708                if (foreground) {
19709                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
19710                            oldUserId));
19711                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
19712                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19713                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
19714                            oldUserId, userId, uss));
19715                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
19716                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
19717                }
19718
19719                if (needStart) {
19720                    // Send USER_STARTED broadcast
19721                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
19722                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19723                            | Intent.FLAG_RECEIVER_FOREGROUND);
19724                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19725                    broadcastIntentLocked(null, null, intent,
19726                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19727                            null, false, false, MY_PID, Process.SYSTEM_UID, userId);
19728                }
19729
19730                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
19731                    if (userId != UserHandle.USER_OWNER) {
19732                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
19733                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19734                        broadcastIntentLocked(null, null, intent, null,
19735                                new IIntentReceiver.Stub() {
19736                                    public void performReceive(Intent intent, int resultCode,
19737                                            String data, Bundle extras, boolean ordered,
19738                                            boolean sticky, int sendingUser) {
19739                                        onUserInitialized(uss, foreground, oldUserId, userId);
19740                                    }
19741                                }, 0, null, null, null, AppOpsManager.OP_NONE,
19742                                null, true, false, MY_PID, Process.SYSTEM_UID, userId);
19743                        uss.initializing = true;
19744                    } else {
19745                        getUserManagerLocked().makeInitialized(userInfo.id);
19746                    }
19747                }
19748
19749                if (foreground) {
19750                    if (!uss.initializing) {
19751                        moveUserToForeground(uss, oldUserId, userId);
19752                    }
19753                } else {
19754                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
19755                }
19756
19757                if (needStart) {
19758                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
19759                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19760                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19761                    broadcastIntentLocked(null, null, intent,
19762                            null, new IIntentReceiver.Stub() {
19763                                @Override
19764                                public void performReceive(Intent intent, int resultCode,
19765                                        String data, Bundle extras, boolean ordered, boolean sticky,
19766                                        int sendingUser) throws RemoteException {
19767                                }
19768                            }, 0, null, null,
19769                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19770                            null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19771                }
19772            }
19773        } finally {
19774            Binder.restoreCallingIdentity(ident);
19775        }
19776
19777        return true;
19778    }
19779
19780    void dispatchForegroundProfileChanged(int userId) {
19781        final int N = mUserSwitchObservers.beginBroadcast();
19782        for (int i = 0; i < N; i++) {
19783            try {
19784                mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
19785            } catch (RemoteException e) {
19786                // Ignore
19787            }
19788        }
19789        mUserSwitchObservers.finishBroadcast();
19790    }
19791
19792    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
19793        long ident = Binder.clearCallingIdentity();
19794        try {
19795            Intent intent;
19796            if (oldUserId >= 0) {
19797                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
19798                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
19799                int count = profiles.size();
19800                for (int i = 0; i < count; i++) {
19801                    int profileUserId = profiles.get(i).id;
19802                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
19803                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19804                            | Intent.FLAG_RECEIVER_FOREGROUND);
19805                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19806                    broadcastIntentLocked(null, null, intent,
19807                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19808                            null, false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19809                }
19810            }
19811            if (newUserId >= 0) {
19812                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
19813                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
19814                int count = profiles.size();
19815                for (int i = 0; i < count; i++) {
19816                    int profileUserId = profiles.get(i).id;
19817                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
19818                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19819                            | Intent.FLAG_RECEIVER_FOREGROUND);
19820                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19821                    broadcastIntentLocked(null, null, intent,
19822                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19823                            null, false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19824                }
19825                intent = new Intent(Intent.ACTION_USER_SWITCHED);
19826                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19827                        | Intent.FLAG_RECEIVER_FOREGROUND);
19828                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
19829                broadcastIntentLocked(null, null, intent,
19830                        null, null, 0, null, null,
19831                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
19832                        null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19833            }
19834        } finally {
19835            Binder.restoreCallingIdentity(ident);
19836        }
19837    }
19838
19839    void dispatchUserSwitch(final UserState uss, final int oldUserId,
19840            final int newUserId) {
19841        final int N = mUserSwitchObservers.beginBroadcast();
19842        if (N > 0) {
19843            final IRemoteCallback callback = new IRemoteCallback.Stub() {
19844                int mCount = 0;
19845                @Override
19846                public void sendResult(Bundle data) throws RemoteException {
19847                    synchronized (ActivityManagerService.this) {
19848                        if (mCurUserSwitchCallback == this) {
19849                            mCount++;
19850                            if (mCount == N) {
19851                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19852                            }
19853                        }
19854                    }
19855                }
19856            };
19857            synchronized (this) {
19858                uss.switching = true;
19859                mCurUserSwitchCallback = callback;
19860            }
19861            for (int i=0; i<N; i++) {
19862                try {
19863                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
19864                            newUserId, callback);
19865                } catch (RemoteException e) {
19866                }
19867            }
19868        } else {
19869            synchronized (this) {
19870                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19871            }
19872        }
19873        mUserSwitchObservers.finishBroadcast();
19874    }
19875
19876    void timeoutUserSwitch(UserState uss, int oldUserId, int newUserId) {
19877        synchronized (this) {
19878            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
19879            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19880        }
19881    }
19882
19883    void sendContinueUserSwitchLocked(UserState uss, int oldUserId, int newUserId) {
19884        mCurUserSwitchCallback = null;
19885        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19886        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
19887                oldUserId, newUserId, uss));
19888    }
19889
19890    void onUserInitialized(UserState uss, boolean foreground, int oldUserId, int newUserId) {
19891        synchronized (this) {
19892            if (foreground) {
19893                moveUserToForeground(uss, oldUserId, newUserId);
19894            }
19895        }
19896
19897        completeSwitchAndInitalize(uss, newUserId, true, false);
19898    }
19899
19900    void moveUserToForeground(UserState uss, int oldUserId, int newUserId) {
19901        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
19902        if (homeInFront) {
19903            startHomeActivityLocked(newUserId, "moveUserToFroreground");
19904        } else {
19905            mStackSupervisor.resumeTopActivitiesLocked();
19906        }
19907        EventLogTags.writeAmSwitchUser(newUserId);
19908        getUserManagerLocked().onUserForeground(newUserId);
19909        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
19910    }
19911
19912    void continueUserSwitch(UserState uss, int oldUserId, int newUserId) {
19913        completeSwitchAndInitalize(uss, newUserId, false, true);
19914    }
19915
19916    void completeSwitchAndInitalize(UserState uss, int newUserId,
19917            boolean clearInitializing, boolean clearSwitching) {
19918        boolean unfrozen = false;
19919        synchronized (this) {
19920            if (clearInitializing) {
19921                uss.initializing = false;
19922                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
19923            }
19924            if (clearSwitching) {
19925                uss.switching = false;
19926            }
19927            if (!uss.switching && !uss.initializing) {
19928                mWindowManager.stopFreezingScreen();
19929                unfrozen = true;
19930            }
19931        }
19932        if (unfrozen) {
19933            final int N = mUserSwitchObservers.beginBroadcast();
19934            for (int i=0; i<N; i++) {
19935                try {
19936                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
19937                } catch (RemoteException e) {
19938                }
19939            }
19940            mUserSwitchObservers.finishBroadcast();
19941        }
19942        stopGuestUserIfBackground();
19943    }
19944
19945    /**
19946     * Stops the guest user if it has gone to the background.
19947     */
19948    private void stopGuestUserIfBackground() {
19949        synchronized (this) {
19950            final int num = mUserLru.size();
19951            for (int i = 0; i < num; i++) {
19952                Integer oldUserId = mUserLru.get(i);
19953                UserState oldUss = mStartedUsers.get(oldUserId);
19954                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
19955                        || oldUss.mState == UserState.STATE_STOPPING
19956                        || oldUss.mState == UserState.STATE_SHUTDOWN) {
19957                    continue;
19958                }
19959                UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
19960                if (userInfo.isGuest()) {
19961                    // This is a user to be stopped.
19962                    stopUserLocked(oldUserId, null);
19963                    break;
19964                }
19965            }
19966        }
19967    }
19968
19969    void scheduleStartProfilesLocked() {
19970        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
19971            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
19972                    DateUtils.SECOND_IN_MILLIS);
19973        }
19974    }
19975
19976    void startProfilesLocked() {
19977        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
19978        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19979                mCurrentUserId, false /* enabledOnly */);
19980        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
19981        for (UserInfo user : profiles) {
19982            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
19983                    && user.id != mCurrentUserId) {
19984                toStart.add(user);
19985            }
19986        }
19987        final int n = toStart.size();
19988        int i = 0;
19989        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
19990            startUserInBackground(toStart.get(i).id);
19991        }
19992        if (i < n) {
19993            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
19994        }
19995    }
19996
19997    void finishUserBoot(UserState uss) {
19998        synchronized (this) {
19999            if (uss.mState == UserState.STATE_BOOTING
20000                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
20001                uss.mState = UserState.STATE_RUNNING;
20002                final int userId = uss.mHandle.getIdentifier();
20003                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
20004                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20005                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
20006                broadcastIntentLocked(null, null, intent,
20007                        null, null, 0, null, null,
20008                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
20009                        null, true, false, MY_PID, Process.SYSTEM_UID, userId);
20010            }
20011        }
20012    }
20013
20014    void finishUserSwitch(UserState uss) {
20015        synchronized (this) {
20016            finishUserBoot(uss);
20017
20018            startProfilesLocked();
20019
20020            int num = mUserLru.size();
20021            int i = 0;
20022            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
20023                Integer oldUserId = mUserLru.get(i);
20024                UserState oldUss = mStartedUsers.get(oldUserId);
20025                if (oldUss == null) {
20026                    // Shouldn't happen, but be sane if it does.
20027                    mUserLru.remove(i);
20028                    num--;
20029                    continue;
20030                }
20031                if (oldUss.mState == UserState.STATE_STOPPING
20032                        || oldUss.mState == UserState.STATE_SHUTDOWN) {
20033                    // This user is already stopping, doesn't count.
20034                    num--;
20035                    i++;
20036                    continue;
20037                }
20038                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
20039                    // Owner and current can't be stopped, but count as running.
20040                    i++;
20041                    continue;
20042                }
20043                // This is a user to be stopped.
20044                stopUserLocked(oldUserId, null);
20045                num--;
20046                i++;
20047            }
20048        }
20049    }
20050
20051    @Override
20052    public int stopUser(final int userId, final IStopUserCallback callback) {
20053        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20054                != PackageManager.PERMISSION_GRANTED) {
20055            String msg = "Permission Denial: switchUser() from pid="
20056                    + Binder.getCallingPid()
20057                    + ", uid=" + Binder.getCallingUid()
20058                    + " requires " + INTERACT_ACROSS_USERS_FULL;
20059            Slog.w(TAG, msg);
20060            throw new SecurityException(msg);
20061        }
20062        if (userId < 0 || userId == UserHandle.USER_OWNER) {
20063            throw new IllegalArgumentException("Can't stop primary user " + userId);
20064        }
20065        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
20066        synchronized (this) {
20067            return stopUserLocked(userId, callback);
20068        }
20069    }
20070
20071    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
20072        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
20073        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
20074            return ActivityManager.USER_OP_IS_CURRENT;
20075        }
20076
20077        final UserState uss = mStartedUsers.get(userId);
20078        if (uss == null) {
20079            // User is not started, nothing to do...  but we do need to
20080            // callback if requested.
20081            if (callback != null) {
20082                mHandler.post(new Runnable() {
20083                    @Override
20084                    public void run() {
20085                        try {
20086                            callback.userStopped(userId);
20087                        } catch (RemoteException e) {
20088                        }
20089                    }
20090                });
20091            }
20092            return ActivityManager.USER_OP_SUCCESS;
20093        }
20094
20095        if (callback != null) {
20096            uss.mStopCallbacks.add(callback);
20097        }
20098
20099        if (uss.mState != UserState.STATE_STOPPING
20100                && uss.mState != UserState.STATE_SHUTDOWN) {
20101            uss.mState = UserState.STATE_STOPPING;
20102            updateStartedUserArrayLocked();
20103
20104            long ident = Binder.clearCallingIdentity();
20105            try {
20106                // We are going to broadcast ACTION_USER_STOPPING and then
20107                // once that is done send a final ACTION_SHUTDOWN and then
20108                // stop the user.
20109                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
20110                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20111                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20112                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
20113                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
20114                // This is the result receiver for the final shutdown broadcast.
20115                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
20116                    @Override
20117                    public void performReceive(Intent intent, int resultCode, String data,
20118                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
20119                        finishUserStop(uss);
20120                    }
20121                };
20122                // This is the result receiver for the initial stopping broadcast.
20123                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
20124                    @Override
20125                    public void performReceive(Intent intent, int resultCode, String data,
20126                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
20127                        // On to the next.
20128                        synchronized (ActivityManagerService.this) {
20129                            if (uss.mState != UserState.STATE_STOPPING) {
20130                                // Whoops, we are being started back up.  Abort, abort!
20131                                return;
20132                            }
20133                            uss.mState = UserState.STATE_SHUTDOWN;
20134                        }
20135                        mBatteryStatsService.noteEvent(
20136                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
20137                                Integer.toString(userId), userId);
20138                        mSystemServiceManager.stopUser(userId);
20139                        broadcastIntentLocked(null, null, shutdownIntent,
20140                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
20141                                null, true, false, MY_PID, Process.SYSTEM_UID, userId);
20142                    }
20143                };
20144                // Kick things off.
20145                broadcastIntentLocked(null, null, stoppingIntent,
20146                        null, stoppingReceiver, 0, null, null,
20147                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
20148                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
20149            } finally {
20150                Binder.restoreCallingIdentity(ident);
20151            }
20152        }
20153
20154        return ActivityManager.USER_OP_SUCCESS;
20155    }
20156
20157    void finishUserStop(UserState uss) {
20158        final int userId = uss.mHandle.getIdentifier();
20159        boolean stopped;
20160        ArrayList<IStopUserCallback> callbacks;
20161        synchronized (this) {
20162            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
20163            if (mStartedUsers.get(userId) != uss) {
20164                stopped = false;
20165            } else if (uss.mState != UserState.STATE_SHUTDOWN) {
20166                stopped = false;
20167            } else {
20168                stopped = true;
20169                // User can no longer run.
20170                mStartedUsers.remove(userId);
20171                mUserLru.remove(Integer.valueOf(userId));
20172                updateStartedUserArrayLocked();
20173
20174                // Clean up all state and processes associated with the user.
20175                // Kill all the processes for the user.
20176                forceStopUserLocked(userId, "finish user");
20177            }
20178
20179            // Explicitly remove the old information in mRecentTasks.
20180            mRecentTasks.removeTasksForUserLocked(userId);
20181        }
20182
20183        for (int i=0; i<callbacks.size(); i++) {
20184            try {
20185                if (stopped) callbacks.get(i).userStopped(userId);
20186                else callbacks.get(i).userStopAborted(userId);
20187            } catch (RemoteException e) {
20188            }
20189        }
20190
20191        if (stopped) {
20192            mSystemServiceManager.cleanupUser(userId);
20193            synchronized (this) {
20194                mStackSupervisor.removeUserLocked(userId);
20195            }
20196        }
20197    }
20198
20199    @Override
20200    public UserInfo getCurrentUser() {
20201        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
20202                != PackageManager.PERMISSION_GRANTED) && (
20203                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20204                != PackageManager.PERMISSION_GRANTED)) {
20205            String msg = "Permission Denial: getCurrentUser() from pid="
20206                    + Binder.getCallingPid()
20207                    + ", uid=" + Binder.getCallingUid()
20208                    + " requires " + INTERACT_ACROSS_USERS;
20209            Slog.w(TAG, msg);
20210            throw new SecurityException(msg);
20211        }
20212        synchronized (this) {
20213            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20214            return getUserManagerLocked().getUserInfo(userId);
20215        }
20216    }
20217
20218    int getCurrentUserIdLocked() {
20219        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20220    }
20221
20222    @Override
20223    public boolean isUserRunning(int userId, boolean orStopped) {
20224        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20225                != PackageManager.PERMISSION_GRANTED) {
20226            String msg = "Permission Denial: isUserRunning() from pid="
20227                    + Binder.getCallingPid()
20228                    + ", uid=" + Binder.getCallingUid()
20229                    + " requires " + INTERACT_ACROSS_USERS;
20230            Slog.w(TAG, msg);
20231            throw new SecurityException(msg);
20232        }
20233        synchronized (this) {
20234            return isUserRunningLocked(userId, orStopped);
20235        }
20236    }
20237
20238    boolean isUserRunningLocked(int userId, boolean orStopped) {
20239        UserState state = mStartedUsers.get(userId);
20240        if (state == null) {
20241            return false;
20242        }
20243        if (orStopped) {
20244            return true;
20245        }
20246        return state.mState != UserState.STATE_STOPPING
20247                && state.mState != UserState.STATE_SHUTDOWN;
20248    }
20249
20250    @Override
20251    public int[] getRunningUserIds() {
20252        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20253                != PackageManager.PERMISSION_GRANTED) {
20254            String msg = "Permission Denial: isUserRunning() from pid="
20255                    + Binder.getCallingPid()
20256                    + ", uid=" + Binder.getCallingUid()
20257                    + " requires " + INTERACT_ACROSS_USERS;
20258            Slog.w(TAG, msg);
20259            throw new SecurityException(msg);
20260        }
20261        synchronized (this) {
20262            return mStartedUserArray;
20263        }
20264    }
20265
20266    private void updateStartedUserArrayLocked() {
20267        int num = 0;
20268        for (int i=0; i<mStartedUsers.size();  i++) {
20269            UserState uss = mStartedUsers.valueAt(i);
20270            // This list does not include stopping users.
20271            if (uss.mState != UserState.STATE_STOPPING
20272                    && uss.mState != UserState.STATE_SHUTDOWN) {
20273                num++;
20274            }
20275        }
20276        mStartedUserArray = new int[num];
20277        num = 0;
20278        for (int i=0; i<mStartedUsers.size();  i++) {
20279            UserState uss = mStartedUsers.valueAt(i);
20280            if (uss.mState != UserState.STATE_STOPPING
20281                    && uss.mState != UserState.STATE_SHUTDOWN) {
20282                mStartedUserArray[num] = mStartedUsers.keyAt(i);
20283                num++;
20284            }
20285        }
20286    }
20287
20288    @Override
20289    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20290        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20291                != PackageManager.PERMISSION_GRANTED) {
20292            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
20293                    + Binder.getCallingPid()
20294                    + ", uid=" + Binder.getCallingUid()
20295                    + " requires " + INTERACT_ACROSS_USERS_FULL;
20296            Slog.w(TAG, msg);
20297            throw new SecurityException(msg);
20298        }
20299
20300        mUserSwitchObservers.register(observer);
20301    }
20302
20303    @Override
20304    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20305        mUserSwitchObservers.unregister(observer);
20306    }
20307
20308    int[] getUsersLocked() {
20309        UserManagerService ums = getUserManagerLocked();
20310        return ums != null ? ums.getUserIds() : new int[] { 0 };
20311    }
20312
20313    UserManagerService getUserManagerLocked() {
20314        if (mUserManager == null) {
20315            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
20316            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
20317        }
20318        return mUserManager;
20319    }
20320
20321    private int applyUserId(int uid, int userId) {
20322        return UserHandle.getUid(userId, uid);
20323    }
20324
20325    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20326        if (info == null) return null;
20327        ApplicationInfo newInfo = new ApplicationInfo(info);
20328        newInfo.uid = applyUserId(info.uid, userId);
20329        newInfo.dataDir = PackageManager.getDataDirForUser(info.volumeUuid, info.packageName,
20330                userId).getAbsolutePath();
20331        return newInfo;
20332    }
20333
20334    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20335        if (aInfo == null
20336                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20337            return aInfo;
20338        }
20339
20340        ActivityInfo info = new ActivityInfo(aInfo);
20341        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20342        return info;
20343    }
20344
20345    private final class LocalService extends ActivityManagerInternal {
20346        @Override
20347        public void onWakefulnessChanged(int wakefulness) {
20348            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20349        }
20350
20351        @Override
20352        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20353                String processName, String abiOverride, int uid, Runnable crashHandler) {
20354            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20355                    processName, abiOverride, uid, crashHandler);
20356        }
20357
20358        @Override
20359        public SleepToken acquireSleepToken(String tag) {
20360            Preconditions.checkNotNull(tag);
20361
20362            synchronized (ActivityManagerService.this) {
20363                SleepTokenImpl token = new SleepTokenImpl(tag);
20364                mSleepTokens.add(token);
20365                updateSleepIfNeededLocked();
20366                return token;
20367            }
20368        }
20369
20370        @Override
20371        public ComponentName getHomeActivityForUser(int userId) {
20372            synchronized (ActivityManagerService.this) {
20373                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20374                return homeActivity == null ? null : homeActivity.realActivity;
20375            }
20376        }
20377    }
20378
20379    private final class SleepTokenImpl extends SleepToken {
20380        private final String mTag;
20381        private final long mAcquireTime;
20382
20383        public SleepTokenImpl(String tag) {
20384            mTag = tag;
20385            mAcquireTime = SystemClock.uptimeMillis();
20386        }
20387
20388        @Override
20389        public void release() {
20390            synchronized (ActivityManagerService.this) {
20391                if (mSleepTokens.remove(this)) {
20392                    updateSleepIfNeededLocked();
20393                }
20394            }
20395        }
20396
20397        @Override
20398        public String toString() {
20399            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20400        }
20401    }
20402
20403    /**
20404     * An implementation of IAppTask, that allows an app to manage its own tasks via
20405     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
20406     * only the process that calls getAppTasks() can call the AppTask methods.
20407     */
20408    class AppTaskImpl extends IAppTask.Stub {
20409        private int mTaskId;
20410        private int mCallingUid;
20411
20412        public AppTaskImpl(int taskId, int callingUid) {
20413            mTaskId = taskId;
20414            mCallingUid = callingUid;
20415        }
20416
20417        private void checkCaller() {
20418            if (mCallingUid != Binder.getCallingUid()) {
20419                throw new SecurityException("Caller " + mCallingUid
20420                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
20421            }
20422        }
20423
20424        @Override
20425        public void finishAndRemoveTask() {
20426            checkCaller();
20427
20428            synchronized (ActivityManagerService.this) {
20429                long origId = Binder.clearCallingIdentity();
20430                try {
20431                    if (!removeTaskByIdLocked(mTaskId, false)) {
20432                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20433                    }
20434                } finally {
20435                    Binder.restoreCallingIdentity(origId);
20436                }
20437            }
20438        }
20439
20440        @Override
20441        public ActivityManager.RecentTaskInfo getTaskInfo() {
20442            checkCaller();
20443
20444            synchronized (ActivityManagerService.this) {
20445                long origId = Binder.clearCallingIdentity();
20446                try {
20447                    TaskRecord tr = mRecentTasks.taskForIdLocked(mTaskId);
20448                    if (tr == null) {
20449                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20450                    }
20451                    return createRecentTaskInfoFromTaskRecord(tr);
20452                } finally {
20453                    Binder.restoreCallingIdentity(origId);
20454                }
20455            }
20456        }
20457
20458        @Override
20459        public void moveToFront() {
20460            checkCaller();
20461            // Will bring task to front if it already has a root activity.
20462            startActivityFromRecentsInner(mTaskId, null);
20463        }
20464
20465        @Override
20466        public int startActivity(IBinder whoThread, String callingPackage,
20467                Intent intent, String resolvedType, Bundle options) {
20468            checkCaller();
20469
20470            int callingUser = UserHandle.getCallingUserId();
20471            TaskRecord tr;
20472            IApplicationThread appThread;
20473            synchronized (ActivityManagerService.this) {
20474                tr = mRecentTasks.taskForIdLocked(mTaskId);
20475                if (tr == null) {
20476                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20477                }
20478                appThread = ApplicationThreadNative.asInterface(whoThread);
20479                if (appThread == null) {
20480                    throw new IllegalArgumentException("Bad app thread " + appThread);
20481                }
20482            }
20483            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
20484                    resolvedType, null, null, null, null, 0, 0, null, null,
20485                    null, options, callingUser, null, tr);
20486        }
20487
20488        @Override
20489        public void setExcludeFromRecents(boolean exclude) {
20490            checkCaller();
20491
20492            synchronized (ActivityManagerService.this) {
20493                long origId = Binder.clearCallingIdentity();
20494                try {
20495                    TaskRecord tr = mRecentTasks.taskForIdLocked(mTaskId);
20496                    if (tr == null) {
20497                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20498                    }
20499                    Intent intent = tr.getBaseIntent();
20500                    if (exclude) {
20501                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20502                    } else {
20503                        intent.setFlags(intent.getFlags()
20504                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20505                    }
20506                } finally {
20507                    Binder.restoreCallingIdentity(origId);
20508                }
20509            }
20510        }
20511    }
20512}
20513