ActivityManagerService.java revision 9ac5983c7b43676f748816381904d4c62a168a3e
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.READ_EXTERNAL_STORAGE;
22import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
23import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
24import static android.Manifest.permission.WRITE_MEDIA_STORAGE;
25import static android.content.pm.PackageManager.PERMISSION_GRANTED;
26import static com.android.internal.util.XmlUtils.readBooleanAttribute;
27import static com.android.internal.util.XmlUtils.readIntAttribute;
28import static com.android.internal.util.XmlUtils.readLongAttribute;
29import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
30import static com.android.internal.util.XmlUtils.writeIntAttribute;
31import static com.android.internal.util.XmlUtils.writeLongAttribute;
32import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
33import static com.android.server.am.ActivityManagerDebugConfig.*;
34import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
35import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
36import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
37import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
38import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
39import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
40import static org.xmlpull.v1.XmlPullParser.START_TAG;
41
42import android.Manifest;
43import android.app.AppOpsManager;
44import android.app.ApplicationThreadNative;
45import android.app.BroadcastOptions;
46import android.app.IActivityContainer;
47import android.app.IActivityContainerCallback;
48import android.app.IAppTask;
49import android.app.ITaskStackListener;
50import android.app.ProfilerInfo;
51import android.app.assist.AssistContent;
52import android.app.assist.AssistStructure;
53import android.app.usage.UsageEvents;
54import android.app.usage.UsageStatsManagerInternal;
55import android.appwidget.AppWidgetManager;
56import android.content.pm.PermissionInfo;
57import android.content.res.Resources;
58import android.graphics.Bitmap;
59import android.graphics.Point;
60import android.graphics.Rect;
61import android.os.BatteryStats;
62import android.os.PersistableBundle;
63import android.os.PowerManager;
64import android.os.Trace;
65import android.os.TransactionTooLargeException;
66import android.os.WorkSource;
67import android.os.storage.IMountService;
68import android.os.storage.MountServiceInternal;
69import android.os.storage.StorageManager;
70import android.service.voice.IVoiceInteractionSession;
71import android.util.ArrayMap;
72import android.util.ArraySet;
73import android.util.DebugUtils;
74import android.util.SparseIntArray;
75import android.view.Display;
76
77import com.android.internal.R;
78import com.android.internal.annotations.GuardedBy;
79import com.android.internal.app.DumpHeapActivity;
80import com.android.internal.app.IAppOpsService;
81import com.android.internal.app.IVoiceInteractor;
82import com.android.internal.app.ProcessMap;
83import com.android.internal.app.ProcessStats;
84import com.android.internal.os.BackgroundThread;
85import com.android.internal.os.BatteryStatsImpl;
86import com.android.internal.os.IResultReceiver;
87import com.android.internal.os.ProcessCpuTracker;
88import com.android.internal.os.TransferPipe;
89import com.android.internal.os.Zygote;
90import com.android.internal.util.ArrayUtils;
91import com.android.internal.util.FastPrintWriter;
92import com.android.internal.util.FastXmlSerializer;
93import com.android.internal.util.MemInfoReader;
94import com.android.internal.util.Preconditions;
95import com.android.server.AppOpsService;
96import com.android.server.AttributeCache;
97import com.android.server.DeviceIdleController;
98import com.android.server.IntentResolver;
99import com.android.server.LocalServices;
100import com.android.server.ServiceThread;
101import com.android.server.SystemService;
102import com.android.server.SystemServiceManager;
103import com.android.server.Watchdog;
104import com.android.server.am.ActivityStack.ActivityState;
105import com.android.server.firewall.IntentFirewall;
106import com.android.server.pm.Installer;
107import com.android.server.pm.UserManagerService;
108import com.android.server.statusbar.StatusBarManagerInternal;
109import com.android.server.wm.AppTransition;
110import com.android.server.wm.WindowManagerService;
111import com.google.android.collect.Lists;
112import com.google.android.collect.Maps;
113
114import libcore.io.IoUtils;
115import libcore.util.EmptyArray;
116
117import org.xmlpull.v1.XmlPullParser;
118import org.xmlpull.v1.XmlPullParserException;
119import org.xmlpull.v1.XmlSerializer;
120
121import android.app.Activity;
122import android.app.ActivityManager;
123import android.app.ActivityManager.RunningTaskInfo;
124import android.app.ActivityManager.StackInfo;
125import android.app.ActivityManagerInternal;
126import android.app.ActivityManagerInternal.SleepToken;
127import android.app.ActivityManagerNative;
128import android.app.ActivityOptions;
129import android.app.ActivityThread;
130import android.app.AlertDialog;
131import android.app.AppGlobals;
132import android.app.ApplicationErrorReport;
133import android.app.Dialog;
134import android.app.IActivityController;
135import android.app.IApplicationThread;
136import android.app.IInstrumentationWatcher;
137import android.app.INotificationManager;
138import android.app.IProcessObserver;
139import android.app.IServiceConnection;
140import android.app.IStopUserCallback;
141import android.app.IUidObserver;
142import android.app.IUiAutomationConnection;
143import android.app.IUserSwitchObserver;
144import android.app.Instrumentation;
145import android.app.Notification;
146import android.app.NotificationManager;
147import android.app.PendingIntent;
148import android.app.backup.IBackupManager;
149import android.app.admin.DevicePolicyManager;
150import android.content.ActivityNotFoundException;
151import android.content.BroadcastReceiver;
152import android.content.ClipData;
153import android.content.ComponentCallbacks2;
154import android.content.ComponentName;
155import android.content.ContentProvider;
156import android.content.ContentResolver;
157import android.content.Context;
158import android.content.DialogInterface;
159import android.content.IContentProvider;
160import android.content.IIntentReceiver;
161import android.content.IIntentSender;
162import android.content.Intent;
163import android.content.IntentFilter;
164import android.content.IntentSender;
165import android.content.pm.ActivityInfo;
166import android.content.pm.ApplicationInfo;
167import android.content.pm.ConfigurationInfo;
168import android.content.pm.IPackageDataObserver;
169import android.content.pm.IPackageManager;
170import android.content.pm.InstrumentationInfo;
171import android.content.pm.PackageInfo;
172import android.content.pm.PackageManager;
173import android.content.pm.ParceledListSlice;
174import android.content.pm.UserInfo;
175import android.content.pm.PackageManager.NameNotFoundException;
176import android.content.pm.PathPermission;
177import android.content.pm.ProviderInfo;
178import android.content.pm.ResolveInfo;
179import android.content.pm.ServiceInfo;
180import android.content.res.CompatibilityInfo;
181import android.content.res.Configuration;
182import android.net.Proxy;
183import android.net.ProxyInfo;
184import android.net.Uri;
185import android.os.Binder;
186import android.os.Build;
187import android.os.Bundle;
188import android.os.Debug;
189import android.os.DropBoxManager;
190import android.os.Environment;
191import android.os.FactoryTest;
192import android.os.FileObserver;
193import android.os.FileUtils;
194import android.os.Handler;
195import android.os.IBinder;
196import android.os.IPermissionController;
197import android.os.IProcessInfoService;
198import android.os.IRemoteCallback;
199import android.os.IUserManager;
200import android.os.Looper;
201import android.os.Message;
202import android.os.Parcel;
203import android.os.ParcelFileDescriptor;
204import android.os.PowerManagerInternal;
205import android.os.Process;
206import android.os.RemoteCallbackList;
207import android.os.RemoteException;
208import android.os.SELinux;
209import android.os.ServiceManager;
210import android.os.StrictMode;
211import android.os.SystemClock;
212import android.os.SystemProperties;
213import android.os.UpdateLock;
214import android.os.UserHandle;
215import android.os.UserManager;
216import android.provider.Settings;
217import android.text.format.DateUtils;
218import android.text.format.Time;
219import android.util.AtomicFile;
220import android.util.EventLog;
221import android.util.Log;
222import android.util.Pair;
223import android.util.PrintWriterPrinter;
224import android.util.Slog;
225import android.util.SparseArray;
226import android.util.TimeUtils;
227import android.util.Xml;
228import android.view.Gravity;
229import android.view.LayoutInflater;
230import android.view.View;
231import android.view.WindowManager;
232
233import dalvik.system.VMRuntime;
234
235import java.io.BufferedInputStream;
236import java.io.BufferedOutputStream;
237import java.io.DataInputStream;
238import java.io.DataOutputStream;
239import java.io.File;
240import java.io.FileDescriptor;
241import java.io.FileInputStream;
242import java.io.FileNotFoundException;
243import java.io.FileOutputStream;
244import java.io.IOException;
245import java.io.InputStreamReader;
246import java.io.PrintWriter;
247import java.io.StringWriter;
248import java.lang.ref.WeakReference;
249import java.nio.charset.StandardCharsets;
250import java.util.ArrayList;
251import java.util.Arrays;
252import java.util.Collections;
253import java.util.Comparator;
254import java.util.HashMap;
255import java.util.HashSet;
256import java.util.Iterator;
257import java.util.List;
258import java.util.Locale;
259import java.util.Map;
260import java.util.Set;
261import java.util.concurrent.atomic.AtomicBoolean;
262import java.util.concurrent.atomic.AtomicLong;
263
264public final class ActivityManagerService extends ActivityManagerNative
265        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
266
267    // File that stores last updated system version and called preboot receivers
268    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
269
270    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
271    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
272    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
273    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
274    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
275    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
276    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
277    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
278    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
279    private static final String TAG_LRU = TAG + POSTFIX_LRU;
280    private static final String TAG_MU = TAG + POSTFIX_MU;
281    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
282    private static final String TAG_POWER = TAG + POSTFIX_POWER;
283    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
284    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
285    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
286    private static final String TAG_PSS = TAG + POSTFIX_PSS;
287    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
288    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
289    private static final String TAG_STACK = TAG + POSTFIX_STACK;
290    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
291    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
292    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
293    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
294    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
295
296    /** Control over CPU and battery monitoring */
297    // write battery stats every 30 minutes.
298    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
299    static final boolean MONITOR_CPU_USAGE = true;
300    // don't sample cpu less than every 5 seconds.
301    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
302    // wait possibly forever for next cpu sample.
303    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
304    static final boolean MONITOR_THREAD_CPU_USAGE = false;
305
306    // The flags that are set for all calls we make to the package manager.
307    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
308
309    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
310
311    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
312
313    // Amount of time after a call to stopAppSwitches() during which we will
314    // prevent further untrusted switches from happening.
315    static final long APP_SWITCH_DELAY_TIME = 5*1000;
316
317    // How long we wait for a launched process to attach to the activity manager
318    // before we decide it's never going to come up for real.
319    static final int PROC_START_TIMEOUT = 10*1000;
320
321    // How long we wait for a launched process to attach to the activity manager
322    // before we decide it's never going to come up for real, when the process was
323    // started with a wrapper for instrumentation (such as Valgrind) because it
324    // could take much longer than usual.
325    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
326
327    // How long to wait after going idle before forcing apps to GC.
328    static final int GC_TIMEOUT = 5*1000;
329
330    // The minimum amount of time between successive GC requests for a process.
331    static final int GC_MIN_INTERVAL = 60*1000;
332
333    // The minimum amount of time between successive PSS requests for a process.
334    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
335
336    // The minimum amount of time between successive PSS requests for a process
337    // when the request is due to the memory state being lowered.
338    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
339
340    // The rate at which we check for apps using excessive power -- 15 mins.
341    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
342
343    // The minimum sample duration we will allow before deciding we have
344    // enough data on wake locks to start killing things.
345    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
346
347    // The minimum sample duration we will allow before deciding we have
348    // enough data on CPU usage to start killing things.
349    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
350
351    // How long we allow a receiver to run before giving up on it.
352    static final int BROADCAST_FG_TIMEOUT = 10*1000;
353    static final int BROADCAST_BG_TIMEOUT = 60*1000;
354
355    // How long we wait until we timeout on key dispatching.
356    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
357
358    // How long we wait until we timeout on key dispatching during instrumentation.
359    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
360
361    // Amount of time we wait for observers to handle a user switch before
362    // giving up on them and unfreezing the screen.
363    static final int USER_SWITCH_TIMEOUT = 2*1000;
364
365    // This is the amount of time an app needs to be running a foreground service before
366    // we will consider it to be doing interaction for usage stats.
367    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
368
369    // Maximum number of users we allow to be running at a time.
370    static final int MAX_RUNNING_USERS = 3;
371
372    // How long to wait in getAssistContextExtras for the activity and foreground services
373    // to respond with the result.
374    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
375
376    // How long top wait when going through the modern assist (which doesn't need to block
377    // on getting this result before starting to launch its UI).
378    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
379
380    // Maximum number of persisted Uri grants a package is allowed
381    static final int MAX_PERSISTED_URI_GRANTS = 128;
382
383    static final int MY_PID = Process.myPid();
384
385    static final String[] EMPTY_STRING_ARRAY = new String[0];
386
387    // How many bytes to write into the dropbox log before truncating
388    static final int DROPBOX_MAX_SIZE = 256 * 1024;
389
390    // Access modes for handleIncomingUser.
391    static final int ALLOW_NON_FULL = 0;
392    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
393    static final int ALLOW_FULL_ONLY = 2;
394
395    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
396
397    // Delay in notifying task stack change listeners (in millis)
398    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
399
400    // Necessary ApplicationInfo flags to mark an app as persistent
401    private static final int PERSISTENT_MASK =
402            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
403
404    /** All system services */
405    SystemServiceManager mSystemServiceManager;
406
407    private Installer mInstaller;
408
409    /** Run all ActivityStacks through this */
410    ActivityStackSupervisor mStackSupervisor;
411
412    /** Task stack change listeners. */
413    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
414            new RemoteCallbackList<ITaskStackListener>();
415
416    public IntentFirewall mIntentFirewall;
417
418    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
419    // default actuion automatically.  Important for devices without direct input
420    // devices.
421    private boolean mShowDialogs = true;
422
423    BroadcastQueue mFgBroadcastQueue;
424    BroadcastQueue mBgBroadcastQueue;
425    // Convenient for easy iteration over the queues. Foreground is first
426    // so that dispatch of foreground broadcasts gets precedence.
427    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
428
429    BroadcastQueue broadcastQueueForIntent(Intent intent) {
430        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
431        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
432                "Broadcast intent " + intent + " on "
433                + (isFg ? "foreground" : "background") + " queue");
434        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
435    }
436
437    /**
438     * Activity we have told the window manager to have key focus.
439     */
440    ActivityRecord mFocusedActivity = null;
441
442    /**
443     * User id of the last activity mFocusedActivity was set to.
444     */
445    private int mLastFocusedUserId;
446
447    /**
448     * If non-null, we are tracking the time the user spends in the currently focused app.
449     */
450    private AppTimeTracker mCurAppTimeTracker;
451
452    /**
453     * List of intents that were used to start the most recent tasks.
454     */
455    private final RecentTasks mRecentTasks;
456
457    /**
458     * For addAppTask: cached of the last activity component that was added.
459     */
460    ComponentName mLastAddedTaskComponent;
461
462    /**
463     * For addAppTask: cached of the last activity uid that was added.
464     */
465    int mLastAddedTaskUid;
466
467    /**
468     * For addAppTask: cached of the last ActivityInfo that was added.
469     */
470    ActivityInfo mLastAddedTaskActivity;
471
472    /**
473     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
474     */
475    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
476
477    /**
478     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
479     */
480    String mDeviceOwnerName;
481
482    public class PendingAssistExtras extends Binder implements Runnable {
483        public final ActivityRecord activity;
484        public final Bundle extras;
485        public final Intent intent;
486        public final String hint;
487        public final IResultReceiver receiver;
488        public final int userHandle;
489        public boolean haveResult = false;
490        public Bundle result = null;
491        public AssistStructure structure = null;
492        public AssistContent content = null;
493        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
494                String _hint, IResultReceiver _receiver, int _userHandle) {
495            activity = _activity;
496            extras = _extras;
497            intent = _intent;
498            hint = _hint;
499            receiver = _receiver;
500            userHandle = _userHandle;
501        }
502        @Override
503        public void run() {
504            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
505            synchronized (this) {
506                haveResult = true;
507                notifyAll();
508            }
509            pendingAssistExtrasTimedOut(this);
510        }
511    }
512
513    final ArrayList<PendingAssistExtras> mPendingAssistExtras
514            = new ArrayList<PendingAssistExtras>();
515
516    /**
517     * Process management.
518     */
519    final ProcessList mProcessList = new ProcessList();
520
521    /**
522     * All of the applications we currently have running organized by name.
523     * The keys are strings of the application package name (as
524     * returned by the package manager), and the keys are ApplicationRecord
525     * objects.
526     */
527    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
528
529    /**
530     * Tracking long-term execution of processes to look for abuse and other
531     * bad app behavior.
532     */
533    final ProcessStatsService mProcessStats;
534
535    /**
536     * The currently running isolated processes.
537     */
538    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
539
540    /**
541     * Counter for assigning isolated process uids, to avoid frequently reusing the
542     * same ones.
543     */
544    int mNextIsolatedProcessUid = 0;
545
546    /**
547     * The currently running heavy-weight process, if any.
548     */
549    ProcessRecord mHeavyWeightProcess = null;
550
551    /**
552     * The last time that various processes have crashed.
553     */
554    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
555
556    /**
557     * Information about a process that is currently marked as bad.
558     */
559    static final class BadProcessInfo {
560        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
561            this.time = time;
562            this.shortMsg = shortMsg;
563            this.longMsg = longMsg;
564            this.stack = stack;
565        }
566
567        final long time;
568        final String shortMsg;
569        final String longMsg;
570        final String stack;
571    }
572
573    /**
574     * Set of applications that we consider to be bad, and will reject
575     * incoming broadcasts from (which the user has no control over).
576     * Processes are added to this set when they have crashed twice within
577     * a minimum amount of time; they are removed from it when they are
578     * later restarted (hopefully due to some user action).  The value is the
579     * time it was added to the list.
580     */
581    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
582
583    /**
584     * All of the processes we currently have running organized by pid.
585     * The keys are the pid running the application.
586     *
587     * <p>NOTE: This object is protected by its own lock, NOT the global
588     * activity manager lock!
589     */
590    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
591
592    /**
593     * All of the processes that have been forced to be foreground.  The key
594     * is the pid of the caller who requested it (we hold a death
595     * link on it).
596     */
597    abstract class ForegroundToken implements IBinder.DeathRecipient {
598        int pid;
599        IBinder token;
600    }
601    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
602
603    /**
604     * List of records for processes that someone had tried to start before the
605     * system was ready.  We don't start them at that point, but ensure they
606     * are started by the time booting is complete.
607     */
608    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
609
610    /**
611     * List of persistent applications that are in the process
612     * of being started.
613     */
614    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
615
616    /**
617     * Processes that are being forcibly torn down.
618     */
619    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
620
621    /**
622     * List of running applications, sorted by recent usage.
623     * The first entry in the list is the least recently used.
624     */
625    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
626
627    /**
628     * Where in mLruProcesses that the processes hosting activities start.
629     */
630    int mLruProcessActivityStart = 0;
631
632    /**
633     * Where in mLruProcesses that the processes hosting services start.
634     * This is after (lower index) than mLruProcessesActivityStart.
635     */
636    int mLruProcessServiceStart = 0;
637
638    /**
639     * List of processes that should gc as soon as things are idle.
640     */
641    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
642
643    /**
644     * Processes we want to collect PSS data from.
645     */
646    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
647
648    private boolean mBinderTransactionTrackingEnabled = false;
649
650    /**
651     * Last time we requested PSS data of all processes.
652     */
653    long mLastFullPssTime = SystemClock.uptimeMillis();
654
655    /**
656     * If set, the next time we collect PSS data we should do a full collection
657     * with data from native processes and the kernel.
658     */
659    boolean mFullPssPending = false;
660
661    /**
662     * This is the process holding what we currently consider to be
663     * the "home" activity.
664     */
665    ProcessRecord mHomeProcess;
666
667    /**
668     * This is the process holding the activity the user last visited that
669     * is in a different process from the one they are currently in.
670     */
671    ProcessRecord mPreviousProcess;
672
673    /**
674     * The time at which the previous process was last visible.
675     */
676    long mPreviousProcessVisibleTime;
677
678    /**
679     * Track all uids that have actively running processes.
680     */
681    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
682
683    /**
684     * Which users have been started, so are allowed to run code.
685     */
686    final SparseArray<UserState> mStartedUsers = new SparseArray<>();
687
688    /**
689     * LRU list of history of current users.  Most recently current is at the end.
690     */
691    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
692
693    /**
694     * Constant array of the users that are currently started.
695     */
696    int[] mStartedUserArray = new int[] { 0 };
697
698    /**
699     * Registered observers of the user switching mechanics.
700     */
701    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
702            = new RemoteCallbackList<IUserSwitchObserver>();
703
704    /**
705     * Currently active user switch.
706     */
707    Object mCurUserSwitchCallback;
708
709    /**
710     * Packages that the user has asked to have run in screen size
711     * compatibility mode instead of filling the screen.
712     */
713    final CompatModePackages mCompatModePackages;
714
715    /**
716     * Set of IntentSenderRecord objects that are currently active.
717     */
718    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
719            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
720
721    /**
722     * Fingerprints (hashCode()) of stack traces that we've
723     * already logged DropBox entries for.  Guarded by itself.  If
724     * something (rogue user app) forces this over
725     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
726     */
727    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
728    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
729
730    /**
731     * Strict Mode background batched logging state.
732     *
733     * The string buffer is guarded by itself, and its lock is also
734     * used to determine if another batched write is already
735     * in-flight.
736     */
737    private final StringBuilder mStrictModeBuffer = new StringBuilder();
738
739    /**
740     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
741     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
742     */
743    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
744
745    /**
746     * Resolver for broadcast intents to registered receivers.
747     * Holds BroadcastFilter (subclass of IntentFilter).
748     */
749    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
750            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
751        @Override
752        protected boolean allowFilterResult(
753                BroadcastFilter filter, List<BroadcastFilter> dest) {
754            IBinder target = filter.receiverList.receiver.asBinder();
755            for (int i = dest.size() - 1; i >= 0; i--) {
756                if (dest.get(i).receiverList.receiver.asBinder() == target) {
757                    return false;
758                }
759            }
760            return true;
761        }
762
763        @Override
764        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
765            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
766                    || userId == filter.owningUserId) {
767                return super.newResult(filter, match, userId);
768            }
769            return null;
770        }
771
772        @Override
773        protected BroadcastFilter[] newArray(int size) {
774            return new BroadcastFilter[size];
775        }
776
777        @Override
778        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
779            return packageName.equals(filter.packageName);
780        }
781    };
782
783    /**
784     * State of all active sticky broadcasts per user.  Keys are the action of the
785     * sticky Intent, values are an ArrayList of all broadcasted intents with
786     * that action (which should usually be one).  The SparseArray is keyed
787     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
788     * for stickies that are sent to all users.
789     */
790    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
791            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
792
793    final ActiveServices mServices;
794
795    final static class Association {
796        final int mSourceUid;
797        final String mSourceProcess;
798        final int mTargetUid;
799        final ComponentName mTargetComponent;
800        final String mTargetProcess;
801
802        int mCount;
803        long mTime;
804
805        int mNesting;
806        long mStartTime;
807
808        Association(int sourceUid, String sourceProcess, int targetUid,
809                ComponentName targetComponent, String targetProcess) {
810            mSourceUid = sourceUid;
811            mSourceProcess = sourceProcess;
812            mTargetUid = targetUid;
813            mTargetComponent = targetComponent;
814            mTargetProcess = targetProcess;
815        }
816    }
817
818    /**
819     * When service association tracking is enabled, this is all of the associations we
820     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
821     * -> association data.
822     */
823    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
824            mAssociations = new SparseArray<>();
825    boolean mTrackingAssociations;
826
827    /**
828     * Backup/restore process management
829     */
830    String mBackupAppName = null;
831    BackupRecord mBackupTarget = null;
832
833    final ProviderMap mProviderMap;
834
835    /**
836     * List of content providers who have clients waiting for them.  The
837     * application is currently being launched and the provider will be
838     * removed from this list once it is published.
839     */
840    final ArrayList<ContentProviderRecord> mLaunchingProviders
841            = new ArrayList<ContentProviderRecord>();
842
843    /**
844     * File storing persisted {@link #mGrantedUriPermissions}.
845     */
846    private final AtomicFile mGrantFile;
847
848    /** XML constants used in {@link #mGrantFile} */
849    private static final String TAG_URI_GRANTS = "uri-grants";
850    private static final String TAG_URI_GRANT = "uri-grant";
851    private static final String ATTR_USER_HANDLE = "userHandle";
852    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
853    private static final String ATTR_TARGET_USER_ID = "targetUserId";
854    private static final String ATTR_SOURCE_PKG = "sourcePkg";
855    private static final String ATTR_TARGET_PKG = "targetPkg";
856    private static final String ATTR_URI = "uri";
857    private static final String ATTR_MODE_FLAGS = "modeFlags";
858    private static final String ATTR_CREATED_TIME = "createdTime";
859    private static final String ATTR_PREFIX = "prefix";
860
861    /**
862     * Global set of specific {@link Uri} permissions that have been granted.
863     * This optimized lookup structure maps from {@link UriPermission#targetUid}
864     * to {@link UriPermission#uri} to {@link UriPermission}.
865     */
866    @GuardedBy("this")
867    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
868            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
869
870    public static class GrantUri {
871        public final int sourceUserId;
872        public final Uri uri;
873        public boolean prefix;
874
875        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
876            this.sourceUserId = sourceUserId;
877            this.uri = uri;
878            this.prefix = prefix;
879        }
880
881        @Override
882        public int hashCode() {
883            int hashCode = 1;
884            hashCode = 31 * hashCode + sourceUserId;
885            hashCode = 31 * hashCode + uri.hashCode();
886            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
887            return hashCode;
888        }
889
890        @Override
891        public boolean equals(Object o) {
892            if (o instanceof GrantUri) {
893                GrantUri other = (GrantUri) o;
894                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
895                        && prefix == other.prefix;
896            }
897            return false;
898        }
899
900        @Override
901        public String toString() {
902            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
903            if (prefix) result += " [prefix]";
904            return result;
905        }
906
907        public String toSafeString() {
908            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
909            if (prefix) result += " [prefix]";
910            return result;
911        }
912
913        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
914            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
915                    ContentProvider.getUriWithoutUserId(uri), false);
916        }
917    }
918
919    CoreSettingsObserver mCoreSettingsObserver;
920
921    /**
922     * Thread-local storage used to carry caller permissions over through
923     * indirect content-provider access.
924     */
925    private class Identity {
926        public final IBinder token;
927        public final int pid;
928        public final int uid;
929
930        Identity(IBinder _token, int _pid, int _uid) {
931            token = _token;
932            pid = _pid;
933            uid = _uid;
934        }
935    }
936
937    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
938
939    /**
940     * All information we have collected about the runtime performance of
941     * any user id that can impact battery performance.
942     */
943    final BatteryStatsService mBatteryStatsService;
944
945    /**
946     * Information about component usage
947     */
948    UsageStatsManagerInternal mUsageStatsService;
949
950    /**
951     * Access to DeviceIdleController service.
952     */
953    DeviceIdleController.LocalService mLocalDeviceIdleController;
954
955    /**
956     * Information about and control over application operations
957     */
958    final AppOpsService mAppOpsService;
959
960    /**
961     * Save recent tasks information across reboots.
962     */
963    final TaskPersister mTaskPersister;
964
965    /**
966     * Current configuration information.  HistoryRecord objects are given
967     * a reference to this object to indicate which configuration they are
968     * currently running in, so this object must be kept immutable.
969     */
970    Configuration mConfiguration = new Configuration();
971
972    /**
973     * Current sequencing integer of the configuration, for skipping old
974     * configurations.
975     */
976    int mConfigurationSeq = 0;
977
978    /**
979     * Hardware-reported OpenGLES version.
980     */
981    final int GL_ES_VERSION;
982
983    /**
984     * List of initialization arguments to pass to all processes when binding applications to them.
985     * For example, references to the commonly used services.
986     */
987    HashMap<String, IBinder> mAppBindArgs;
988
989    /**
990     * Temporary to avoid allocations.  Protected by main lock.
991     */
992    final StringBuilder mStringBuilder = new StringBuilder(256);
993
994    /**
995     * Used to control how we initialize the service.
996     */
997    ComponentName mTopComponent;
998    String mTopAction = Intent.ACTION_MAIN;
999    String mTopData;
1000    boolean mProcessesReady = false;
1001    boolean mSystemReady = false;
1002    boolean mBooting = false;
1003    boolean mCallFinishBooting = false;
1004    boolean mBootAnimationComplete = false;
1005    boolean mWaitingUpdate = false;
1006    boolean mDidUpdate = false;
1007    boolean mOnBattery = false;
1008    boolean mLaunchWarningShown = false;
1009
1010    Context mContext;
1011
1012    int mFactoryTest;
1013
1014    boolean mCheckedForSetup;
1015
1016    /**
1017     * The time at which we will allow normal application switches again,
1018     * after a call to {@link #stopAppSwitches()}.
1019     */
1020    long mAppSwitchesAllowedTime;
1021
1022    /**
1023     * This is set to true after the first switch after mAppSwitchesAllowedTime
1024     * is set; any switches after that will clear the time.
1025     */
1026    boolean mDidAppSwitch;
1027
1028    /**
1029     * Last time (in realtime) at which we checked for power usage.
1030     */
1031    long mLastPowerCheckRealtime;
1032
1033    /**
1034     * Last time (in uptime) at which we checked for power usage.
1035     */
1036    long mLastPowerCheckUptime;
1037
1038    /**
1039     * Set while we are wanting to sleep, to prevent any
1040     * activities from being started/resumed.
1041     */
1042    private boolean mSleeping = false;
1043
1044    /**
1045     * The process state used for processes that are running the top activities.
1046     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1047     */
1048    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1049
1050    /**
1051     * Set while we are running a voice interaction.  This overrides
1052     * sleeping while it is active.
1053     */
1054    private IVoiceInteractionSession mRunningVoice;
1055
1056    /**
1057     * For some direct access we need to power manager.
1058     */
1059    PowerManagerInternal mLocalPowerManager;
1060
1061    /**
1062     * We want to hold a wake lock while running a voice interaction session, since
1063     * this may happen with the screen off and we need to keep the CPU running to
1064     * be able to continue to interact with the user.
1065     */
1066    PowerManager.WakeLock mVoiceWakeLock;
1067
1068    /**
1069     * State of external calls telling us if the device is awake or asleep.
1070     */
1071    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1072
1073    /**
1074     * A list of tokens that cause the top activity to be put to sleep.
1075     * They are used by components that may hide and block interaction with underlying
1076     * activities.
1077     */
1078    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1079
1080    static final int LOCK_SCREEN_HIDDEN = 0;
1081    static final int LOCK_SCREEN_LEAVING = 1;
1082    static final int LOCK_SCREEN_SHOWN = 2;
1083    /**
1084     * State of external call telling us if the lock screen is shown.
1085     */
1086    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1087
1088    /**
1089     * Set if we are shutting down the system, similar to sleeping.
1090     */
1091    boolean mShuttingDown = false;
1092
1093    /**
1094     * Current sequence id for oom_adj computation traversal.
1095     */
1096    int mAdjSeq = 0;
1097
1098    /**
1099     * Current sequence id for process LRU updating.
1100     */
1101    int mLruSeq = 0;
1102
1103    /**
1104     * Keep track of the non-cached/empty process we last found, to help
1105     * determine how to distribute cached/empty processes next time.
1106     */
1107    int mNumNonCachedProcs = 0;
1108
1109    /**
1110     * Keep track of the number of cached hidden procs, to balance oom adj
1111     * distribution between those and empty procs.
1112     */
1113    int mNumCachedHiddenProcs = 0;
1114
1115    /**
1116     * Keep track of the number of service processes we last found, to
1117     * determine on the next iteration which should be B services.
1118     */
1119    int mNumServiceProcs = 0;
1120    int mNewNumAServiceProcs = 0;
1121    int mNewNumServiceProcs = 0;
1122
1123    /**
1124     * Allow the current computed overall memory level of the system to go down?
1125     * This is set to false when we are killing processes for reasons other than
1126     * memory management, so that the now smaller process list will not be taken as
1127     * an indication that memory is tighter.
1128     */
1129    boolean mAllowLowerMemLevel = false;
1130
1131    /**
1132     * The last computed memory level, for holding when we are in a state that
1133     * processes are going away for other reasons.
1134     */
1135    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1136
1137    /**
1138     * The last total number of process we have, to determine if changes actually look
1139     * like a shrinking number of process due to lower RAM.
1140     */
1141    int mLastNumProcesses;
1142
1143    /**
1144     * The uptime of the last time we performed idle maintenance.
1145     */
1146    long mLastIdleTime = SystemClock.uptimeMillis();
1147
1148    /**
1149     * Total time spent with RAM that has been added in the past since the last idle time.
1150     */
1151    long mLowRamTimeSinceLastIdle = 0;
1152
1153    /**
1154     * If RAM is currently low, when that horrible situation started.
1155     */
1156    long mLowRamStartTime = 0;
1157
1158    /**
1159     * For reporting to battery stats the current top application.
1160     */
1161    private String mCurResumedPackage = null;
1162    private int mCurResumedUid = -1;
1163
1164    /**
1165     * For reporting to battery stats the apps currently running foreground
1166     * service.  The ProcessMap is package/uid tuples; each of these contain
1167     * an array of the currently foreground processes.
1168     */
1169    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1170            = new ProcessMap<ArrayList<ProcessRecord>>();
1171
1172    /**
1173     * This is set if we had to do a delayed dexopt of an app before launching
1174     * it, to increase the ANR timeouts in that case.
1175     */
1176    boolean mDidDexOpt;
1177
1178    /**
1179     * Set if the systemServer made a call to enterSafeMode.
1180     */
1181    boolean mSafeMode;
1182
1183    /**
1184     * If true, we are running under a test environment so will sample PSS from processes
1185     * much more rapidly to try to collect better data when the tests are rapidly
1186     * running through apps.
1187     */
1188    boolean mTestPssMode = false;
1189
1190    String mDebugApp = null;
1191    boolean mWaitForDebugger = false;
1192    boolean mDebugTransient = false;
1193    String mOrigDebugApp = null;
1194    boolean mOrigWaitForDebugger = false;
1195    boolean mAlwaysFinishActivities = false;
1196    IActivityController mController = null;
1197    String mProfileApp = null;
1198    ProcessRecord mProfileProc = null;
1199    String mProfileFile;
1200    ParcelFileDescriptor mProfileFd;
1201    int mSamplingInterval = 0;
1202    boolean mAutoStopProfiler = false;
1203    int mProfileType = 0;
1204    String mOpenGlTraceApp = null;
1205    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1206    String mMemWatchDumpProcName;
1207    String mMemWatchDumpFile;
1208    int mMemWatchDumpPid;
1209    int mMemWatchDumpUid;
1210    String mTrackAllocationApp = null;
1211
1212    final long[] mTmpLong = new long[1];
1213
1214    static final class ProcessChangeItem {
1215        static final int CHANGE_ACTIVITIES = 1<<0;
1216        static final int CHANGE_PROCESS_STATE = 1<<1;
1217        int changes;
1218        int uid;
1219        int pid;
1220        int processState;
1221        boolean foregroundActivities;
1222    }
1223
1224    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1225    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1226
1227    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1228    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1229
1230    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1231    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1232
1233    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1234    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1235
1236    /**
1237     * Runtime CPU use collection thread.  This object's lock is used to
1238     * perform synchronization with the thread (notifying it to run).
1239     */
1240    final Thread mProcessCpuThread;
1241
1242    /**
1243     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1244     * Must acquire this object's lock when accessing it.
1245     * NOTE: this lock will be held while doing long operations (trawling
1246     * through all processes in /proc), so it should never be acquired by
1247     * any critical paths such as when holding the main activity manager lock.
1248     */
1249    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1250            MONITOR_THREAD_CPU_USAGE);
1251    final AtomicLong mLastCpuTime = new AtomicLong(0);
1252    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1253
1254    long mLastWriteTime = 0;
1255
1256    /**
1257     * Used to retain an update lock when the foreground activity is in
1258     * immersive mode.
1259     */
1260    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1261
1262    /**
1263     * Set to true after the system has finished booting.
1264     */
1265    boolean mBooted = false;
1266
1267    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1268    int mProcessLimitOverride = -1;
1269
1270    WindowManagerService mWindowManager;
1271
1272    final ActivityThread mSystemThread;
1273
1274    // Holds the current foreground user's id
1275    int mCurrentUserId = 0;
1276    // Holds the target user's id during a user switch
1277    int mTargetUserId = UserHandle.USER_NULL;
1278    // If there are multiple profiles for the current user, their ids are here
1279    // Currently only the primary user can have managed profiles
1280    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1281
1282    /**
1283     * Mapping from each known user ID to the profile group ID it is associated with.
1284     */
1285    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1286
1287    private UserManagerService mUserManager;
1288
1289    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1290        final ProcessRecord mApp;
1291        final int mPid;
1292        final IApplicationThread mAppThread;
1293
1294        AppDeathRecipient(ProcessRecord app, int pid,
1295                IApplicationThread thread) {
1296            if (DEBUG_ALL) Slog.v(
1297                TAG, "New death recipient " + this
1298                + " for thread " + thread.asBinder());
1299            mApp = app;
1300            mPid = pid;
1301            mAppThread = thread;
1302        }
1303
1304        @Override
1305        public void binderDied() {
1306            if (DEBUG_ALL) Slog.v(
1307                TAG, "Death received in " + this
1308                + " for thread " + mAppThread.asBinder());
1309            synchronized(ActivityManagerService.this) {
1310                appDiedLocked(mApp, mPid, mAppThread, true);
1311            }
1312        }
1313    }
1314
1315    static final int SHOW_ERROR_MSG = 1;
1316    static final int SHOW_NOT_RESPONDING_MSG = 2;
1317    static final int SHOW_FACTORY_ERROR_MSG = 3;
1318    static final int UPDATE_CONFIGURATION_MSG = 4;
1319    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1320    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1321    static final int SERVICE_TIMEOUT_MSG = 12;
1322    static final int UPDATE_TIME_ZONE = 13;
1323    static final int SHOW_UID_ERROR_MSG = 14;
1324    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1325    static final int PROC_START_TIMEOUT_MSG = 20;
1326    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1327    static final int KILL_APPLICATION_MSG = 22;
1328    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1329    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1330    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1331    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1332    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1333    static final int CLEAR_DNS_CACHE_MSG = 28;
1334    static final int UPDATE_HTTP_PROXY_MSG = 29;
1335    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1336    static final int DISPATCH_PROCESSES_CHANGED = 31;
1337    static final int DISPATCH_PROCESS_DIED = 32;
1338    static final int REPORT_MEM_USAGE_MSG = 33;
1339    static final int REPORT_USER_SWITCH_MSG = 34;
1340    static final int CONTINUE_USER_SWITCH_MSG = 35;
1341    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1342    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1343    static final int PERSIST_URI_GRANTS_MSG = 38;
1344    static final int REQUEST_ALL_PSS_MSG = 39;
1345    static final int START_PROFILES_MSG = 40;
1346    static final int UPDATE_TIME = 41;
1347    static final int SYSTEM_USER_START_MSG = 42;
1348    static final int SYSTEM_USER_CURRENT_MSG = 43;
1349    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1350    static final int FINISH_BOOTING_MSG = 45;
1351    static final int START_USER_SWITCH_MSG = 46;
1352    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1353    static final int DISMISS_DIALOG_MSG = 48;
1354    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1355    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1356    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1357    static final int DELETE_DUMPHEAP_MSG = 52;
1358    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1359    static final int DISPATCH_UIDS_CHANGED_MSG = 54;
1360    static final int REPORT_TIME_TRACKER_MSG = 55;
1361    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1362
1363    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1364    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1365    static final int FIRST_COMPAT_MODE_MSG = 300;
1366    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1367
1368    CompatModeDialog mCompatModeDialog;
1369    long mLastMemUsageReportTime = 0;
1370
1371    /**
1372     * Flag whether the current user is a "monkey", i.e. whether
1373     * the UI is driven by a UI automation tool.
1374     */
1375    private boolean mUserIsMonkey;
1376
1377    /** Flag whether the device has a Recents UI */
1378    boolean mHasRecents;
1379
1380    /** The dimensions of the thumbnails in the Recents UI. */
1381    int mThumbnailWidth;
1382    int mThumbnailHeight;
1383
1384    final ServiceThread mHandlerThread;
1385    final MainHandler mHandler;
1386    final UiHandler mUiHandler;
1387
1388    final class UiHandler extends Handler {
1389        public UiHandler() {
1390            super(com.android.server.UiThread.get().getLooper(), null, true);
1391        }
1392
1393        @Override
1394        public void handleMessage(Message msg) {
1395            switch (msg.what) {
1396            case SHOW_ERROR_MSG: {
1397                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1398                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1399                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1400                synchronized (ActivityManagerService.this) {
1401                    ProcessRecord proc = (ProcessRecord)data.get("app");
1402                    AppErrorResult res = (AppErrorResult) data.get("result");
1403                    if (proc != null && proc.crashDialog != null) {
1404                        Slog.e(TAG, "App already has crash dialog: " + proc);
1405                        if (res != null) {
1406                            res.set(0);
1407                        }
1408                        return;
1409                    }
1410                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1411                            >= Process.FIRST_APPLICATION_UID
1412                            && proc.pid != MY_PID);
1413                    for (int userId : mCurrentProfileIds) {
1414                        isBackground &= (proc.userId != userId);
1415                    }
1416                    if (isBackground && !showBackground) {
1417                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1418                        if (res != null) {
1419                            res.set(0);
1420                        }
1421                        return;
1422                    }
1423                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1424                        Dialog d = new AppErrorDialog(mContext,
1425                                ActivityManagerService.this, res, proc);
1426                        d.show();
1427                        proc.crashDialog = d;
1428                    } else {
1429                        // The device is asleep, so just pretend that the user
1430                        // saw a crash dialog and hit "force quit".
1431                        if (res != null) {
1432                            res.set(0);
1433                        }
1434                    }
1435                }
1436
1437                ensureBootCompleted();
1438            } break;
1439            case SHOW_NOT_RESPONDING_MSG: {
1440                synchronized (ActivityManagerService.this) {
1441                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1442                    ProcessRecord proc = (ProcessRecord)data.get("app");
1443                    if (proc != null && proc.anrDialog != null) {
1444                        Slog.e(TAG, "App already has anr dialog: " + proc);
1445                        return;
1446                    }
1447
1448                    Intent intent = new Intent("android.intent.action.ANR");
1449                    if (!mProcessesReady) {
1450                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1451                                | Intent.FLAG_RECEIVER_FOREGROUND);
1452                    }
1453                    broadcastIntentLocked(null, null, intent,
1454                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1455                            null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1456
1457                    if (mShowDialogs) {
1458                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1459                                mContext, proc, (ActivityRecord)data.get("activity"),
1460                                msg.arg1 != 0);
1461                        d.show();
1462                        proc.anrDialog = d;
1463                    } else {
1464                        // Just kill the app if there is no dialog to be shown.
1465                        killAppAtUsersRequest(proc, null);
1466                    }
1467                }
1468
1469                ensureBootCompleted();
1470            } break;
1471            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1472                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1473                synchronized (ActivityManagerService.this) {
1474                    ProcessRecord proc = (ProcessRecord) data.get("app");
1475                    if (proc == null) {
1476                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1477                        break;
1478                    }
1479                    if (proc.crashDialog != null) {
1480                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1481                        return;
1482                    }
1483                    AppErrorResult res = (AppErrorResult) data.get("result");
1484                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1485                        Dialog d = new StrictModeViolationDialog(mContext,
1486                                ActivityManagerService.this, res, proc);
1487                        d.show();
1488                        proc.crashDialog = d;
1489                    } else {
1490                        // The device is asleep, so just pretend that the user
1491                        // saw a crash dialog and hit "force quit".
1492                        res.set(0);
1493                    }
1494                }
1495                ensureBootCompleted();
1496            } break;
1497            case SHOW_FACTORY_ERROR_MSG: {
1498                Dialog d = new FactoryErrorDialog(
1499                    mContext, msg.getData().getCharSequence("msg"));
1500                d.show();
1501                ensureBootCompleted();
1502            } break;
1503            case WAIT_FOR_DEBUGGER_MSG: {
1504                synchronized (ActivityManagerService.this) {
1505                    ProcessRecord app = (ProcessRecord)msg.obj;
1506                    if (msg.arg1 != 0) {
1507                        if (!app.waitedForDebugger) {
1508                            Dialog d = new AppWaitingForDebuggerDialog(
1509                                    ActivityManagerService.this,
1510                                    mContext, app);
1511                            app.waitDialog = d;
1512                            app.waitedForDebugger = true;
1513                            d.show();
1514                        }
1515                    } else {
1516                        if (app.waitDialog != null) {
1517                            app.waitDialog.dismiss();
1518                            app.waitDialog = null;
1519                        }
1520                    }
1521                }
1522            } break;
1523            case SHOW_UID_ERROR_MSG: {
1524                if (mShowDialogs) {
1525                    AlertDialog d = new BaseErrorDialog(mContext);
1526                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1527                    d.setCancelable(false);
1528                    d.setTitle(mContext.getText(R.string.android_system_label));
1529                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1530                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1531                            obtainMessage(DISMISS_DIALOG_MSG, d));
1532                    d.show();
1533                }
1534            } break;
1535            case SHOW_FINGERPRINT_ERROR_MSG: {
1536                if (mShowDialogs) {
1537                    AlertDialog d = new BaseErrorDialog(mContext);
1538                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1539                    d.setCancelable(false);
1540                    d.setTitle(mContext.getText(R.string.android_system_label));
1541                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1542                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1543                            obtainMessage(DISMISS_DIALOG_MSG, d));
1544                    d.show();
1545                }
1546            } break;
1547            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1548                synchronized (ActivityManagerService.this) {
1549                    ActivityRecord ar = (ActivityRecord) msg.obj;
1550                    if (mCompatModeDialog != null) {
1551                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1552                                ar.info.applicationInfo.packageName)) {
1553                            return;
1554                        }
1555                        mCompatModeDialog.dismiss();
1556                        mCompatModeDialog = null;
1557                    }
1558                    if (ar != null && false) {
1559                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1560                                ar.packageName)) {
1561                            int mode = mCompatModePackages.computeCompatModeLocked(
1562                                    ar.info.applicationInfo);
1563                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1564                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1565                                mCompatModeDialog = new CompatModeDialog(
1566                                        ActivityManagerService.this, mContext,
1567                                        ar.info.applicationInfo);
1568                                mCompatModeDialog.show();
1569                            }
1570                        }
1571                    }
1572                }
1573                break;
1574            }
1575            case START_USER_SWITCH_MSG: {
1576                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1577                break;
1578            }
1579            case DISMISS_DIALOG_MSG: {
1580                final Dialog d = (Dialog) msg.obj;
1581                d.dismiss();
1582                break;
1583            }
1584            case DISPATCH_PROCESSES_CHANGED: {
1585                dispatchProcessesChanged();
1586                break;
1587            }
1588            case DISPATCH_PROCESS_DIED: {
1589                final int pid = msg.arg1;
1590                final int uid = msg.arg2;
1591                dispatchProcessDied(pid, uid);
1592                break;
1593            }
1594            case DISPATCH_UIDS_CHANGED_MSG: {
1595                dispatchUidsChanged();
1596            } break;
1597            }
1598        }
1599    }
1600
1601    final class MainHandler extends Handler {
1602        public MainHandler(Looper looper) {
1603            super(looper, null, true);
1604        }
1605
1606        @Override
1607        public void handleMessage(Message msg) {
1608            switch (msg.what) {
1609            case UPDATE_CONFIGURATION_MSG: {
1610                final ContentResolver resolver = mContext.getContentResolver();
1611                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1612                        msg.arg1);
1613            } break;
1614            case GC_BACKGROUND_PROCESSES_MSG: {
1615                synchronized (ActivityManagerService.this) {
1616                    performAppGcsIfAppropriateLocked();
1617                }
1618            } break;
1619            case SERVICE_TIMEOUT_MSG: {
1620                if (mDidDexOpt) {
1621                    mDidDexOpt = false;
1622                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1623                    nmsg.obj = msg.obj;
1624                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1625                    return;
1626                }
1627                mServices.serviceTimeout((ProcessRecord)msg.obj);
1628            } break;
1629            case UPDATE_TIME_ZONE: {
1630                synchronized (ActivityManagerService.this) {
1631                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1632                        ProcessRecord r = mLruProcesses.get(i);
1633                        if (r.thread != null) {
1634                            try {
1635                                r.thread.updateTimeZone();
1636                            } catch (RemoteException ex) {
1637                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1638                            }
1639                        }
1640                    }
1641                }
1642            } break;
1643            case CLEAR_DNS_CACHE_MSG: {
1644                synchronized (ActivityManagerService.this) {
1645                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1646                        ProcessRecord r = mLruProcesses.get(i);
1647                        if (r.thread != null) {
1648                            try {
1649                                r.thread.clearDnsCache();
1650                            } catch (RemoteException ex) {
1651                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1652                            }
1653                        }
1654                    }
1655                }
1656            } break;
1657            case UPDATE_HTTP_PROXY_MSG: {
1658                ProxyInfo proxy = (ProxyInfo)msg.obj;
1659                String host = "";
1660                String port = "";
1661                String exclList = "";
1662                Uri pacFileUrl = Uri.EMPTY;
1663                if (proxy != null) {
1664                    host = proxy.getHost();
1665                    port = Integer.toString(proxy.getPort());
1666                    exclList = proxy.getExclusionListAsString();
1667                    pacFileUrl = proxy.getPacFileUrl();
1668                }
1669                synchronized (ActivityManagerService.this) {
1670                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1671                        ProcessRecord r = mLruProcesses.get(i);
1672                        if (r.thread != null) {
1673                            try {
1674                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1675                            } catch (RemoteException ex) {
1676                                Slog.w(TAG, "Failed to update http proxy for: " +
1677                                        r.info.processName);
1678                            }
1679                        }
1680                    }
1681                }
1682            } break;
1683            case PROC_START_TIMEOUT_MSG: {
1684                if (mDidDexOpt) {
1685                    mDidDexOpt = false;
1686                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1687                    nmsg.obj = msg.obj;
1688                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1689                    return;
1690                }
1691                ProcessRecord app = (ProcessRecord)msg.obj;
1692                synchronized (ActivityManagerService.this) {
1693                    processStartTimedOutLocked(app);
1694                }
1695            } break;
1696            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1697                synchronized (ActivityManagerService.this) {
1698                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1699                }
1700            } break;
1701            case KILL_APPLICATION_MSG: {
1702                synchronized (ActivityManagerService.this) {
1703                    int appid = msg.arg1;
1704                    boolean restart = (msg.arg2 == 1);
1705                    Bundle bundle = (Bundle)msg.obj;
1706                    String pkg = bundle.getString("pkg");
1707                    String reason = bundle.getString("reason");
1708                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1709                            false, UserHandle.USER_ALL, reason);
1710                }
1711            } break;
1712            case FINALIZE_PENDING_INTENT_MSG: {
1713                ((PendingIntentRecord)msg.obj).completeFinalize();
1714            } break;
1715            case POST_HEAVY_NOTIFICATION_MSG: {
1716                INotificationManager inm = NotificationManager.getService();
1717                if (inm == null) {
1718                    return;
1719                }
1720
1721                ActivityRecord root = (ActivityRecord)msg.obj;
1722                ProcessRecord process = root.app;
1723                if (process == null) {
1724                    return;
1725                }
1726
1727                try {
1728                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1729                    String text = mContext.getString(R.string.heavy_weight_notification,
1730                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1731                    Notification notification = new Notification.Builder(context)
1732                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1733                            .setWhen(0)
1734                            .setOngoing(true)
1735                            .setTicker(text)
1736                            .setColor(mContext.getColor(
1737                                    com.android.internal.R.color.system_notification_accent_color))
1738                            .setContentTitle(text)
1739                            .setContentText(
1740                                    mContext.getText(R.string.heavy_weight_notification_detail))
1741                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1742                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1743                                    new UserHandle(root.userId)))
1744                            .build();
1745                    try {
1746                        int[] outId = new int[1];
1747                        inm.enqueueNotificationWithTag("android", "android", null,
1748                                R.string.heavy_weight_notification,
1749                                notification, outId, root.userId);
1750                    } catch (RuntimeException e) {
1751                        Slog.w(ActivityManagerService.TAG,
1752                                "Error showing notification for heavy-weight app", e);
1753                    } catch (RemoteException e) {
1754                    }
1755                } catch (NameNotFoundException e) {
1756                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1757                }
1758            } break;
1759            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1760                INotificationManager inm = NotificationManager.getService();
1761                if (inm == null) {
1762                    return;
1763                }
1764                try {
1765                    inm.cancelNotificationWithTag("android", null,
1766                            R.string.heavy_weight_notification,  msg.arg1);
1767                } catch (RuntimeException e) {
1768                    Slog.w(ActivityManagerService.TAG,
1769                            "Error canceling notification for service", e);
1770                } catch (RemoteException e) {
1771                }
1772            } break;
1773            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1774                synchronized (ActivityManagerService.this) {
1775                    checkExcessivePowerUsageLocked(true);
1776                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1777                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1778                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1779                }
1780            } break;
1781            case REPORT_MEM_USAGE_MSG: {
1782                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1783                Thread thread = new Thread() {
1784                    @Override public void run() {
1785                        reportMemUsage(memInfos);
1786                    }
1787                };
1788                thread.start();
1789                break;
1790            }
1791            case REPORT_USER_SWITCH_MSG: {
1792                dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1793                break;
1794            }
1795            case CONTINUE_USER_SWITCH_MSG: {
1796                continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1797                break;
1798            }
1799            case USER_SWITCH_TIMEOUT_MSG: {
1800                timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1801                break;
1802            }
1803            case IMMERSIVE_MODE_LOCK_MSG: {
1804                final boolean nextState = (msg.arg1 != 0);
1805                if (mUpdateLock.isHeld() != nextState) {
1806                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1807                            "Applying new update lock state '" + nextState
1808                            + "' for " + (ActivityRecord)msg.obj);
1809                    if (nextState) {
1810                        mUpdateLock.acquire();
1811                    } else {
1812                        mUpdateLock.release();
1813                    }
1814                }
1815                break;
1816            }
1817            case PERSIST_URI_GRANTS_MSG: {
1818                writeGrantedUriPermissions();
1819                break;
1820            }
1821            case REQUEST_ALL_PSS_MSG: {
1822                synchronized (ActivityManagerService.this) {
1823                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1824                }
1825                break;
1826            }
1827            case START_PROFILES_MSG: {
1828                synchronized (ActivityManagerService.this) {
1829                    startProfilesLocked();
1830                }
1831                break;
1832            }
1833            case UPDATE_TIME: {
1834                synchronized (ActivityManagerService.this) {
1835                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1836                        ProcessRecord r = mLruProcesses.get(i);
1837                        if (r.thread != null) {
1838                            try {
1839                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1840                            } catch (RemoteException ex) {
1841                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1842                            }
1843                        }
1844                    }
1845                }
1846                break;
1847            }
1848            case SYSTEM_USER_START_MSG: {
1849                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1850                        Integer.toString(msg.arg1), msg.arg1);
1851                mSystemServiceManager.startUser(msg.arg1);
1852                break;
1853            }
1854            case SYSTEM_USER_CURRENT_MSG: {
1855                mBatteryStatsService.noteEvent(
1856                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1857                        Integer.toString(msg.arg2), msg.arg2);
1858                mBatteryStatsService.noteEvent(
1859                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1860                        Integer.toString(msg.arg1), msg.arg1);
1861                mSystemServiceManager.switchUser(msg.arg1);
1862                break;
1863            }
1864            case ENTER_ANIMATION_COMPLETE_MSG: {
1865                synchronized (ActivityManagerService.this) {
1866                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1867                    if (r != null && r.app != null && r.app.thread != null) {
1868                        try {
1869                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1870                        } catch (RemoteException e) {
1871                        }
1872                    }
1873                }
1874                break;
1875            }
1876            case FINISH_BOOTING_MSG: {
1877                if (msg.arg1 != 0) {
1878                    finishBooting();
1879                }
1880                if (msg.arg2 != 0) {
1881                    enableScreenAfterBoot();
1882                }
1883                break;
1884            }
1885            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1886                try {
1887                    Locale l = (Locale) msg.obj;
1888                    IBinder service = ServiceManager.getService("mount");
1889                    IMountService mountService = IMountService.Stub.asInterface(service);
1890                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1891                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1892                } catch (RemoteException e) {
1893                    Log.e(TAG, "Error storing locale for decryption UI", e);
1894                }
1895                break;
1896            }
1897            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1898                synchronized (ActivityManagerService.this) {
1899                    int i = mTaskStackListeners.beginBroadcast();
1900                    while (i > 0) {
1901                        i--;
1902                        try {
1903                            // Make a one-way callback to the listener
1904                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1905                        } catch (RemoteException e){
1906                            // Handled by the RemoteCallbackList
1907                        }
1908                    }
1909                    mTaskStackListeners.finishBroadcast();
1910                }
1911                break;
1912            }
1913            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1914                final int uid = msg.arg1;
1915                final byte[] firstPacket = (byte[]) msg.obj;
1916
1917                synchronized (mPidsSelfLocked) {
1918                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
1919                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
1920                        if (p.uid == uid) {
1921                            try {
1922                                p.thread.notifyCleartextNetwork(firstPacket);
1923                            } catch (RemoteException ignored) {
1924                            }
1925                        }
1926                    }
1927                }
1928                break;
1929            }
1930            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
1931                final String procName;
1932                final int uid;
1933                final long memLimit;
1934                final String reportPackage;
1935                synchronized (ActivityManagerService.this) {
1936                    procName = mMemWatchDumpProcName;
1937                    uid = mMemWatchDumpUid;
1938                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
1939                    if (val == null) {
1940                        val = mMemWatchProcesses.get(procName, 0);
1941                    }
1942                    if (val != null) {
1943                        memLimit = val.first;
1944                        reportPackage = val.second;
1945                    } else {
1946                        memLimit = 0;
1947                        reportPackage = null;
1948                    }
1949                }
1950                if (procName == null) {
1951                    return;
1952                }
1953
1954                if (DEBUG_PSS) Slog.d(TAG_PSS,
1955                        "Showing dump heap notification from " + procName + "/" + uid);
1956
1957                INotificationManager inm = NotificationManager.getService();
1958                if (inm == null) {
1959                    return;
1960                }
1961
1962                String text = mContext.getString(R.string.dump_heap_notification, procName);
1963
1964
1965                Intent deleteIntent = new Intent();
1966                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
1967                Intent intent = new Intent();
1968                intent.setClassName("android", DumpHeapActivity.class.getName());
1969                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
1970                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
1971                if (reportPackage != null) {
1972                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
1973                }
1974                int userId = UserHandle.getUserId(uid);
1975                Notification notification = new Notification.Builder(mContext)
1976                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1977                        .setWhen(0)
1978                        .setOngoing(true)
1979                        .setAutoCancel(true)
1980                        .setTicker(text)
1981                        .setColor(mContext.getColor(
1982                                com.android.internal.R.color.system_notification_accent_color))
1983                        .setContentTitle(text)
1984                        .setContentText(
1985                                mContext.getText(R.string.dump_heap_notification_detail))
1986                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1987                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1988                                new UserHandle(userId)))
1989                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
1990                                deleteIntent, 0, UserHandle.OWNER))
1991                        .build();
1992
1993                try {
1994                    int[] outId = new int[1];
1995                    inm.enqueueNotificationWithTag("android", "android", null,
1996                            R.string.dump_heap_notification,
1997                            notification, outId, userId);
1998                } catch (RuntimeException e) {
1999                    Slog.w(ActivityManagerService.TAG,
2000                            "Error showing notification for dump heap", e);
2001                } catch (RemoteException e) {
2002                }
2003            } break;
2004            case DELETE_DUMPHEAP_MSG: {
2005                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2006                        DumpHeapActivity.JAVA_URI,
2007                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2008                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2009                        UserHandle.myUserId());
2010                synchronized (ActivityManagerService.this) {
2011                    mMemWatchDumpFile = null;
2012                    mMemWatchDumpProcName = null;
2013                    mMemWatchDumpPid = -1;
2014                    mMemWatchDumpUid = -1;
2015                }
2016            } break;
2017            case FOREGROUND_PROFILE_CHANGED_MSG: {
2018                dispatchForegroundProfileChanged(msg.arg1);
2019            } break;
2020            case REPORT_TIME_TRACKER_MSG: {
2021                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2022                tracker.deliverResult(mContext);
2023            } break;
2024            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2025                dispatchUserSwitchComplete(msg.arg1);
2026            } break;
2027            }
2028        }
2029    };
2030
2031    static final int COLLECT_PSS_BG_MSG = 1;
2032
2033    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2034        @Override
2035        public void handleMessage(Message msg) {
2036            switch (msg.what) {
2037            case COLLECT_PSS_BG_MSG: {
2038                long start = SystemClock.uptimeMillis();
2039                MemInfoReader memInfo = null;
2040                synchronized (ActivityManagerService.this) {
2041                    if (mFullPssPending) {
2042                        mFullPssPending = false;
2043                        memInfo = new MemInfoReader();
2044                    }
2045                }
2046                if (memInfo != null) {
2047                    updateCpuStatsNow();
2048                    long nativeTotalPss = 0;
2049                    synchronized (mProcessCpuTracker) {
2050                        final int N = mProcessCpuTracker.countStats();
2051                        for (int j=0; j<N; j++) {
2052                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2053                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2054                                // This is definitely an application process; skip it.
2055                                continue;
2056                            }
2057                            synchronized (mPidsSelfLocked) {
2058                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2059                                    // This is one of our own processes; skip it.
2060                                    continue;
2061                                }
2062                            }
2063                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2064                        }
2065                    }
2066                    memInfo.readMemInfo();
2067                    synchronized (ActivityManagerService.this) {
2068                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2069                                + (SystemClock.uptimeMillis()-start) + "ms");
2070                        final long cachedKb = memInfo.getCachedSizeKb();
2071                        final long freeKb = memInfo.getFreeSizeKb();
2072                        final long zramKb = memInfo.getZramTotalSizeKb();
2073                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2074                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2075                                kernelKb*1024, nativeTotalPss*1024);
2076                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2077                                nativeTotalPss);
2078                    }
2079                }
2080
2081                int num = 0;
2082                long[] tmp = new long[1];
2083                do {
2084                    ProcessRecord proc;
2085                    int procState;
2086                    int pid;
2087                    long lastPssTime;
2088                    synchronized (ActivityManagerService.this) {
2089                        if (mPendingPssProcesses.size() <= 0) {
2090                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2091                                    "Collected PSS of " + num + " processes in "
2092                                    + (SystemClock.uptimeMillis() - start) + "ms");
2093                            mPendingPssProcesses.clear();
2094                            return;
2095                        }
2096                        proc = mPendingPssProcesses.remove(0);
2097                        procState = proc.pssProcState;
2098                        lastPssTime = proc.lastPssTime;
2099                        if (proc.thread != null && procState == proc.setProcState
2100                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2101                                        < SystemClock.uptimeMillis()) {
2102                            pid = proc.pid;
2103                        } else {
2104                            proc = null;
2105                            pid = 0;
2106                        }
2107                    }
2108                    if (proc != null) {
2109                        long pss = Debug.getPss(pid, tmp, null);
2110                        synchronized (ActivityManagerService.this) {
2111                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2112                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2113                                num++;
2114                                recordPssSampleLocked(proc, procState, pss, tmp[0],
2115                                        SystemClock.uptimeMillis());
2116                            }
2117                        }
2118                    }
2119                } while (true);
2120            }
2121            }
2122        }
2123    };
2124
2125    public void setSystemProcess() {
2126        try {
2127            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2128            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2129            ServiceManager.addService("meminfo", new MemBinder(this));
2130            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2131            ServiceManager.addService("dbinfo", new DbBinder(this));
2132            if (MONITOR_CPU_USAGE) {
2133                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2134            }
2135            ServiceManager.addService("permission", new PermissionController(this));
2136            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2137
2138            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2139                    "android", STOCK_PM_FLAGS);
2140            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2141
2142            synchronized (this) {
2143                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2144                app.persistent = true;
2145                app.pid = MY_PID;
2146                app.maxAdj = ProcessList.SYSTEM_ADJ;
2147                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2148                synchronized (mPidsSelfLocked) {
2149                    mPidsSelfLocked.put(app.pid, app);
2150                }
2151                updateLruProcessLocked(app, false, null);
2152                updateOomAdjLocked();
2153            }
2154        } catch (PackageManager.NameNotFoundException e) {
2155            throw new RuntimeException(
2156                    "Unable to find android system package", e);
2157        }
2158    }
2159
2160    public void setWindowManager(WindowManagerService wm) {
2161        mWindowManager = wm;
2162        mStackSupervisor.setWindowManager(wm);
2163    }
2164
2165    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2166        mUsageStatsService = usageStatsManager;
2167    }
2168
2169    public void startObservingNativeCrashes() {
2170        final NativeCrashListener ncl = new NativeCrashListener(this);
2171        ncl.start();
2172    }
2173
2174    public IAppOpsService getAppOpsService() {
2175        return mAppOpsService;
2176    }
2177
2178    static class MemBinder extends Binder {
2179        ActivityManagerService mActivityManagerService;
2180        MemBinder(ActivityManagerService activityManagerService) {
2181            mActivityManagerService = activityManagerService;
2182        }
2183
2184        @Override
2185        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2186            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2187                    != PackageManager.PERMISSION_GRANTED) {
2188                pw.println("Permission Denial: can't dump meminfo from from pid="
2189                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2190                        + " without permission " + android.Manifest.permission.DUMP);
2191                return;
2192            }
2193
2194            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2195        }
2196    }
2197
2198    static class GraphicsBinder extends Binder {
2199        ActivityManagerService mActivityManagerService;
2200        GraphicsBinder(ActivityManagerService activityManagerService) {
2201            mActivityManagerService = activityManagerService;
2202        }
2203
2204        @Override
2205        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2206            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2207                    != PackageManager.PERMISSION_GRANTED) {
2208                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2209                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2210                        + " without permission " + android.Manifest.permission.DUMP);
2211                return;
2212            }
2213
2214            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2215        }
2216    }
2217
2218    static class DbBinder extends Binder {
2219        ActivityManagerService mActivityManagerService;
2220        DbBinder(ActivityManagerService activityManagerService) {
2221            mActivityManagerService = activityManagerService;
2222        }
2223
2224        @Override
2225        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2226            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2227                    != PackageManager.PERMISSION_GRANTED) {
2228                pw.println("Permission Denial: can't dump dbinfo from from pid="
2229                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2230                        + " without permission " + android.Manifest.permission.DUMP);
2231                return;
2232            }
2233
2234            mActivityManagerService.dumpDbInfo(fd, pw, args);
2235        }
2236    }
2237
2238    static class CpuBinder extends Binder {
2239        ActivityManagerService mActivityManagerService;
2240        CpuBinder(ActivityManagerService activityManagerService) {
2241            mActivityManagerService = activityManagerService;
2242        }
2243
2244        @Override
2245        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2246            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2247                    != PackageManager.PERMISSION_GRANTED) {
2248                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2249                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2250                        + " without permission " + android.Manifest.permission.DUMP);
2251                return;
2252            }
2253
2254            synchronized (mActivityManagerService.mProcessCpuTracker) {
2255                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2256                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2257                        SystemClock.uptimeMillis()));
2258            }
2259        }
2260    }
2261
2262    public static final class Lifecycle extends SystemService {
2263        private final ActivityManagerService mService;
2264
2265        public Lifecycle(Context context) {
2266            super(context);
2267            mService = new ActivityManagerService(context);
2268        }
2269
2270        @Override
2271        public void onStart() {
2272            mService.start();
2273        }
2274
2275        public ActivityManagerService getService() {
2276            return mService;
2277        }
2278    }
2279
2280    // Note: This method is invoked on the main thread but may need to attach various
2281    // handlers to other threads.  So take care to be explicit about the looper.
2282    public ActivityManagerService(Context systemContext) {
2283        mContext = systemContext;
2284        mFactoryTest = FactoryTest.getMode();
2285        mSystemThread = ActivityThread.currentActivityThread();
2286
2287        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2288
2289        mHandlerThread = new ServiceThread(TAG,
2290                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2291        mHandlerThread.start();
2292        mHandler = new MainHandler(mHandlerThread.getLooper());
2293        mUiHandler = new UiHandler();
2294
2295        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2296                "foreground", BROADCAST_FG_TIMEOUT, false);
2297        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2298                "background", BROADCAST_BG_TIMEOUT, true);
2299        mBroadcastQueues[0] = mFgBroadcastQueue;
2300        mBroadcastQueues[1] = mBgBroadcastQueue;
2301
2302        mServices = new ActiveServices(this);
2303        mProviderMap = new ProviderMap(this);
2304
2305        // TODO: Move creation of battery stats service outside of activity manager service.
2306        File dataDir = Environment.getDataDirectory();
2307        File systemDir = new File(dataDir, "system");
2308        systemDir.mkdirs();
2309        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2310        mBatteryStatsService.getActiveStatistics().readLocked();
2311        mBatteryStatsService.scheduleWriteToDisk();
2312        mOnBattery = DEBUG_POWER ? true
2313                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2314        mBatteryStatsService.getActiveStatistics().setCallback(this);
2315
2316        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2317
2318        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2319
2320        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2321
2322        // User 0 is the first and only user that runs at boot.
2323        mStartedUsers.put(UserHandle.USER_OWNER, new UserState(UserHandle.OWNER, true));
2324        mUserLru.add(UserHandle.USER_OWNER);
2325        updateStartedUserArrayLocked();
2326
2327        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2328            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2329
2330        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2331
2332        mConfiguration.setToDefaults();
2333        mConfiguration.setLocale(Locale.getDefault());
2334
2335        mConfigurationSeq = mConfiguration.seq = 1;
2336        mProcessCpuTracker.init();
2337
2338        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2339        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2340        mRecentTasks = new RecentTasks(this);
2341        mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
2342        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
2343
2344        mProcessCpuThread = new Thread("CpuTracker") {
2345            @Override
2346            public void run() {
2347                while (true) {
2348                    try {
2349                        try {
2350                            synchronized(this) {
2351                                final long now = SystemClock.uptimeMillis();
2352                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2353                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2354                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2355                                //        + ", write delay=" + nextWriteDelay);
2356                                if (nextWriteDelay < nextCpuDelay) {
2357                                    nextCpuDelay = nextWriteDelay;
2358                                }
2359                                if (nextCpuDelay > 0) {
2360                                    mProcessCpuMutexFree.set(true);
2361                                    this.wait(nextCpuDelay);
2362                                }
2363                            }
2364                        } catch (InterruptedException e) {
2365                        }
2366                        updateCpuStatsNow();
2367                    } catch (Exception e) {
2368                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2369                    }
2370                }
2371            }
2372        };
2373
2374        Watchdog.getInstance().addMonitor(this);
2375        Watchdog.getInstance().addThread(mHandler);
2376    }
2377
2378    public void setSystemServiceManager(SystemServiceManager mgr) {
2379        mSystemServiceManager = mgr;
2380    }
2381
2382    public void setInstaller(Installer installer) {
2383        mInstaller = installer;
2384    }
2385
2386    private void start() {
2387        Process.removeAllProcessGroups();
2388        mProcessCpuThread.start();
2389
2390        mBatteryStatsService.publish(mContext);
2391        mAppOpsService.publish(mContext);
2392        Slog.d("AppOps", "AppOpsService published");
2393        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2394    }
2395
2396    public void initPowerManagement() {
2397        mStackSupervisor.initPowerManagement();
2398        mBatteryStatsService.initPowerManagement();
2399        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2400        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2401        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2402        mVoiceWakeLock.setReferenceCounted(false);
2403    }
2404
2405    @Override
2406    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2407            throws RemoteException {
2408        if (code == SYSPROPS_TRANSACTION) {
2409            // We need to tell all apps about the system property change.
2410            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2411            synchronized(this) {
2412                final int NP = mProcessNames.getMap().size();
2413                for (int ip=0; ip<NP; ip++) {
2414                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2415                    final int NA = apps.size();
2416                    for (int ia=0; ia<NA; ia++) {
2417                        ProcessRecord app = apps.valueAt(ia);
2418                        if (app.thread != null) {
2419                            procs.add(app.thread.asBinder());
2420                        }
2421                    }
2422                }
2423            }
2424
2425            int N = procs.size();
2426            for (int i=0; i<N; i++) {
2427                Parcel data2 = Parcel.obtain();
2428                try {
2429                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2430                } catch (RemoteException e) {
2431                }
2432                data2.recycle();
2433            }
2434        }
2435        try {
2436            return super.onTransact(code, data, reply, flags);
2437        } catch (RuntimeException e) {
2438            // The activity manager only throws security exceptions, so let's
2439            // log all others.
2440            if (!(e instanceof SecurityException)) {
2441                Slog.wtf(TAG, "Activity Manager Crash", e);
2442            }
2443            throw e;
2444        }
2445    }
2446
2447    void updateCpuStats() {
2448        final long now = SystemClock.uptimeMillis();
2449        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2450            return;
2451        }
2452        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2453            synchronized (mProcessCpuThread) {
2454                mProcessCpuThread.notify();
2455            }
2456        }
2457    }
2458
2459    void updateCpuStatsNow() {
2460        synchronized (mProcessCpuTracker) {
2461            mProcessCpuMutexFree.set(false);
2462            final long now = SystemClock.uptimeMillis();
2463            boolean haveNewCpuStats = false;
2464
2465            if (MONITOR_CPU_USAGE &&
2466                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2467                mLastCpuTime.set(now);
2468                mProcessCpuTracker.update();
2469                if (mProcessCpuTracker.hasGoodLastStats()) {
2470                    haveNewCpuStats = true;
2471                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2472                    //Slog.i(TAG, "Total CPU usage: "
2473                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2474
2475                    // Slog the cpu usage if the property is set.
2476                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2477                        int user = mProcessCpuTracker.getLastUserTime();
2478                        int system = mProcessCpuTracker.getLastSystemTime();
2479                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2480                        int irq = mProcessCpuTracker.getLastIrqTime();
2481                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2482                        int idle = mProcessCpuTracker.getLastIdleTime();
2483
2484                        int total = user + system + iowait + irq + softIrq + idle;
2485                        if (total == 0) total = 1;
2486
2487                        EventLog.writeEvent(EventLogTags.CPU,
2488                                ((user+system+iowait+irq+softIrq) * 100) / total,
2489                                (user * 100) / total,
2490                                (system * 100) / total,
2491                                (iowait * 100) / total,
2492                                (irq * 100) / total,
2493                                (softIrq * 100) / total);
2494                    }
2495                }
2496            }
2497
2498            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2499            synchronized(bstats) {
2500                synchronized(mPidsSelfLocked) {
2501                    if (haveNewCpuStats) {
2502                        if (bstats.startAddingCpuLocked()) {
2503                            int totalUTime = 0;
2504                            int totalSTime = 0;
2505                            final int N = mProcessCpuTracker.countStats();
2506                            for (int i=0; i<N; i++) {
2507                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2508                                if (!st.working) {
2509                                    continue;
2510                                }
2511                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2512                                totalUTime += st.rel_utime;
2513                                totalSTime += st.rel_stime;
2514                                if (pr != null) {
2515                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2516                                    if (ps == null || !ps.isActive()) {
2517                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2518                                                pr.info.uid, pr.processName);
2519                                    }
2520                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2521                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2522                                } else {
2523                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2524                                    if (ps == null || !ps.isActive()) {
2525                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2526                                                bstats.mapUid(st.uid), st.name);
2527                                    }
2528                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2529                                }
2530                            }
2531                            final int userTime = mProcessCpuTracker.getLastUserTime();
2532                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2533                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2534                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2535                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2536                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2537                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2538                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2539                        }
2540                    }
2541                }
2542
2543                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2544                    mLastWriteTime = now;
2545                    mBatteryStatsService.scheduleWriteToDisk();
2546                }
2547            }
2548        }
2549    }
2550
2551    @Override
2552    public void batteryNeedsCpuUpdate() {
2553        updateCpuStatsNow();
2554    }
2555
2556    @Override
2557    public void batteryPowerChanged(boolean onBattery) {
2558        // When plugging in, update the CPU stats first before changing
2559        // the plug state.
2560        updateCpuStatsNow();
2561        synchronized (this) {
2562            synchronized(mPidsSelfLocked) {
2563                mOnBattery = DEBUG_POWER ? true : onBattery;
2564            }
2565        }
2566    }
2567
2568    @Override
2569    public void batterySendBroadcast(Intent intent) {
2570        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2571                AppOpsManager.OP_NONE, null, false, false,
2572                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2573    }
2574
2575    /**
2576     * Initialize the application bind args. These are passed to each
2577     * process when the bindApplication() IPC is sent to the process. They're
2578     * lazily setup to make sure the services are running when they're asked for.
2579     */
2580    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2581        if (mAppBindArgs == null) {
2582            mAppBindArgs = new HashMap<>();
2583
2584            // Isolated processes won't get this optimization, so that we don't
2585            // violate the rules about which services they have access to.
2586            if (!isolated) {
2587                // Setup the application init args
2588                mAppBindArgs.put("package", ServiceManager.getService("package"));
2589                mAppBindArgs.put("window", ServiceManager.getService("window"));
2590                mAppBindArgs.put(Context.ALARM_SERVICE,
2591                        ServiceManager.getService(Context.ALARM_SERVICE));
2592            }
2593        }
2594        return mAppBindArgs;
2595    }
2596
2597    final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2598        if (r != null && mFocusedActivity != r) {
2599            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2600            ActivityRecord last = mFocusedActivity;
2601            mFocusedActivity = r;
2602            if (r.task.taskType != ActivityRecord.HOME_ACTIVITY_TYPE
2603                    && r.task.taskType != ActivityRecord.RECENTS_ACTIVITY_TYPE) {
2604                if (mCurAppTimeTracker != r.appTimeTracker) {
2605                    // We are switching app tracking.  Complete the current one.
2606                    if (mCurAppTimeTracker != null) {
2607                        mCurAppTimeTracker.stop();
2608                        mHandler.obtainMessage(REPORT_TIME_TRACKER_MSG,
2609                                mCurAppTimeTracker).sendToTarget();
2610                        mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2611                        mCurAppTimeTracker = null;
2612                    }
2613                    if (r.appTimeTracker != null) {
2614                        mCurAppTimeTracker = r.appTimeTracker;
2615                        startTimeTrackingFocusedActivityLocked();
2616                    }
2617                } else {
2618                    startTimeTrackingFocusedActivityLocked();
2619                }
2620            } else {
2621                r.appTimeTracker = null;
2622            }
2623            if (r.task != null && r.task.voiceInteractor != null) {
2624                startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2625            } else {
2626                finishRunningVoiceLocked();
2627                if (last != null && last.task.voiceSession != null) {
2628                    // We had been in a voice interaction session, but now focused has
2629                    // move to something different.  Just finish the session, we can't
2630                    // return to it and retain the proper state and synchronization with
2631                    // the voice interaction service.
2632                    finishVoiceTask(last.task.voiceSession);
2633                }
2634            }
2635            if (mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
2636                mWindowManager.setFocusedApp(r.appToken, true);
2637            }
2638            applyUpdateLockStateLocked(r);
2639            if (mFocusedActivity.userId != mLastFocusedUserId) {
2640                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2641                mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2642                        mFocusedActivity.userId, 0));
2643                mLastFocusedUserId = mFocusedActivity.userId;
2644            }
2645        }
2646        EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY,
2647                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2648                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2649    }
2650
2651    final void clearFocusedActivity(ActivityRecord r) {
2652        if (mFocusedActivity == r) {
2653            ActivityStack stack = mStackSupervisor.getFocusedStack();
2654            if (stack != null) {
2655                ActivityRecord top = stack.topActivity();
2656                if (top != null && top.userId != mLastFocusedUserId) {
2657                    mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2658                    mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2659                                    top.userId, 0));
2660                    mLastFocusedUserId = top.userId;
2661                }
2662            }
2663            mFocusedActivity = null;
2664            EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, -1, "NULL");
2665        }
2666    }
2667
2668    @Override
2669    public void setFocusedStack(int stackId) {
2670        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2671        synchronized (ActivityManagerService.this) {
2672            ActivityStack stack = mStackSupervisor.getStack(stackId);
2673            if (stack != null) {
2674                ActivityRecord r = stack.topRunningActivityLocked(null);
2675                if (r != null) {
2676                    setFocusedActivityLocked(r, "setFocusedStack");
2677                    mStackSupervisor.resumeTopActivitiesLocked(stack, null, null);
2678                }
2679            }
2680        }
2681    }
2682
2683    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2684    @Override
2685    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2686        synchronized (ActivityManagerService.this) {
2687            if (listener != null) {
2688                mTaskStackListeners.register(listener);
2689            }
2690        }
2691    }
2692
2693    @Override
2694    public void notifyActivityDrawn(IBinder token) {
2695        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2696        synchronized (this) {
2697            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2698            if (r != null) {
2699                r.task.stack.notifyActivityDrawnLocked(r);
2700            }
2701        }
2702    }
2703
2704    final void applyUpdateLockStateLocked(ActivityRecord r) {
2705        // Modifications to the UpdateLock state are done on our handler, outside
2706        // the activity manager's locks.  The new state is determined based on the
2707        // state *now* of the relevant activity record.  The object is passed to
2708        // the handler solely for logging detail, not to be consulted/modified.
2709        final boolean nextState = r != null && r.immersive;
2710        mHandler.sendMessage(
2711                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2712    }
2713
2714    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2715        Message msg = Message.obtain();
2716        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2717        msg.obj = r.task.askedCompatMode ? null : r;
2718        mUiHandler.sendMessage(msg);
2719    }
2720
2721    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2722            String what, Object obj, ProcessRecord srcApp) {
2723        app.lastActivityTime = now;
2724
2725        if (app.activities.size() > 0) {
2726            // Don't want to touch dependent processes that are hosting activities.
2727            return index;
2728        }
2729
2730        int lrui = mLruProcesses.lastIndexOf(app);
2731        if (lrui < 0) {
2732            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2733                    + what + " " + obj + " from " + srcApp);
2734            return index;
2735        }
2736
2737        if (lrui >= index) {
2738            // Don't want to cause this to move dependent processes *back* in the
2739            // list as if they were less frequently used.
2740            return index;
2741        }
2742
2743        if (lrui >= mLruProcessActivityStart) {
2744            // Don't want to touch dependent processes that are hosting activities.
2745            return index;
2746        }
2747
2748        mLruProcesses.remove(lrui);
2749        if (index > 0) {
2750            index--;
2751        }
2752        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2753                + " in LRU list: " + app);
2754        mLruProcesses.add(index, app);
2755        return index;
2756    }
2757
2758    private static void killProcessGroup(int uid, int pid) {
2759        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
2760        Process.killProcessGroup(uid, pid);
2761        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2762    }
2763
2764    final void removeLruProcessLocked(ProcessRecord app) {
2765        int lrui = mLruProcesses.lastIndexOf(app);
2766        if (lrui >= 0) {
2767            if (!app.killed) {
2768                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2769                Process.killProcessQuiet(app.pid);
2770                killProcessGroup(app.info.uid, app.pid);
2771            }
2772            if (lrui <= mLruProcessActivityStart) {
2773                mLruProcessActivityStart--;
2774            }
2775            if (lrui <= mLruProcessServiceStart) {
2776                mLruProcessServiceStart--;
2777            }
2778            mLruProcesses.remove(lrui);
2779        }
2780    }
2781
2782    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2783            ProcessRecord client) {
2784        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2785                || app.treatLikeActivity;
2786        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2787        if (!activityChange && hasActivity) {
2788            // The process has activities, so we are only allowing activity-based adjustments
2789            // to move it.  It should be kept in the front of the list with other
2790            // processes that have activities, and we don't want those to change their
2791            // order except due to activity operations.
2792            return;
2793        }
2794
2795        mLruSeq++;
2796        final long now = SystemClock.uptimeMillis();
2797        app.lastActivityTime = now;
2798
2799        // First a quick reject: if the app is already at the position we will
2800        // put it, then there is nothing to do.
2801        if (hasActivity) {
2802            final int N = mLruProcesses.size();
2803            if (N > 0 && mLruProcesses.get(N-1) == app) {
2804                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
2805                return;
2806            }
2807        } else {
2808            if (mLruProcessServiceStart > 0
2809                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2810                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
2811                return;
2812            }
2813        }
2814
2815        int lrui = mLruProcesses.lastIndexOf(app);
2816
2817        if (app.persistent && lrui >= 0) {
2818            // We don't care about the position of persistent processes, as long as
2819            // they are in the list.
2820            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
2821            return;
2822        }
2823
2824        /* In progress: compute new position first, so we can avoid doing work
2825           if the process is not actually going to move.  Not yet working.
2826        int addIndex;
2827        int nextIndex;
2828        boolean inActivity = false, inService = false;
2829        if (hasActivity) {
2830            // Process has activities, put it at the very tipsy-top.
2831            addIndex = mLruProcesses.size();
2832            nextIndex = mLruProcessServiceStart;
2833            inActivity = true;
2834        } else if (hasService) {
2835            // Process has services, put it at the top of the service list.
2836            addIndex = mLruProcessActivityStart;
2837            nextIndex = mLruProcessServiceStart;
2838            inActivity = true;
2839            inService = true;
2840        } else  {
2841            // Process not otherwise of interest, it goes to the top of the non-service area.
2842            addIndex = mLruProcessServiceStart;
2843            if (client != null) {
2844                int clientIndex = mLruProcesses.lastIndexOf(client);
2845                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2846                        + app);
2847                if (clientIndex >= 0 && addIndex > clientIndex) {
2848                    addIndex = clientIndex;
2849                }
2850            }
2851            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2852        }
2853
2854        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2855                + mLruProcessActivityStart + "): " + app);
2856        */
2857
2858        if (lrui >= 0) {
2859            if (lrui < mLruProcessActivityStart) {
2860                mLruProcessActivityStart--;
2861            }
2862            if (lrui < mLruProcessServiceStart) {
2863                mLruProcessServiceStart--;
2864            }
2865            /*
2866            if (addIndex > lrui) {
2867                addIndex--;
2868            }
2869            if (nextIndex > lrui) {
2870                nextIndex--;
2871            }
2872            */
2873            mLruProcesses.remove(lrui);
2874        }
2875
2876        /*
2877        mLruProcesses.add(addIndex, app);
2878        if (inActivity) {
2879            mLruProcessActivityStart++;
2880        }
2881        if (inService) {
2882            mLruProcessActivityStart++;
2883        }
2884        */
2885
2886        int nextIndex;
2887        if (hasActivity) {
2888            final int N = mLruProcesses.size();
2889            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
2890                // Process doesn't have activities, but has clients with
2891                // activities...  move it up, but one below the top (the top
2892                // should always have a real activity).
2893                if (DEBUG_LRU) Slog.d(TAG_LRU,
2894                        "Adding to second-top of LRU activity list: " + app);
2895                mLruProcesses.add(N - 1, app);
2896                // To keep it from spamming the LRU list (by making a bunch of clients),
2897                // we will push down any other entries owned by the app.
2898                final int uid = app.info.uid;
2899                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
2900                    ProcessRecord subProc = mLruProcesses.get(i);
2901                    if (subProc.info.uid == uid) {
2902                        // We want to push this one down the list.  If the process after
2903                        // it is for the same uid, however, don't do so, because we don't
2904                        // want them internally to be re-ordered.
2905                        if (mLruProcesses.get(i - 1).info.uid != uid) {
2906                            if (DEBUG_LRU) Slog.d(TAG_LRU,
2907                                    "Pushing uid " + uid + " swapping at " + i + ": "
2908                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
2909                            ProcessRecord tmp = mLruProcesses.get(i);
2910                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
2911                            mLruProcesses.set(i - 1, tmp);
2912                            i--;
2913                        }
2914                    } else {
2915                        // A gap, we can stop here.
2916                        break;
2917                    }
2918                }
2919            } else {
2920                // Process has activities, put it at the very tipsy-top.
2921                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
2922                mLruProcesses.add(app);
2923            }
2924            nextIndex = mLruProcessServiceStart;
2925        } else if (hasService) {
2926            // Process has services, put it at the top of the service list.
2927            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
2928            mLruProcesses.add(mLruProcessActivityStart, app);
2929            nextIndex = mLruProcessServiceStart;
2930            mLruProcessActivityStart++;
2931        } else  {
2932            // Process not otherwise of interest, it goes to the top of the non-service area.
2933            int index = mLruProcessServiceStart;
2934            if (client != null) {
2935                // If there is a client, don't allow the process to be moved up higher
2936                // in the list than that client.
2937                int clientIndex = mLruProcesses.lastIndexOf(client);
2938                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
2939                        + " when updating " + app);
2940                if (clientIndex <= lrui) {
2941                    // Don't allow the client index restriction to push it down farther in the
2942                    // list than it already is.
2943                    clientIndex = lrui;
2944                }
2945                if (clientIndex >= 0 && index > clientIndex) {
2946                    index = clientIndex;
2947                }
2948            }
2949            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
2950            mLruProcesses.add(index, app);
2951            nextIndex = index-1;
2952            mLruProcessActivityStart++;
2953            mLruProcessServiceStart++;
2954        }
2955
2956        // If the app is currently using a content provider or service,
2957        // bump those processes as well.
2958        for (int j=app.connections.size()-1; j>=0; j--) {
2959            ConnectionRecord cr = app.connections.valueAt(j);
2960            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2961                    && cr.binding.service.app != null
2962                    && cr.binding.service.app.lruSeq != mLruSeq
2963                    && !cr.binding.service.app.persistent) {
2964                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2965                        "service connection", cr, app);
2966            }
2967        }
2968        for (int j=app.conProviders.size()-1; j>=0; j--) {
2969            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2970            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2971                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2972                        "provider reference", cpr, app);
2973            }
2974        }
2975    }
2976
2977    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2978        if (uid == Process.SYSTEM_UID) {
2979            // The system gets to run in any process.  If there are multiple
2980            // processes with the same uid, just pick the first (this
2981            // should never happen).
2982            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2983            if (procs == null) return null;
2984            final int procCount = procs.size();
2985            for (int i = 0; i < procCount; i++) {
2986                final int procUid = procs.keyAt(i);
2987                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
2988                    // Don't use an app process or different user process for system component.
2989                    continue;
2990                }
2991                return procs.valueAt(i);
2992            }
2993        }
2994        ProcessRecord proc = mProcessNames.get(processName, uid);
2995        if (false && proc != null && !keepIfLarge
2996                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2997                && proc.lastCachedPss >= 4000) {
2998            // Turn this condition on to cause killing to happen regularly, for testing.
2999            if (proc.baseProcessTracker != null) {
3000                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3001            }
3002            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3003        } else if (proc != null && !keepIfLarge
3004                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3005                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3006            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3007            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3008                if (proc.baseProcessTracker != null) {
3009                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3010                }
3011                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3012            }
3013        }
3014        return proc;
3015    }
3016
3017    void ensurePackageDexOpt(String packageName) {
3018        IPackageManager pm = AppGlobals.getPackageManager();
3019        try {
3020            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
3021                mDidDexOpt = true;
3022            }
3023        } catch (RemoteException e) {
3024        }
3025    }
3026
3027    boolean isNextTransitionForward() {
3028        int transit = mWindowManager.getPendingAppTransition();
3029        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
3030                || transit == AppTransition.TRANSIT_TASK_OPEN
3031                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
3032    }
3033
3034    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3035            String processName, String abiOverride, int uid, Runnable crashHandler) {
3036        synchronized(this) {
3037            ApplicationInfo info = new ApplicationInfo();
3038            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3039            // For isolated processes, the former contains the parent's uid and the latter the
3040            // actual uid of the isolated process.
3041            // In the special case introduced by this method (which is, starting an isolated
3042            // process directly from the SystemServer without an actual parent app process) the
3043            // closest thing to a parent's uid is SYSTEM_UID.
3044            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3045            // the |isolated| logic in the ProcessRecord constructor.
3046            info.uid = Process.SYSTEM_UID;
3047            info.processName = processName;
3048            info.className = entryPoint;
3049            info.packageName = "android";
3050            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3051                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3052                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3053                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3054                    crashHandler);
3055            return proc != null ? proc.pid : 0;
3056        }
3057    }
3058
3059    final ProcessRecord startProcessLocked(String processName,
3060            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3061            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3062            boolean isolated, boolean keepIfLarge) {
3063        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3064                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3065                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3066                null /* crashHandler */);
3067    }
3068
3069    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3070            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3071            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3072            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3073        long startTime = SystemClock.elapsedRealtime();
3074        ProcessRecord app;
3075        if (!isolated) {
3076            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3077            checkTime(startTime, "startProcess: after getProcessRecord");
3078
3079            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3080                // If we are in the background, then check to see if this process
3081                // is bad.  If so, we will just silently fail.
3082                if (mBadProcesses.get(info.processName, info.uid) != null) {
3083                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3084                            + "/" + info.processName);
3085                    return null;
3086                }
3087            } else {
3088                // When the user is explicitly starting a process, then clear its
3089                // crash count so that we won't make it bad until they see at
3090                // least one crash dialog again, and make the process good again
3091                // if it had been bad.
3092                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3093                        + "/" + info.processName);
3094                mProcessCrashTimes.remove(info.processName, info.uid);
3095                if (mBadProcesses.get(info.processName, info.uid) != null) {
3096                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3097                            UserHandle.getUserId(info.uid), info.uid,
3098                            info.processName);
3099                    mBadProcesses.remove(info.processName, info.uid);
3100                    if (app != null) {
3101                        app.bad = false;
3102                    }
3103                }
3104            }
3105        } else {
3106            // If this is an isolated process, it can't re-use an existing process.
3107            app = null;
3108        }
3109
3110        // We don't have to do anything more if:
3111        // (1) There is an existing application record; and
3112        // (2) The caller doesn't think it is dead, OR there is no thread
3113        //     object attached to it so we know it couldn't have crashed; and
3114        // (3) There is a pid assigned to it, so it is either starting or
3115        //     already running.
3116        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3117                + " app=" + app + " knownToBeDead=" + knownToBeDead
3118                + " thread=" + (app != null ? app.thread : null)
3119                + " pid=" + (app != null ? app.pid : -1));
3120        if (app != null && app.pid > 0) {
3121            if (!knownToBeDead || app.thread == null) {
3122                // We already have the app running, or are waiting for it to
3123                // come up (we have a pid but not yet its thread), so keep it.
3124                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3125                // If this is a new package in the process, add the package to the list
3126                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3127                checkTime(startTime, "startProcess: done, added package to proc");
3128                return app;
3129            }
3130
3131            // An application record is attached to a previous process,
3132            // clean it up now.
3133            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3134            checkTime(startTime, "startProcess: bad proc running, killing");
3135            killProcessGroup(app.info.uid, app.pid);
3136            handleAppDiedLocked(app, true, true);
3137            checkTime(startTime, "startProcess: done killing old proc");
3138        }
3139
3140        String hostingNameStr = hostingName != null
3141                ? hostingName.flattenToShortString() : null;
3142
3143        if (app == null) {
3144            checkTime(startTime, "startProcess: creating new process record");
3145            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3146            if (app == null) {
3147                Slog.w(TAG, "Failed making new process record for "
3148                        + processName + "/" + info.uid + " isolated=" + isolated);
3149                return null;
3150            }
3151            app.crashHandler = crashHandler;
3152            checkTime(startTime, "startProcess: done creating new process record");
3153        } else {
3154            // If this is a new package in the process, add the package to the list
3155            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3156            checkTime(startTime, "startProcess: added package to existing proc");
3157        }
3158
3159        // If the system is not ready yet, then hold off on starting this
3160        // process until it is.
3161        if (!mProcessesReady
3162                && !isAllowedWhileBooting(info)
3163                && !allowWhileBooting) {
3164            if (!mProcessesOnHold.contains(app)) {
3165                mProcessesOnHold.add(app);
3166            }
3167            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3168                    "System not ready, putting on hold: " + app);
3169            checkTime(startTime, "startProcess: returning with proc on hold");
3170            return app;
3171        }
3172
3173        checkTime(startTime, "startProcess: stepping in to startProcess");
3174        startProcessLocked(
3175                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3176        checkTime(startTime, "startProcess: done starting proc!");
3177        return (app.pid != 0) ? app : null;
3178    }
3179
3180    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3181        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3182    }
3183
3184    private final void startProcessLocked(ProcessRecord app,
3185            String hostingType, String hostingNameStr) {
3186        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3187                null /* entryPoint */, null /* entryPointArgs */);
3188    }
3189
3190    private final void startProcessLocked(ProcessRecord app, String hostingType,
3191            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3192        long startTime = SystemClock.elapsedRealtime();
3193        if (app.pid > 0 && app.pid != MY_PID) {
3194            checkTime(startTime, "startProcess: removing from pids map");
3195            synchronized (mPidsSelfLocked) {
3196                mPidsSelfLocked.remove(app.pid);
3197                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3198            }
3199            checkTime(startTime, "startProcess: done removing from pids map");
3200            app.setPid(0);
3201        }
3202
3203        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3204                "startProcessLocked removing on hold: " + app);
3205        mProcessesOnHold.remove(app);
3206
3207        checkTime(startTime, "startProcess: starting to update cpu stats");
3208        updateCpuStats();
3209        checkTime(startTime, "startProcess: done updating cpu stats");
3210
3211        try {
3212            try {
3213                if (AppGlobals.getPackageManager().isPackageFrozen(app.info.packageName)) {
3214                    // This is caught below as if we had failed to fork zygote
3215                    throw new RuntimeException("Package " + app.info.packageName + " is frozen!");
3216                }
3217            } catch (RemoteException e) {
3218                throw e.rethrowAsRuntimeException();
3219            }
3220
3221            int uid = app.uid;
3222            int[] gids = null;
3223            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3224            if (!app.isolated) {
3225                int[] permGids = null;
3226                try {
3227                    checkTime(startTime, "startProcess: getting gids from package manager");
3228                    final IPackageManager pm = AppGlobals.getPackageManager();
3229                    permGids = pm.getPackageGids(app.info.packageName, app.userId);
3230                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3231                            MountServiceInternal.class);
3232                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3233                            app.info.packageName);
3234                } catch (RemoteException e) {
3235                    throw e.rethrowAsRuntimeException();
3236                }
3237
3238                /*
3239                 * Add shared application and profile GIDs so applications can share some
3240                 * resources like shared libraries and access user-wide resources
3241                 */
3242                if (ArrayUtils.isEmpty(permGids)) {
3243                    gids = new int[2];
3244                } else {
3245                    gids = new int[permGids.length + 2];
3246                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3247                }
3248                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3249                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3250            }
3251            checkTime(startTime, "startProcess: building args");
3252            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3253                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3254                        && mTopComponent != null
3255                        && app.processName.equals(mTopComponent.getPackageName())) {
3256                    uid = 0;
3257                }
3258                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3259                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3260                    uid = 0;
3261                }
3262            }
3263            int debugFlags = 0;
3264            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3265                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3266                // Also turn on CheckJNI for debuggable apps. It's quite
3267                // awkward to turn on otherwise.
3268                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3269            }
3270            // Run the app in safe mode if its manifest requests so or the
3271            // system is booted in safe mode.
3272            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3273                mSafeMode == true) {
3274                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3275            }
3276            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3277                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3278            }
3279            String jitDebugProperty = SystemProperties.get("debug.usejit");
3280            if ("true".equals(jitDebugProperty)) {
3281                debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3282            } else if (!"false".equals(jitDebugProperty)) {
3283                // If we didn't force disable by setting false, defer to the dalvik vm options.
3284                if ("true".equals(SystemProperties.get("dalvik.vm.usejit"))) {
3285                    debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3286                }
3287            }
3288            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3289            if ("true".equals(genDebugInfoProperty)) {
3290                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3291            }
3292            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3293                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3294            }
3295            if ("1".equals(SystemProperties.get("debug.assert"))) {
3296                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3297            }
3298
3299            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3300            if (requiredAbi == null) {
3301                requiredAbi = Build.SUPPORTED_ABIS[0];
3302            }
3303
3304            String instructionSet = null;
3305            if (app.info.primaryCpuAbi != null) {
3306                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3307            }
3308
3309            app.gids = gids;
3310            app.requiredAbi = requiredAbi;
3311            app.instructionSet = instructionSet;
3312
3313            // Start the process.  It will either succeed and return a result containing
3314            // the PID of the new process, or else throw a RuntimeException.
3315            boolean isActivityProcess = (entryPoint == null);
3316            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3317            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3318                    app.processName);
3319            checkTime(startTime, "startProcess: asking zygote to start proc");
3320            Process.ProcessStartResult startResult = Process.start(entryPoint,
3321                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3322                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3323                    app.info.dataDir, entryPointArgs);
3324            checkTime(startTime, "startProcess: returned from zygote!");
3325            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3326
3327            if (app.isolated) {
3328                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3329            }
3330            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3331            checkTime(startTime, "startProcess: done updating battery stats");
3332
3333            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3334                    UserHandle.getUserId(uid), startResult.pid, uid,
3335                    app.processName, hostingType,
3336                    hostingNameStr != null ? hostingNameStr : "");
3337
3338            if (app.persistent) {
3339                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3340            }
3341
3342            checkTime(startTime, "startProcess: building log message");
3343            StringBuilder buf = mStringBuilder;
3344            buf.setLength(0);
3345            buf.append("Start proc ");
3346            buf.append(startResult.pid);
3347            buf.append(':');
3348            buf.append(app.processName);
3349            buf.append('/');
3350            UserHandle.formatUid(buf, uid);
3351            if (!isActivityProcess) {
3352                buf.append(" [");
3353                buf.append(entryPoint);
3354                buf.append("]");
3355            }
3356            buf.append(" for ");
3357            buf.append(hostingType);
3358            if (hostingNameStr != null) {
3359                buf.append(" ");
3360                buf.append(hostingNameStr);
3361            }
3362            Slog.i(TAG, buf.toString());
3363            app.setPid(startResult.pid);
3364            app.usingWrapper = startResult.usingWrapper;
3365            app.removed = false;
3366            app.killed = false;
3367            app.killedByAm = false;
3368            checkTime(startTime, "startProcess: starting to update pids map");
3369            synchronized (mPidsSelfLocked) {
3370                this.mPidsSelfLocked.put(startResult.pid, app);
3371                if (isActivityProcess) {
3372                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3373                    msg.obj = app;
3374                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3375                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3376                }
3377            }
3378            checkTime(startTime, "startProcess: done updating pids map");
3379        } catch (RuntimeException e) {
3380            // XXX do better error recovery.
3381            app.setPid(0);
3382            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3383            if (app.isolated) {
3384                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3385            }
3386            Slog.e(TAG, "Failure starting process " + app.processName, e);
3387        }
3388    }
3389
3390    void updateUsageStats(ActivityRecord component, boolean resumed) {
3391        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3392                "updateUsageStats: comp=" + component + "res=" + resumed);
3393        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3394        if (resumed) {
3395            if (mUsageStatsService != null) {
3396                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3397                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3398            }
3399            synchronized (stats) {
3400                stats.noteActivityResumedLocked(component.app.uid);
3401            }
3402        } else {
3403            if (mUsageStatsService != null) {
3404                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3405                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3406            }
3407            synchronized (stats) {
3408                stats.noteActivityPausedLocked(component.app.uid);
3409            }
3410        }
3411    }
3412
3413    Intent getHomeIntent() {
3414        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3415        intent.setComponent(mTopComponent);
3416        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3417            intent.addCategory(Intent.CATEGORY_HOME);
3418        }
3419        return intent;
3420    }
3421
3422    boolean startHomeActivityLocked(int userId, String reason) {
3423        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3424                && mTopAction == null) {
3425            // We are running in factory test mode, but unable to find
3426            // the factory test app, so just sit around displaying the
3427            // error message and don't try to start anything.
3428            return false;
3429        }
3430        Intent intent = getHomeIntent();
3431        ActivityInfo aInfo =
3432            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3433        if (aInfo != null) {
3434            intent.setComponent(new ComponentName(
3435                    aInfo.applicationInfo.packageName, aInfo.name));
3436            // Don't do this if the home app is currently being
3437            // instrumented.
3438            aInfo = new ActivityInfo(aInfo);
3439            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3440            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3441                    aInfo.applicationInfo.uid, true);
3442            if (app == null || app.instrumentationClass == null) {
3443                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3444                mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3445            }
3446        }
3447
3448        return true;
3449    }
3450
3451    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3452        ActivityInfo ai = null;
3453        ComponentName comp = intent.getComponent();
3454        try {
3455            if (comp != null) {
3456                // Factory test.
3457                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3458            } else {
3459                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3460                        intent,
3461                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3462                        flags, userId);
3463
3464                if (info != null) {
3465                    ai = info.activityInfo;
3466                }
3467            }
3468        } catch (RemoteException e) {
3469            // ignore
3470        }
3471
3472        return ai;
3473    }
3474
3475    /**
3476     * Starts the "new version setup screen" if appropriate.
3477     */
3478    void startSetupActivityLocked() {
3479        // Only do this once per boot.
3480        if (mCheckedForSetup) {
3481            return;
3482        }
3483
3484        // We will show this screen if the current one is a different
3485        // version than the last one shown, and we are not running in
3486        // low-level factory test mode.
3487        final ContentResolver resolver = mContext.getContentResolver();
3488        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3489                Settings.Global.getInt(resolver,
3490                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3491            mCheckedForSetup = true;
3492
3493            // See if we should be showing the platform update setup UI.
3494            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3495            List<ResolveInfo> ris = mContext.getPackageManager()
3496                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3497
3498            // We don't allow third party apps to replace this.
3499            ResolveInfo ri = null;
3500            for (int i=0; ris != null && i<ris.size(); i++) {
3501                if ((ris.get(i).activityInfo.applicationInfo.flags
3502                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3503                    ri = ris.get(i);
3504                    break;
3505                }
3506            }
3507
3508            if (ri != null) {
3509                String vers = ri.activityInfo.metaData != null
3510                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3511                        : null;
3512                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3513                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3514                            Intent.METADATA_SETUP_VERSION);
3515                }
3516                String lastVers = Settings.Secure.getString(
3517                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3518                if (vers != null && !vers.equals(lastVers)) {
3519                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3520                    intent.setComponent(new ComponentName(
3521                            ri.activityInfo.packageName, ri.activityInfo.name));
3522                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3523                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3524                            null);
3525                }
3526            }
3527        }
3528    }
3529
3530    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3531        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3532    }
3533
3534    void enforceNotIsolatedCaller(String caller) {
3535        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3536            throw new SecurityException("Isolated process not allowed to call " + caller);
3537        }
3538    }
3539
3540    void enforceShellRestriction(String restriction, int userHandle) {
3541        if (Binder.getCallingUid() == Process.SHELL_UID) {
3542            if (userHandle < 0
3543                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3544                throw new SecurityException("Shell does not have permission to access user "
3545                        + userHandle);
3546            }
3547        }
3548    }
3549
3550    @Override
3551    public int getFrontActivityScreenCompatMode() {
3552        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3553        synchronized (this) {
3554            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3555        }
3556    }
3557
3558    @Override
3559    public void setFrontActivityScreenCompatMode(int mode) {
3560        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3561                "setFrontActivityScreenCompatMode");
3562        synchronized (this) {
3563            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3564        }
3565    }
3566
3567    @Override
3568    public int getPackageScreenCompatMode(String packageName) {
3569        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3570        synchronized (this) {
3571            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3572        }
3573    }
3574
3575    @Override
3576    public void setPackageScreenCompatMode(String packageName, int mode) {
3577        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3578                "setPackageScreenCompatMode");
3579        synchronized (this) {
3580            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3581        }
3582    }
3583
3584    @Override
3585    public boolean getPackageAskScreenCompat(String packageName) {
3586        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3587        synchronized (this) {
3588            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3589        }
3590    }
3591
3592    @Override
3593    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3594        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3595                "setPackageAskScreenCompat");
3596        synchronized (this) {
3597            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3598        }
3599    }
3600
3601    private boolean hasUsageStatsPermission(String callingPackage) {
3602        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3603                Binder.getCallingUid(), callingPackage);
3604        if (mode == AppOpsManager.MODE_DEFAULT) {
3605            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3606                    == PackageManager.PERMISSION_GRANTED;
3607        }
3608        return mode == AppOpsManager.MODE_ALLOWED;
3609    }
3610
3611    @Override
3612    public int getPackageProcessState(String packageName, String callingPackage) {
3613        if (!hasUsageStatsPermission(callingPackage)) {
3614            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3615                    "getPackageProcessState");
3616        }
3617
3618        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3619        synchronized (this) {
3620            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3621                final ProcessRecord proc = mLruProcesses.get(i);
3622                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3623                        || procState > proc.setProcState) {
3624                    boolean found = false;
3625                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3626                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3627                            procState = proc.setProcState;
3628                            found = true;
3629                        }
3630                    }
3631                    if (proc.pkgDeps != null && !found) {
3632                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3633                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3634                                procState = proc.setProcState;
3635                                break;
3636                            }
3637                        }
3638                    }
3639                }
3640            }
3641        }
3642        return procState;
3643    }
3644
3645    @Override
3646    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3647        synchronized (this) {
3648            final ProcessRecord app = getProcessRecordLocked(process, userId, true);
3649            if (app == null) {
3650                return false;
3651            }
3652            if (app.trimMemoryLevel < level && app.thread != null &&
3653                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3654                            app.trimMemoryLevel >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN)) {
3655                try {
3656                    app.thread.scheduleTrimMemory(level);
3657                    app.trimMemoryLevel = level;
3658                    return true;
3659                } catch (RemoteException e) {
3660                    // Fallthrough to failure case.
3661                }
3662            }
3663        }
3664        return false;
3665    }
3666
3667    private void dispatchProcessesChanged() {
3668        int N;
3669        synchronized (this) {
3670            N = mPendingProcessChanges.size();
3671            if (mActiveProcessChanges.length < N) {
3672                mActiveProcessChanges = new ProcessChangeItem[N];
3673            }
3674            mPendingProcessChanges.toArray(mActiveProcessChanges);
3675            mPendingProcessChanges.clear();
3676            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3677                    "*** Delivering " + N + " process changes");
3678        }
3679
3680        int i = mProcessObservers.beginBroadcast();
3681        while (i > 0) {
3682            i--;
3683            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3684            if (observer != null) {
3685                try {
3686                    for (int j=0; j<N; j++) {
3687                        ProcessChangeItem item = mActiveProcessChanges[j];
3688                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3689                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3690                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3691                                    + item.uid + ": " + item.foregroundActivities);
3692                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3693                                    item.foregroundActivities);
3694                        }
3695                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3696                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3697                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3698                                    + ": " + item.processState);
3699                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3700                        }
3701                    }
3702                } catch (RemoteException e) {
3703                }
3704            }
3705        }
3706        mProcessObservers.finishBroadcast();
3707
3708        synchronized (this) {
3709            for (int j=0; j<N; j++) {
3710                mAvailProcessChanges.add(mActiveProcessChanges[j]);
3711            }
3712        }
3713    }
3714
3715    private void dispatchProcessDied(int pid, int uid) {
3716        int i = mProcessObservers.beginBroadcast();
3717        while (i > 0) {
3718            i--;
3719            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3720            if (observer != null) {
3721                try {
3722                    observer.onProcessDied(pid, uid);
3723                } catch (RemoteException e) {
3724                }
3725            }
3726        }
3727        mProcessObservers.finishBroadcast();
3728    }
3729
3730    private void dispatchUidsChanged() {
3731        int N;
3732        synchronized (this) {
3733            N = mPendingUidChanges.size();
3734            if (mActiveUidChanges.length < N) {
3735                mActiveUidChanges = new UidRecord.ChangeItem[N];
3736            }
3737            for (int i=0; i<N; i++) {
3738                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3739                mActiveUidChanges[i] = change;
3740                change.uidRecord.pendingChange = null;
3741                change.uidRecord = null;
3742            }
3743            mPendingUidChanges.clear();
3744            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3745                    "*** Delivering " + N + " uid changes");
3746        }
3747
3748        if (mLocalPowerManager != null) {
3749            for (int j=0; j<N; j++) {
3750                UidRecord.ChangeItem item = mActiveUidChanges[j];
3751                if (item.gone) {
3752                    mLocalPowerManager.uidGone(item.uid);
3753                } else {
3754                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
3755                }
3756            }
3757        }
3758
3759        int i = mUidObservers.beginBroadcast();
3760        while (i > 0) {
3761            i--;
3762            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
3763            if (observer != null) {
3764                try {
3765                    for (int j=0; j<N; j++) {
3766                        UidRecord.ChangeItem item = mActiveUidChanges[j];
3767                        if (item.gone) {
3768                            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3769                                    "UID gone uid=" + item.uid);
3770                            observer.onUidGone(item.uid);
3771                        } else {
3772                            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3773                                    "UID CHANGED uid=" + item.uid
3774                                    + ": " + item.processState);
3775                            observer.onUidStateChanged(item.uid, item.processState);
3776                        }
3777                    }
3778                } catch (RemoteException e) {
3779                }
3780            }
3781        }
3782        mUidObservers.finishBroadcast();
3783
3784        synchronized (this) {
3785            for (int j=0; j<N; j++) {
3786                mAvailUidChanges.add(mActiveUidChanges[j]);
3787            }
3788        }
3789    }
3790
3791    @Override
3792    public final int startActivity(IApplicationThread caller, String callingPackage,
3793            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3794            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3795        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3796            resultWho, requestCode, startFlags, profilerInfo, options,
3797            UserHandle.getCallingUserId());
3798    }
3799
3800    @Override
3801    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3802            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3803            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3804        enforceNotIsolatedCaller("startActivity");
3805        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3806                false, ALLOW_FULL_ONLY, "startActivity", null);
3807        // TODO: Switch to user app stacks here.
3808        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3809                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3810                profilerInfo, null, null, options, userId, null, null);
3811    }
3812
3813    @Override
3814    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3815            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3816            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3817
3818        // This is very dangerous -- it allows you to perform a start activity (including
3819        // permission grants) as any app that may launch one of your own activities.  So
3820        // we will only allow this to be done from activities that are part of the core framework,
3821        // and then only when they are running as the system.
3822        final ActivityRecord sourceRecord;
3823        final int targetUid;
3824        final String targetPackage;
3825        synchronized (this) {
3826            if (resultTo == null) {
3827                throw new SecurityException("Must be called from an activity");
3828            }
3829            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3830            if (sourceRecord == null) {
3831                throw new SecurityException("Called with bad activity token: " + resultTo);
3832            }
3833            if (!sourceRecord.info.packageName.equals("android")) {
3834                throw new SecurityException(
3835                        "Must be called from an activity that is declared in the android package");
3836            }
3837            if (sourceRecord.app == null) {
3838                throw new SecurityException("Called without a process attached to activity");
3839            }
3840            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3841                // This is still okay, as long as this activity is running under the
3842                // uid of the original calling activity.
3843                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3844                    throw new SecurityException(
3845                            "Calling activity in uid " + sourceRecord.app.uid
3846                                    + " must be system uid or original calling uid "
3847                                    + sourceRecord.launchedFromUid);
3848                }
3849            }
3850            targetUid = sourceRecord.launchedFromUid;
3851            targetPackage = sourceRecord.launchedFromPackage;
3852        }
3853
3854        if (userId == UserHandle.USER_NULL) {
3855            userId = UserHandle.getUserId(sourceRecord.app.uid);
3856        }
3857
3858        // TODO: Switch to user app stacks here.
3859        try {
3860            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3861                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3862                    null, null, options, userId, null, null);
3863            return ret;
3864        } catch (SecurityException e) {
3865            // XXX need to figure out how to propagate to original app.
3866            // A SecurityException here is generally actually a fault of the original
3867            // calling activity (such as a fairly granting permissions), so propagate it
3868            // back to them.
3869            /*
3870            StringBuilder msg = new StringBuilder();
3871            msg.append("While launching");
3872            msg.append(intent.toString());
3873            msg.append(": ");
3874            msg.append(e.getMessage());
3875            */
3876            throw e;
3877        }
3878    }
3879
3880    @Override
3881    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3882            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3883            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3884        enforceNotIsolatedCaller("startActivityAndWait");
3885        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3886                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3887        WaitResult res = new WaitResult();
3888        // TODO: Switch to user app stacks here.
3889        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3890                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3891                options, userId, null, null);
3892        return res;
3893    }
3894
3895    @Override
3896    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3897            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3898            int startFlags, Configuration config, Bundle options, int userId) {
3899        enforceNotIsolatedCaller("startActivityWithConfig");
3900        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3901                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3902        // TODO: Switch to user app stacks here.
3903        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3904                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3905                null, null, config, options, userId, null, null);
3906        return ret;
3907    }
3908
3909    @Override
3910    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
3911            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
3912            int requestCode, int flagsMask, int flagsValues, Bundle options)
3913            throws TransactionTooLargeException {
3914        enforceNotIsolatedCaller("startActivityIntentSender");
3915        // Refuse possible leaked file descriptors
3916        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3917            throw new IllegalArgumentException("File descriptors passed in Intent");
3918        }
3919
3920        IIntentSender sender = intent.getTarget();
3921        if (!(sender instanceof PendingIntentRecord)) {
3922            throw new IllegalArgumentException("Bad PendingIntent object");
3923        }
3924
3925        PendingIntentRecord pir = (PendingIntentRecord)sender;
3926
3927        synchronized (this) {
3928            // If this is coming from the currently resumed activity, it is
3929            // effectively saying that app switches are allowed at this point.
3930            final ActivityStack stack = getFocusedStack();
3931            if (stack.mResumedActivity != null &&
3932                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3933                mAppSwitchesAllowedTime = 0;
3934            }
3935        }
3936        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3937                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3938        return ret;
3939    }
3940
3941    @Override
3942    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3943            Intent intent, String resolvedType, IVoiceInteractionSession session,
3944            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3945            Bundle options, int userId) {
3946        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3947                != PackageManager.PERMISSION_GRANTED) {
3948            String msg = "Permission Denial: startVoiceActivity() from pid="
3949                    + Binder.getCallingPid()
3950                    + ", uid=" + Binder.getCallingUid()
3951                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3952            Slog.w(TAG, msg);
3953            throw new SecurityException(msg);
3954        }
3955        if (session == null || interactor == null) {
3956            throw new NullPointerException("null session or interactor");
3957        }
3958        userId = handleIncomingUser(callingPid, callingUid, userId,
3959                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3960        // TODO: Switch to user app stacks here.
3961        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3962                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3963                null, options, userId, null, null);
3964    }
3965
3966    @Override
3967    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
3968        synchronized (this) {
3969            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
3970                if (keepAwake) {
3971                    mVoiceWakeLock.acquire();
3972                } else {
3973                    mVoiceWakeLock.release();
3974                }
3975            }
3976        }
3977    }
3978
3979    @Override
3980    public boolean startNextMatchingActivity(IBinder callingActivity,
3981            Intent intent, Bundle options) {
3982        // Refuse possible leaked file descriptors
3983        if (intent != null && intent.hasFileDescriptors() == true) {
3984            throw new IllegalArgumentException("File descriptors passed in Intent");
3985        }
3986
3987        synchronized (this) {
3988            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3989            if (r == null) {
3990                ActivityOptions.abort(options);
3991                return false;
3992            }
3993            if (r.app == null || r.app.thread == null) {
3994                // The caller is not running...  d'oh!
3995                ActivityOptions.abort(options);
3996                return false;
3997            }
3998            intent = new Intent(intent);
3999            // The caller is not allowed to change the data.
4000            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4001            // And we are resetting to find the next component...
4002            intent.setComponent(null);
4003
4004            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4005
4006            ActivityInfo aInfo = null;
4007            try {
4008                List<ResolveInfo> resolves =
4009                    AppGlobals.getPackageManager().queryIntentActivities(
4010                            intent, r.resolvedType,
4011                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4012                            UserHandle.getCallingUserId());
4013
4014                // Look for the original activity in the list...
4015                final int N = resolves != null ? resolves.size() : 0;
4016                for (int i=0; i<N; i++) {
4017                    ResolveInfo rInfo = resolves.get(i);
4018                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4019                            && rInfo.activityInfo.name.equals(r.info.name)) {
4020                        // We found the current one...  the next matching is
4021                        // after it.
4022                        i++;
4023                        if (i<N) {
4024                            aInfo = resolves.get(i).activityInfo;
4025                        }
4026                        if (debug) {
4027                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4028                                    + "/" + r.info.name);
4029                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
4030                                    + "/" + aInfo.name);
4031                        }
4032                        break;
4033                    }
4034                }
4035            } catch (RemoteException e) {
4036            }
4037
4038            if (aInfo == null) {
4039                // Nobody who is next!
4040                ActivityOptions.abort(options);
4041                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4042                return false;
4043            }
4044
4045            intent.setComponent(new ComponentName(
4046                    aInfo.applicationInfo.packageName, aInfo.name));
4047            intent.setFlags(intent.getFlags()&~(
4048                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4049                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4050                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4051                    Intent.FLAG_ACTIVITY_NEW_TASK));
4052
4053            // Okay now we need to start the new activity, replacing the
4054            // currently running activity.  This is a little tricky because
4055            // we want to start the new one as if the current one is finished,
4056            // but not finish the current one first so that there is no flicker.
4057            // And thus...
4058            final boolean wasFinishing = r.finishing;
4059            r.finishing = true;
4060
4061            // Propagate reply information over to the new activity.
4062            final ActivityRecord resultTo = r.resultTo;
4063            final String resultWho = r.resultWho;
4064            final int requestCode = r.requestCode;
4065            r.resultTo = null;
4066            if (resultTo != null) {
4067                resultTo.removeResultsLocked(r, resultWho, requestCode);
4068            }
4069
4070            final long origId = Binder.clearCallingIdentity();
4071            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
4072                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
4073                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
4074                    -1, r.launchedFromUid, 0, options, false, null, null, null);
4075            Binder.restoreCallingIdentity(origId);
4076
4077            r.finishing = wasFinishing;
4078            if (res != ActivityManager.START_SUCCESS) {
4079                return false;
4080            }
4081            return true;
4082        }
4083    }
4084
4085    @Override
4086    public final int startActivityFromRecents(int taskId, Bundle options) {
4087        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4088            String msg = "Permission Denial: startActivityFromRecents called without " +
4089                    START_TASKS_FROM_RECENTS;
4090            Slog.w(TAG, msg);
4091            throw new SecurityException(msg);
4092        }
4093        return startActivityFromRecentsInner(taskId, options);
4094    }
4095
4096    final int startActivityFromRecentsInner(int taskId, Bundle options) {
4097        final TaskRecord task;
4098        final int callingUid;
4099        final String callingPackage;
4100        final Intent intent;
4101        final int userId;
4102        synchronized (this) {
4103            task = mRecentTasks.taskForIdLocked(taskId);
4104            if (task == null) {
4105                throw new IllegalArgumentException("Task " + taskId + " not found.");
4106            }
4107            if (task.getRootActivity() != null) {
4108                moveTaskToFrontLocked(task.taskId, 0, null);
4109                return ActivityManager.START_TASK_TO_FRONT;
4110            }
4111            callingUid = task.mCallingUid;
4112            callingPackage = task.mCallingPackage;
4113            intent = task.intent;
4114            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4115            userId = task.userId;
4116        }
4117        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4118                options, userId, null, task);
4119    }
4120
4121    final int startActivityInPackage(int uid, String callingPackage,
4122            Intent intent, String resolvedType, IBinder resultTo,
4123            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
4124            IActivityContainer container, TaskRecord inTask) {
4125
4126        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4127                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4128
4129        // TODO: Switch to user app stacks here.
4130        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
4131                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4132                null, null, null, options, userId, container, inTask);
4133        return ret;
4134    }
4135
4136    @Override
4137    public final int startActivities(IApplicationThread caller, String callingPackage,
4138            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
4139            int userId) {
4140        enforceNotIsolatedCaller("startActivities");
4141        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4142                false, ALLOW_FULL_ONLY, "startActivity", null);
4143        // TODO: Switch to user app stacks here.
4144        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
4145                resolvedTypes, resultTo, options, userId);
4146        return ret;
4147    }
4148
4149    final int startActivitiesInPackage(int uid, String callingPackage,
4150            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4151            Bundle options, int userId) {
4152
4153        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4154                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4155        // TODO: Switch to user app stacks here.
4156        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4157                resultTo, options, userId);
4158        return ret;
4159    }
4160
4161    @Override
4162    public void reportActivityFullyDrawn(IBinder token) {
4163        synchronized (this) {
4164            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4165            if (r == null) {
4166                return;
4167            }
4168            r.reportFullyDrawnLocked();
4169        }
4170    }
4171
4172    @Override
4173    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4174        synchronized (this) {
4175            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4176            if (r == null) {
4177                return;
4178            }
4179            if (r.task != null && r.task.mResizeable) {
4180                // Fixed screen orientation isn't supported with resizeable activities.
4181                return;
4182            }
4183            final long origId = Binder.clearCallingIdentity();
4184            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4185            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4186                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4187            if (config != null) {
4188                r.frozenBeforeDestroy = true;
4189                if (!updateConfigurationLocked(config, r, false)) {
4190                    mStackSupervisor.resumeTopActivitiesLocked();
4191                }
4192            }
4193            Binder.restoreCallingIdentity(origId);
4194        }
4195    }
4196
4197    @Override
4198    public int getRequestedOrientation(IBinder token) {
4199        synchronized (this) {
4200            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4201            if (r == null) {
4202                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4203            }
4204            return mWindowManager.getAppOrientation(r.appToken);
4205        }
4206    }
4207
4208    /**
4209     * This is the internal entry point for handling Activity.finish().
4210     *
4211     * @param token The Binder token referencing the Activity we want to finish.
4212     * @param resultCode Result code, if any, from this Activity.
4213     * @param resultData Result data (Intent), if any, from this Activity.
4214     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4215     *            the root Activity in the task.
4216     *
4217     * @return Returns true if the activity successfully finished, or false if it is still running.
4218     */
4219    @Override
4220    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4221            boolean finishTask) {
4222        // Refuse possible leaked file descriptors
4223        if (resultData != null && resultData.hasFileDescriptors() == true) {
4224            throw new IllegalArgumentException("File descriptors passed in Intent");
4225        }
4226
4227        synchronized(this) {
4228            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4229            if (r == null) {
4230                return true;
4231            }
4232            // Keep track of the root activity of the task before we finish it
4233            TaskRecord tr = r.task;
4234            ActivityRecord rootR = tr.getRootActivity();
4235            if (rootR == null) {
4236                Slog.w(TAG, "Finishing task with all activities already finished");
4237            }
4238            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4239            // finish.
4240            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4241                    mStackSupervisor.isLastLockedTask(tr)) {
4242                Slog.i(TAG, "Not finishing task in lock task mode");
4243                mStackSupervisor.showLockTaskToast();
4244                return false;
4245            }
4246            if (mController != null) {
4247                // Find the first activity that is not finishing.
4248                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4249                if (next != null) {
4250                    // ask watcher if this is allowed
4251                    boolean resumeOK = true;
4252                    try {
4253                        resumeOK = mController.activityResuming(next.packageName);
4254                    } catch (RemoteException e) {
4255                        mController = null;
4256                        Watchdog.getInstance().setActivityController(null);
4257                    }
4258
4259                    if (!resumeOK) {
4260                        Slog.i(TAG, "Not finishing activity because controller resumed");
4261                        return false;
4262                    }
4263                }
4264            }
4265            final long origId = Binder.clearCallingIdentity();
4266            try {
4267                boolean res;
4268                if (finishTask && r == rootR) {
4269                    // If requested, remove the task that is associated to this activity only if it
4270                    // was the root activity in the task. The result code and data is ignored
4271                    // because we don't support returning them across task boundaries.
4272                    res = removeTaskByIdLocked(tr.taskId, false);
4273                    if (!res) {
4274                        Slog.i(TAG, "Removing task failed to finish activity");
4275                    }
4276                } else {
4277                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4278                            resultData, "app-request", true);
4279                    if (!res) {
4280                        Slog.i(TAG, "Failed to finish by app-request");
4281                    }
4282                }
4283                return res;
4284            } finally {
4285                Binder.restoreCallingIdentity(origId);
4286            }
4287        }
4288    }
4289
4290    @Override
4291    public final void finishHeavyWeightApp() {
4292        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4293                != PackageManager.PERMISSION_GRANTED) {
4294            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4295                    + Binder.getCallingPid()
4296                    + ", uid=" + Binder.getCallingUid()
4297                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4298            Slog.w(TAG, msg);
4299            throw new SecurityException(msg);
4300        }
4301
4302        synchronized(this) {
4303            if (mHeavyWeightProcess == null) {
4304                return;
4305            }
4306
4307            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4308            for (int i = 0; i < activities.size(); i++) {
4309                ActivityRecord r = activities.get(i);
4310                if (!r.finishing && r.isInStackLocked()) {
4311                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4312                            null, "finish-heavy", true);
4313                }
4314            }
4315
4316            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4317                    mHeavyWeightProcess.userId, 0));
4318            mHeavyWeightProcess = null;
4319        }
4320    }
4321
4322    @Override
4323    public void crashApplication(int uid, int initialPid, String packageName,
4324            String message) {
4325        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4326                != PackageManager.PERMISSION_GRANTED) {
4327            String msg = "Permission Denial: crashApplication() from pid="
4328                    + Binder.getCallingPid()
4329                    + ", uid=" + Binder.getCallingUid()
4330                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4331            Slog.w(TAG, msg);
4332            throw new SecurityException(msg);
4333        }
4334
4335        synchronized(this) {
4336            ProcessRecord proc = null;
4337
4338            // Figure out which process to kill.  We don't trust that initialPid
4339            // still has any relation to current pids, so must scan through the
4340            // list.
4341            synchronized (mPidsSelfLocked) {
4342                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4343                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4344                    if (p.uid != uid) {
4345                        continue;
4346                    }
4347                    if (p.pid == initialPid) {
4348                        proc = p;
4349                        break;
4350                    }
4351                    if (p.pkgList.containsKey(packageName)) {
4352                        proc = p;
4353                    }
4354                }
4355            }
4356
4357            if (proc == null) {
4358                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4359                        + " initialPid=" + initialPid
4360                        + " packageName=" + packageName);
4361                return;
4362            }
4363
4364            if (proc.thread != null) {
4365                if (proc.pid == Process.myPid()) {
4366                    Log.w(TAG, "crashApplication: trying to crash self!");
4367                    return;
4368                }
4369                long ident = Binder.clearCallingIdentity();
4370                try {
4371                    proc.thread.scheduleCrash(message);
4372                } catch (RemoteException e) {
4373                }
4374                Binder.restoreCallingIdentity(ident);
4375            }
4376        }
4377    }
4378
4379    @Override
4380    public final void finishSubActivity(IBinder token, String resultWho,
4381            int requestCode) {
4382        synchronized(this) {
4383            final long origId = Binder.clearCallingIdentity();
4384            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4385            if (r != null) {
4386                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4387            }
4388            Binder.restoreCallingIdentity(origId);
4389        }
4390    }
4391
4392    @Override
4393    public boolean finishActivityAffinity(IBinder token) {
4394        synchronized(this) {
4395            final long origId = Binder.clearCallingIdentity();
4396            try {
4397                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4398                if (r == null) {
4399                    return false;
4400                }
4401
4402                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4403                // can finish.
4404                final TaskRecord task = r.task;
4405                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4406                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4407                    mStackSupervisor.showLockTaskToast();
4408                    return false;
4409                }
4410                return task.stack.finishActivityAffinityLocked(r);
4411            } finally {
4412                Binder.restoreCallingIdentity(origId);
4413            }
4414        }
4415    }
4416
4417    @Override
4418    public void finishVoiceTask(IVoiceInteractionSession session) {
4419        synchronized(this) {
4420            final long origId = Binder.clearCallingIdentity();
4421            try {
4422                mStackSupervisor.finishVoiceTask(session);
4423            } finally {
4424                Binder.restoreCallingIdentity(origId);
4425            }
4426        }
4427
4428    }
4429
4430    @Override
4431    public boolean releaseActivityInstance(IBinder token) {
4432        synchronized(this) {
4433            final long origId = Binder.clearCallingIdentity();
4434            try {
4435                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4436                if (r == null) {
4437                    return false;
4438                }
4439                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4440            } finally {
4441                Binder.restoreCallingIdentity(origId);
4442            }
4443        }
4444    }
4445
4446    @Override
4447    public void releaseSomeActivities(IApplicationThread appInt) {
4448        synchronized(this) {
4449            final long origId = Binder.clearCallingIdentity();
4450            try {
4451                ProcessRecord app = getRecordForAppLocked(appInt);
4452                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4453            } finally {
4454                Binder.restoreCallingIdentity(origId);
4455            }
4456        }
4457    }
4458
4459    @Override
4460    public boolean willActivityBeVisible(IBinder token) {
4461        synchronized(this) {
4462            ActivityStack stack = ActivityRecord.getStackLocked(token);
4463            if (stack != null) {
4464                return stack.willActivityBeVisibleLocked(token);
4465            }
4466            return false;
4467        }
4468    }
4469
4470    @Override
4471    public void overridePendingTransition(IBinder token, String packageName,
4472            int enterAnim, int exitAnim) {
4473        synchronized(this) {
4474            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4475            if (self == null) {
4476                return;
4477            }
4478
4479            final long origId = Binder.clearCallingIdentity();
4480
4481            if (self.state == ActivityState.RESUMED
4482                    || self.state == ActivityState.PAUSING) {
4483                mWindowManager.overridePendingAppTransition(packageName,
4484                        enterAnim, exitAnim, null);
4485            }
4486
4487            Binder.restoreCallingIdentity(origId);
4488        }
4489    }
4490
4491    /**
4492     * Main function for removing an existing process from the activity manager
4493     * as a result of that process going away.  Clears out all connections
4494     * to the process.
4495     */
4496    private final void handleAppDiedLocked(ProcessRecord app,
4497            boolean restarting, boolean allowRestart) {
4498        int pid = app.pid;
4499        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4500        if (!kept && !restarting) {
4501            removeLruProcessLocked(app);
4502            if (pid > 0) {
4503                ProcessList.remove(pid);
4504            }
4505        }
4506
4507        if (mProfileProc == app) {
4508            clearProfilerLocked();
4509        }
4510
4511        // Remove this application's activities from active lists.
4512        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4513
4514        app.activities.clear();
4515
4516        if (app.instrumentationClass != null) {
4517            Slog.w(TAG, "Crash of app " + app.processName
4518                  + " running instrumentation " + app.instrumentationClass);
4519            Bundle info = new Bundle();
4520            info.putString("shortMsg", "Process crashed.");
4521            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4522        }
4523
4524        if (!restarting && hasVisibleActivities && !mStackSupervisor.resumeTopActivitiesLocked()) {
4525            // If there was nothing to resume, and we are not already
4526            // restarting this process, but there is a visible activity that
4527            // is hosted by the process...  then make sure all visible
4528            // activities are running, taking care of restarting this
4529            // process.
4530            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4531        }
4532    }
4533
4534    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4535        IBinder threadBinder = thread.asBinder();
4536        // Find the application record.
4537        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4538            ProcessRecord rec = mLruProcesses.get(i);
4539            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4540                return i;
4541            }
4542        }
4543        return -1;
4544    }
4545
4546    final ProcessRecord getRecordForAppLocked(
4547            IApplicationThread thread) {
4548        if (thread == null) {
4549            return null;
4550        }
4551
4552        int appIndex = getLRURecordIndexForAppLocked(thread);
4553        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4554    }
4555
4556    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4557        // If there are no longer any background processes running,
4558        // and the app that died was not running instrumentation,
4559        // then tell everyone we are now low on memory.
4560        boolean haveBg = false;
4561        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4562            ProcessRecord rec = mLruProcesses.get(i);
4563            if (rec.thread != null
4564                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4565                haveBg = true;
4566                break;
4567            }
4568        }
4569
4570        if (!haveBg) {
4571            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4572            if (doReport) {
4573                long now = SystemClock.uptimeMillis();
4574                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4575                    doReport = false;
4576                } else {
4577                    mLastMemUsageReportTime = now;
4578                }
4579            }
4580            final ArrayList<ProcessMemInfo> memInfos
4581                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4582            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4583            long now = SystemClock.uptimeMillis();
4584            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4585                ProcessRecord rec = mLruProcesses.get(i);
4586                if (rec == dyingProc || rec.thread == null) {
4587                    continue;
4588                }
4589                if (doReport) {
4590                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4591                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4592                }
4593                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4594                    // The low memory report is overriding any current
4595                    // state for a GC request.  Make sure to do
4596                    // heavy/important/visible/foreground processes first.
4597                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4598                        rec.lastRequestedGc = 0;
4599                    } else {
4600                        rec.lastRequestedGc = rec.lastLowMemory;
4601                    }
4602                    rec.reportLowMemory = true;
4603                    rec.lastLowMemory = now;
4604                    mProcessesToGc.remove(rec);
4605                    addProcessToGcListLocked(rec);
4606                }
4607            }
4608            if (doReport) {
4609                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4610                mHandler.sendMessage(msg);
4611            }
4612            scheduleAppGcsLocked();
4613        }
4614    }
4615
4616    final void appDiedLocked(ProcessRecord app) {
4617       appDiedLocked(app, app.pid, app.thread, false);
4618    }
4619
4620    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4621            boolean fromBinderDied) {
4622        // First check if this ProcessRecord is actually active for the pid.
4623        synchronized (mPidsSelfLocked) {
4624            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4625            if (curProc != app) {
4626                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4627                return;
4628            }
4629        }
4630
4631        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4632        synchronized (stats) {
4633            stats.noteProcessDiedLocked(app.info.uid, pid);
4634        }
4635
4636        if (!app.killed) {
4637            if (!fromBinderDied) {
4638                Process.killProcessQuiet(pid);
4639            }
4640            killProcessGroup(app.info.uid, pid);
4641            app.killed = true;
4642        }
4643
4644        // Clean up already done if the process has been re-started.
4645        if (app.pid == pid && app.thread != null &&
4646                app.thread.asBinder() == thread.asBinder()) {
4647            boolean doLowMem = app.instrumentationClass == null;
4648            boolean doOomAdj = doLowMem;
4649            if (!app.killedByAm) {
4650                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4651                        + ") has died");
4652                mAllowLowerMemLevel = true;
4653            } else {
4654                // Note that we always want to do oom adj to update our state with the
4655                // new number of procs.
4656                mAllowLowerMemLevel = false;
4657                doLowMem = false;
4658            }
4659            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4660            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4661                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
4662            handleAppDiedLocked(app, false, true);
4663
4664            if (doOomAdj) {
4665                updateOomAdjLocked();
4666            }
4667            if (doLowMem) {
4668                doLowMemReportIfNeededLocked(app);
4669            }
4670        } else if (app.pid != pid) {
4671            // A new process has already been started.
4672            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4673                    + ") has died and restarted (pid " + app.pid + ").");
4674            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4675        } else if (DEBUG_PROCESSES) {
4676            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
4677                    + thread.asBinder());
4678        }
4679    }
4680
4681    /**
4682     * If a stack trace dump file is configured, dump process stack traces.
4683     * @param clearTraces causes the dump file to be erased prior to the new
4684     *    traces being written, if true; when false, the new traces will be
4685     *    appended to any existing file content.
4686     * @param firstPids of dalvik VM processes to dump stack traces for first
4687     * @param lastPids of dalvik VM processes to dump stack traces for last
4688     * @param nativeProcs optional list of native process names to dump stack crawls
4689     * @return file containing stack traces, or null if no dump file is configured
4690     */
4691    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4692            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4693        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4694        if (tracesPath == null || tracesPath.length() == 0) {
4695            return null;
4696        }
4697
4698        File tracesFile = new File(tracesPath);
4699        try {
4700            File tracesDir = tracesFile.getParentFile();
4701            if (!tracesDir.exists()) {
4702                tracesDir.mkdirs();
4703                if (!SELinux.restorecon(tracesDir)) {
4704                    return null;
4705                }
4706            }
4707            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4708
4709            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4710            tracesFile.createNewFile();
4711            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4712        } catch (IOException e) {
4713            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4714            return null;
4715        }
4716
4717        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4718        return tracesFile;
4719    }
4720
4721    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4722            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4723        // Use a FileObserver to detect when traces finish writing.
4724        // The order of traces is considered important to maintain for legibility.
4725        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4726            @Override
4727            public synchronized void onEvent(int event, String path) { notify(); }
4728        };
4729
4730        try {
4731            observer.startWatching();
4732
4733            // First collect all of the stacks of the most important pids.
4734            if (firstPids != null) {
4735                try {
4736                    int num = firstPids.size();
4737                    for (int i = 0; i < num; i++) {
4738                        synchronized (observer) {
4739                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4740                            observer.wait(200);  // Wait for write-close, give up after 200msec
4741                        }
4742                    }
4743                } catch (InterruptedException e) {
4744                    Slog.wtf(TAG, e);
4745                }
4746            }
4747
4748            // Next collect the stacks of the native pids
4749            if (nativeProcs != null) {
4750                int[] pids = Process.getPidsForCommands(nativeProcs);
4751                if (pids != null) {
4752                    for (int pid : pids) {
4753                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4754                    }
4755                }
4756            }
4757
4758            // Lastly, measure CPU usage.
4759            if (processCpuTracker != null) {
4760                processCpuTracker.init();
4761                System.gc();
4762                processCpuTracker.update();
4763                try {
4764                    synchronized (processCpuTracker) {
4765                        processCpuTracker.wait(500); // measure over 1/2 second.
4766                    }
4767                } catch (InterruptedException e) {
4768                }
4769                processCpuTracker.update();
4770
4771                // We'll take the stack crawls of just the top apps using CPU.
4772                final int N = processCpuTracker.countWorkingStats();
4773                int numProcs = 0;
4774                for (int i=0; i<N && numProcs<5; i++) {
4775                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4776                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4777                        numProcs++;
4778                        try {
4779                            synchronized (observer) {
4780                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4781                                observer.wait(200);  // Wait for write-close, give up after 200msec
4782                            }
4783                        } catch (InterruptedException e) {
4784                            Slog.wtf(TAG, e);
4785                        }
4786
4787                    }
4788                }
4789            }
4790        } finally {
4791            observer.stopWatching();
4792        }
4793    }
4794
4795    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4796        if (true || IS_USER_BUILD) {
4797            return;
4798        }
4799        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4800        if (tracesPath == null || tracesPath.length() == 0) {
4801            return;
4802        }
4803
4804        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4805        StrictMode.allowThreadDiskWrites();
4806        try {
4807            final File tracesFile = new File(tracesPath);
4808            final File tracesDir = tracesFile.getParentFile();
4809            final File tracesTmp = new File(tracesDir, "__tmp__");
4810            try {
4811                if (!tracesDir.exists()) {
4812                    tracesDir.mkdirs();
4813                    if (!SELinux.restorecon(tracesDir.getPath())) {
4814                        return;
4815                    }
4816                }
4817                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4818
4819                if (tracesFile.exists()) {
4820                    tracesTmp.delete();
4821                    tracesFile.renameTo(tracesTmp);
4822                }
4823                StringBuilder sb = new StringBuilder();
4824                Time tobj = new Time();
4825                tobj.set(System.currentTimeMillis());
4826                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4827                sb.append(": ");
4828                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4829                sb.append(" since ");
4830                sb.append(msg);
4831                FileOutputStream fos = new FileOutputStream(tracesFile);
4832                fos.write(sb.toString().getBytes());
4833                if (app == null) {
4834                    fos.write("\n*** No application process!".getBytes());
4835                }
4836                fos.close();
4837                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4838            } catch (IOException e) {
4839                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4840                return;
4841            }
4842
4843            if (app != null) {
4844                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4845                firstPids.add(app.pid);
4846                dumpStackTraces(tracesPath, firstPids, null, null, null);
4847            }
4848
4849            File lastTracesFile = null;
4850            File curTracesFile = null;
4851            for (int i=9; i>=0; i--) {
4852                String name = String.format(Locale.US, "slow%02d.txt", i);
4853                curTracesFile = new File(tracesDir, name);
4854                if (curTracesFile.exists()) {
4855                    if (lastTracesFile != null) {
4856                        curTracesFile.renameTo(lastTracesFile);
4857                    } else {
4858                        curTracesFile.delete();
4859                    }
4860                }
4861                lastTracesFile = curTracesFile;
4862            }
4863            tracesFile.renameTo(curTracesFile);
4864            if (tracesTmp.exists()) {
4865                tracesTmp.renameTo(tracesFile);
4866            }
4867        } finally {
4868            StrictMode.setThreadPolicy(oldPolicy);
4869        }
4870    }
4871
4872    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4873            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4874        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4875        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4876
4877        if (mController != null) {
4878            try {
4879                // 0 == continue, -1 = kill process immediately
4880                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4881                if (res < 0 && app.pid != MY_PID) {
4882                    app.kill("anr", true);
4883                }
4884            } catch (RemoteException e) {
4885                mController = null;
4886                Watchdog.getInstance().setActivityController(null);
4887            }
4888        }
4889
4890        long anrTime = SystemClock.uptimeMillis();
4891        if (MONITOR_CPU_USAGE) {
4892            updateCpuStatsNow();
4893        }
4894
4895        synchronized (this) {
4896            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4897            if (mShuttingDown) {
4898                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4899                return;
4900            } else if (app.notResponding) {
4901                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4902                return;
4903            } else if (app.crashing) {
4904                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4905                return;
4906            }
4907
4908            // In case we come through here for the same app before completing
4909            // this one, mark as anring now so we will bail out.
4910            app.notResponding = true;
4911
4912            // Log the ANR to the event log.
4913            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4914                    app.processName, app.info.flags, annotation);
4915
4916            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4917            firstPids.add(app.pid);
4918
4919            int parentPid = app.pid;
4920            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4921            if (parentPid != app.pid) firstPids.add(parentPid);
4922
4923            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4924
4925            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4926                ProcessRecord r = mLruProcesses.get(i);
4927                if (r != null && r.thread != null) {
4928                    int pid = r.pid;
4929                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4930                        if (r.persistent) {
4931                            firstPids.add(pid);
4932                        } else {
4933                            lastPids.put(pid, Boolean.TRUE);
4934                        }
4935                    }
4936                }
4937            }
4938        }
4939
4940        // Log the ANR to the main log.
4941        StringBuilder info = new StringBuilder();
4942        info.setLength(0);
4943        info.append("ANR in ").append(app.processName);
4944        if (activity != null && activity.shortComponentName != null) {
4945            info.append(" (").append(activity.shortComponentName).append(")");
4946        }
4947        info.append("\n");
4948        info.append("PID: ").append(app.pid).append("\n");
4949        if (annotation != null) {
4950            info.append("Reason: ").append(annotation).append("\n");
4951        }
4952        if (parent != null && parent != activity) {
4953            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4954        }
4955
4956        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4957
4958        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4959                NATIVE_STACKS_OF_INTEREST);
4960
4961        String cpuInfo = null;
4962        if (MONITOR_CPU_USAGE) {
4963            updateCpuStatsNow();
4964            synchronized (mProcessCpuTracker) {
4965                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4966            }
4967            info.append(processCpuTracker.printCurrentLoad());
4968            info.append(cpuInfo);
4969        }
4970
4971        info.append(processCpuTracker.printCurrentState(anrTime));
4972
4973        Slog.e(TAG, info.toString());
4974        if (tracesFile == null) {
4975            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4976            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4977        }
4978
4979        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4980                cpuInfo, tracesFile, null);
4981
4982        if (mController != null) {
4983            try {
4984                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4985                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4986                if (res != 0) {
4987                    if (res < 0 && app.pid != MY_PID) {
4988                        app.kill("anr", true);
4989                    } else {
4990                        synchronized (this) {
4991                            mServices.scheduleServiceTimeoutLocked(app);
4992                        }
4993                    }
4994                    return;
4995                }
4996            } catch (RemoteException e) {
4997                mController = null;
4998                Watchdog.getInstance().setActivityController(null);
4999            }
5000        }
5001
5002        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5003        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5004                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5005
5006        synchronized (this) {
5007            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5008
5009            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5010                app.kill("bg anr", true);
5011                return;
5012            }
5013
5014            // Set the app's notResponding state, and look up the errorReportReceiver
5015            makeAppNotRespondingLocked(app,
5016                    activity != null ? activity.shortComponentName : null,
5017                    annotation != null ? "ANR " + annotation : "ANR",
5018                    info.toString());
5019
5020            // Bring up the infamous App Not Responding dialog
5021            Message msg = Message.obtain();
5022            HashMap<String, Object> map = new HashMap<String, Object>();
5023            msg.what = SHOW_NOT_RESPONDING_MSG;
5024            msg.obj = map;
5025            msg.arg1 = aboveSystem ? 1 : 0;
5026            map.put("app", app);
5027            if (activity != null) {
5028                map.put("activity", activity);
5029            }
5030
5031            mUiHandler.sendMessage(msg);
5032        }
5033    }
5034
5035    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5036        if (!mLaunchWarningShown) {
5037            mLaunchWarningShown = true;
5038            mUiHandler.post(new Runnable() {
5039                @Override
5040                public void run() {
5041                    synchronized (ActivityManagerService.this) {
5042                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5043                        d.show();
5044                        mUiHandler.postDelayed(new Runnable() {
5045                            @Override
5046                            public void run() {
5047                                synchronized (ActivityManagerService.this) {
5048                                    d.dismiss();
5049                                    mLaunchWarningShown = false;
5050                                }
5051                            }
5052                        }, 4000);
5053                    }
5054                }
5055            });
5056        }
5057    }
5058
5059    @Override
5060    public boolean clearApplicationUserData(final String packageName,
5061            final IPackageDataObserver observer, int userId) {
5062        enforceNotIsolatedCaller("clearApplicationUserData");
5063        if (packageName != null && packageName.equals(mDeviceOwnerName)) {
5064            throw new SecurityException("Clearing DeviceOwner data is forbidden.");
5065        }
5066        int uid = Binder.getCallingUid();
5067        int pid = Binder.getCallingPid();
5068        userId = handleIncomingUser(pid, uid,
5069                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5070        long callingId = Binder.clearCallingIdentity();
5071        try {
5072            IPackageManager pm = AppGlobals.getPackageManager();
5073            int pkgUid = -1;
5074            synchronized(this) {
5075                try {
5076                    pkgUid = pm.getPackageUid(packageName, userId);
5077                } catch (RemoteException e) {
5078                }
5079                if (pkgUid == -1) {
5080                    Slog.w(TAG, "Invalid packageName: " + packageName);
5081                    if (observer != null) {
5082                        try {
5083                            observer.onRemoveCompleted(packageName, false);
5084                        } catch (RemoteException e) {
5085                            Slog.i(TAG, "Observer no longer exists.");
5086                        }
5087                    }
5088                    return false;
5089                }
5090                if (uid == pkgUid || checkComponentPermission(
5091                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5092                        pid, uid, -1, true)
5093                        == PackageManager.PERMISSION_GRANTED) {
5094                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5095                } else {
5096                    throw new SecurityException("PID " + pid + " does not have permission "
5097                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5098                                    + " of package " + packageName);
5099                }
5100
5101                // Remove all tasks match the cleared application package and user
5102                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5103                    final TaskRecord tr = mRecentTasks.get(i);
5104                    final String taskPackageName =
5105                            tr.getBaseIntent().getComponent().getPackageName();
5106                    if (tr.userId != userId) continue;
5107                    if (!taskPackageName.equals(packageName)) continue;
5108                    removeTaskByIdLocked(tr.taskId, false);
5109                }
5110            }
5111
5112            try {
5113                // Clear application user data
5114                pm.clearApplicationUserData(packageName, observer, userId);
5115
5116                synchronized(this) {
5117                    // Remove all permissions granted from/to this package
5118                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5119                }
5120
5121                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5122                        Uri.fromParts("package", packageName, null));
5123                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5124                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5125                        null, null, 0, null, null, null, null, false, false, userId);
5126            } catch (RemoteException e) {
5127            }
5128        } finally {
5129            Binder.restoreCallingIdentity(callingId);
5130        }
5131        return true;
5132    }
5133
5134    @Override
5135    public void killBackgroundProcesses(final String packageName, int userId) {
5136        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5137                != PackageManager.PERMISSION_GRANTED &&
5138                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5139                        != PackageManager.PERMISSION_GRANTED) {
5140            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5141                    + Binder.getCallingPid()
5142                    + ", uid=" + Binder.getCallingUid()
5143                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5144            Slog.w(TAG, msg);
5145            throw new SecurityException(msg);
5146        }
5147
5148        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5149                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5150        long callingId = Binder.clearCallingIdentity();
5151        try {
5152            IPackageManager pm = AppGlobals.getPackageManager();
5153            synchronized(this) {
5154                int appId = -1;
5155                try {
5156                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5157                } catch (RemoteException e) {
5158                }
5159                if (appId == -1) {
5160                    Slog.w(TAG, "Invalid packageName: " + packageName);
5161                    return;
5162                }
5163                killPackageProcessesLocked(packageName, appId, userId,
5164                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5165            }
5166        } finally {
5167            Binder.restoreCallingIdentity(callingId);
5168        }
5169    }
5170
5171    @Override
5172    public void killAllBackgroundProcesses() {
5173        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5174                != PackageManager.PERMISSION_GRANTED) {
5175            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5176                    + Binder.getCallingPid()
5177                    + ", uid=" + Binder.getCallingUid()
5178                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5179            Slog.w(TAG, msg);
5180            throw new SecurityException(msg);
5181        }
5182
5183        long callingId = Binder.clearCallingIdentity();
5184        try {
5185            synchronized(this) {
5186                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5187                final int NP = mProcessNames.getMap().size();
5188                for (int ip=0; ip<NP; ip++) {
5189                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5190                    final int NA = apps.size();
5191                    for (int ia=0; ia<NA; ia++) {
5192                        ProcessRecord app = apps.valueAt(ia);
5193                        if (app.persistent) {
5194                            // we don't kill persistent processes
5195                            continue;
5196                        }
5197                        if (app.removed) {
5198                            procs.add(app);
5199                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5200                            app.removed = true;
5201                            procs.add(app);
5202                        }
5203                    }
5204                }
5205
5206                int N = procs.size();
5207                for (int i=0; i<N; i++) {
5208                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5209                }
5210                mAllowLowerMemLevel = true;
5211                updateOomAdjLocked();
5212                doLowMemReportIfNeededLocked(null);
5213            }
5214        } finally {
5215            Binder.restoreCallingIdentity(callingId);
5216        }
5217    }
5218
5219    @Override
5220    public void forceStopPackage(final String packageName, int userId) {
5221        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5222                != PackageManager.PERMISSION_GRANTED) {
5223            String msg = "Permission Denial: forceStopPackage() from pid="
5224                    + Binder.getCallingPid()
5225                    + ", uid=" + Binder.getCallingUid()
5226                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5227            Slog.w(TAG, msg);
5228            throw new SecurityException(msg);
5229        }
5230        final int callingPid = Binder.getCallingPid();
5231        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5232                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5233        long callingId = Binder.clearCallingIdentity();
5234        try {
5235            IPackageManager pm = AppGlobals.getPackageManager();
5236            synchronized(this) {
5237                int[] users = userId == UserHandle.USER_ALL
5238                        ? getUsersLocked() : new int[] { userId };
5239                for (int user : users) {
5240                    int pkgUid = -1;
5241                    try {
5242                        pkgUid = pm.getPackageUid(packageName, user);
5243                    } catch (RemoteException e) {
5244                    }
5245                    if (pkgUid == -1) {
5246                        Slog.w(TAG, "Invalid packageName: " + packageName);
5247                        continue;
5248                    }
5249                    try {
5250                        pm.setPackageStoppedState(packageName, true, user);
5251                    } catch (RemoteException e) {
5252                    } catch (IllegalArgumentException e) {
5253                        Slog.w(TAG, "Failed trying to unstop package "
5254                                + packageName + ": " + e);
5255                    }
5256                    if (isUserRunningLocked(user, false)) {
5257                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5258                    }
5259                }
5260            }
5261        } finally {
5262            Binder.restoreCallingIdentity(callingId);
5263        }
5264    }
5265
5266    @Override
5267    public void addPackageDependency(String packageName) {
5268        synchronized (this) {
5269            int callingPid = Binder.getCallingPid();
5270            if (callingPid == Process.myPid()) {
5271                //  Yeah, um, no.
5272                return;
5273            }
5274            ProcessRecord proc;
5275            synchronized (mPidsSelfLocked) {
5276                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5277            }
5278            if (proc != null) {
5279                if (proc.pkgDeps == null) {
5280                    proc.pkgDeps = new ArraySet<String>(1);
5281                }
5282                proc.pkgDeps.add(packageName);
5283            }
5284        }
5285    }
5286
5287    /*
5288     * The pkg name and app id have to be specified.
5289     */
5290    @Override
5291    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5292        if (pkg == null) {
5293            return;
5294        }
5295        // Make sure the uid is valid.
5296        if (appid < 0) {
5297            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5298            return;
5299        }
5300        int callerUid = Binder.getCallingUid();
5301        // Only the system server can kill an application
5302        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5303            // Post an aysnc message to kill the application
5304            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5305            msg.arg1 = appid;
5306            msg.arg2 = 0;
5307            Bundle bundle = new Bundle();
5308            bundle.putString("pkg", pkg);
5309            bundle.putString("reason", reason);
5310            msg.obj = bundle;
5311            mHandler.sendMessage(msg);
5312        } else {
5313            throw new SecurityException(callerUid + " cannot kill pkg: " +
5314                    pkg);
5315        }
5316    }
5317
5318    @Override
5319    public void closeSystemDialogs(String reason) {
5320        enforceNotIsolatedCaller("closeSystemDialogs");
5321
5322        final int pid = Binder.getCallingPid();
5323        final int uid = Binder.getCallingUid();
5324        final long origId = Binder.clearCallingIdentity();
5325        try {
5326            synchronized (this) {
5327                // Only allow this from foreground processes, so that background
5328                // applications can't abuse it to prevent system UI from being shown.
5329                if (uid >= Process.FIRST_APPLICATION_UID) {
5330                    ProcessRecord proc;
5331                    synchronized (mPidsSelfLocked) {
5332                        proc = mPidsSelfLocked.get(pid);
5333                    }
5334                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5335                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5336                                + " from background process " + proc);
5337                        return;
5338                    }
5339                }
5340                closeSystemDialogsLocked(reason);
5341            }
5342        } finally {
5343            Binder.restoreCallingIdentity(origId);
5344        }
5345    }
5346
5347    void closeSystemDialogsLocked(String reason) {
5348        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5349        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5350                | Intent.FLAG_RECEIVER_FOREGROUND);
5351        if (reason != null) {
5352            intent.putExtra("reason", reason);
5353        }
5354        mWindowManager.closeSystemDialogs(reason);
5355
5356        mStackSupervisor.closeSystemDialogsLocked();
5357
5358        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5359                AppOpsManager.OP_NONE, null, false, false,
5360                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5361    }
5362
5363    @Override
5364    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5365        enforceNotIsolatedCaller("getProcessMemoryInfo");
5366        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5367        for (int i=pids.length-1; i>=0; i--) {
5368            ProcessRecord proc;
5369            int oomAdj;
5370            synchronized (this) {
5371                synchronized (mPidsSelfLocked) {
5372                    proc = mPidsSelfLocked.get(pids[i]);
5373                    oomAdj = proc != null ? proc.setAdj : 0;
5374                }
5375            }
5376            infos[i] = new Debug.MemoryInfo();
5377            Debug.getMemoryInfo(pids[i], infos[i]);
5378            if (proc != null) {
5379                synchronized (this) {
5380                    if (proc.thread != null && proc.setAdj == oomAdj) {
5381                        // Record this for posterity if the process has been stable.
5382                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5383                                infos[i].getTotalUss(), false, proc.pkgList);
5384                    }
5385                }
5386            }
5387        }
5388        return infos;
5389    }
5390
5391    @Override
5392    public long[] getProcessPss(int[] pids) {
5393        enforceNotIsolatedCaller("getProcessPss");
5394        long[] pss = new long[pids.length];
5395        for (int i=pids.length-1; i>=0; i--) {
5396            ProcessRecord proc;
5397            int oomAdj;
5398            synchronized (this) {
5399                synchronized (mPidsSelfLocked) {
5400                    proc = mPidsSelfLocked.get(pids[i]);
5401                    oomAdj = proc != null ? proc.setAdj : 0;
5402                }
5403            }
5404            long[] tmpUss = new long[1];
5405            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5406            if (proc != null) {
5407                synchronized (this) {
5408                    if (proc.thread != null && proc.setAdj == oomAdj) {
5409                        // Record this for posterity if the process has been stable.
5410                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5411                    }
5412                }
5413            }
5414        }
5415        return pss;
5416    }
5417
5418    @Override
5419    public void killApplicationProcess(String processName, int uid) {
5420        if (processName == null) {
5421            return;
5422        }
5423
5424        int callerUid = Binder.getCallingUid();
5425        // Only the system server can kill an application
5426        if (callerUid == Process.SYSTEM_UID) {
5427            synchronized (this) {
5428                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5429                if (app != null && app.thread != null) {
5430                    try {
5431                        app.thread.scheduleSuicide();
5432                    } catch (RemoteException e) {
5433                        // If the other end already died, then our work here is done.
5434                    }
5435                } else {
5436                    Slog.w(TAG, "Process/uid not found attempting kill of "
5437                            + processName + " / " + uid);
5438                }
5439            }
5440        } else {
5441            throw new SecurityException(callerUid + " cannot kill app process: " +
5442                    processName);
5443        }
5444    }
5445
5446    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5447        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5448                false, true, false, false, UserHandle.getUserId(uid), reason);
5449        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5450                Uri.fromParts("package", packageName, null));
5451        if (!mProcessesReady) {
5452            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5453                    | Intent.FLAG_RECEIVER_FOREGROUND);
5454        }
5455        intent.putExtra(Intent.EXTRA_UID, uid);
5456        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5457        broadcastIntentLocked(null, null, intent,
5458                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5459                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5460    }
5461
5462    private void forceStopUserLocked(int userId, String reason) {
5463        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5464        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5465        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5466                | Intent.FLAG_RECEIVER_FOREGROUND);
5467        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5468        broadcastIntentLocked(null, null, intent,
5469                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5470                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5471    }
5472
5473    private final boolean killPackageProcessesLocked(String packageName, int appId,
5474            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5475            boolean doit, boolean evenPersistent, String reason) {
5476        ArrayList<ProcessRecord> procs = new ArrayList<>();
5477
5478        // Remove all processes this package may have touched: all with the
5479        // same UID (except for the system or root user), and all whose name
5480        // matches the package name.
5481        final int NP = mProcessNames.getMap().size();
5482        for (int ip=0; ip<NP; ip++) {
5483            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5484            final int NA = apps.size();
5485            for (int ia=0; ia<NA; ia++) {
5486                ProcessRecord app = apps.valueAt(ia);
5487                if (app.persistent && !evenPersistent) {
5488                    // we don't kill persistent processes
5489                    continue;
5490                }
5491                if (app.removed) {
5492                    if (doit) {
5493                        procs.add(app);
5494                    }
5495                    continue;
5496                }
5497
5498                // Skip process if it doesn't meet our oom adj requirement.
5499                if (app.setAdj < minOomAdj) {
5500                    continue;
5501                }
5502
5503                // If no package is specified, we call all processes under the
5504                // give user id.
5505                if (packageName == null) {
5506                    if (app.userId != userId) {
5507                        continue;
5508                    }
5509                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5510                        continue;
5511                    }
5512                // Package has been specified, we want to hit all processes
5513                // that match it.  We need to qualify this by the processes
5514                // that are running under the specified app and user ID.
5515                } else {
5516                    final boolean isDep = app.pkgDeps != null
5517                            && app.pkgDeps.contains(packageName);
5518                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5519                        continue;
5520                    }
5521                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5522                        continue;
5523                    }
5524                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5525                        continue;
5526                    }
5527                }
5528
5529                // Process has passed all conditions, kill it!
5530                if (!doit) {
5531                    return true;
5532                }
5533                app.removed = true;
5534                procs.add(app);
5535            }
5536        }
5537
5538        int N = procs.size();
5539        for (int i=0; i<N; i++) {
5540            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5541        }
5542        updateOomAdjLocked();
5543        return N > 0;
5544    }
5545
5546    private void cleanupDisabledPackageComponentsLocked(
5547            String packageName, int userId, String[] changedClasses) {
5548
5549        Set<String> disabledClasses = null;
5550        boolean packageDisabled = false;
5551        IPackageManager pm = AppGlobals.getPackageManager();
5552
5553        if (changedClasses == null) {
5554            // Nothing changed...
5555            return;
5556        }
5557
5558        // Determine enable/disable state of the package and its components.
5559        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5560        for (int i = changedClasses.length - 1; i >= 0; i--) {
5561            final String changedClass = changedClasses[i];
5562
5563            if (changedClass.equals(packageName)) {
5564                try {
5565                    // Entire package setting changed
5566                    enabled = pm.getApplicationEnabledSetting(packageName,
5567                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5568                } catch (Exception e) {
5569                    // No such package/component; probably racing with uninstall.  In any
5570                    // event it means we have nothing further to do here.
5571                    return;
5572                }
5573                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5574                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5575                if (packageDisabled) {
5576                    // Entire package is disabled.
5577                    // No need to continue to check component states.
5578                    disabledClasses = null;
5579                    break;
5580                }
5581            } else {
5582                try {
5583                    enabled = pm.getComponentEnabledSetting(
5584                            new ComponentName(packageName, changedClass),
5585                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5586                } catch (Exception e) {
5587                    // As above, probably racing with uninstall.
5588                    return;
5589                }
5590                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5591                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5592                    if (disabledClasses == null) {
5593                        disabledClasses = new ArraySet<>(changedClasses.length);
5594                    }
5595                    disabledClasses.add(changedClass);
5596                }
5597            }
5598        }
5599
5600        if (!packageDisabled && disabledClasses == null) {
5601            // Nothing to do here...
5602            return;
5603        }
5604
5605        // Clean-up disabled activities.
5606        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5607                packageName, disabledClasses, true, false, userId) && mBooted) {
5608            mStackSupervisor.resumeTopActivitiesLocked();
5609            mStackSupervisor.scheduleIdleLocked();
5610        }
5611
5612        // Clean-up disabled tasks
5613        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5614
5615        // Clean-up disabled services.
5616        mServices.bringDownDisabledPackageServicesLocked(
5617                packageName, disabledClasses, userId, false, true);
5618
5619        // Clean-up disabled providers.
5620        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5621        mProviderMap.collectPackageProvidersLocked(
5622                packageName, disabledClasses, true, false, userId, providers);
5623        for (int i = providers.size() - 1; i >= 0; i--) {
5624            removeDyingProviderLocked(null, providers.get(i), true);
5625        }
5626
5627        // Clean-up disabled broadcast receivers.
5628        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5629            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5630                    packageName, disabledClasses, userId, true);
5631        }
5632
5633    }
5634
5635    private final boolean forceStopPackageLocked(String packageName, int appId,
5636            boolean callerWillRestart, boolean purgeCache, boolean doit,
5637            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5638        int i;
5639
5640        if (userId == UserHandle.USER_ALL && packageName == null) {
5641            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5642        }
5643
5644        if (appId < 0 && packageName != null) {
5645            try {
5646                appId = UserHandle.getAppId(
5647                        AppGlobals.getPackageManager().getPackageUid(packageName, 0));
5648            } catch (RemoteException e) {
5649            }
5650        }
5651
5652        if (doit) {
5653            if (packageName != null) {
5654                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5655                        + " user=" + userId + ": " + reason);
5656            } else {
5657                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5658            }
5659
5660            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5661            for (int ip = pmap.size() - 1; ip >= 0; ip--) {
5662                SparseArray<Long> ba = pmap.valueAt(ip);
5663                for (i = ba.size() - 1; i >= 0; i--) {
5664                    boolean remove = false;
5665                    final int entUid = ba.keyAt(i);
5666                    if (packageName != null) {
5667                        if (userId == UserHandle.USER_ALL) {
5668                            if (UserHandle.getAppId(entUid) == appId) {
5669                                remove = true;
5670                            }
5671                        } else {
5672                            if (entUid == UserHandle.getUid(userId, appId)) {
5673                                remove = true;
5674                            }
5675                        }
5676                    } else if (UserHandle.getUserId(entUid) == userId) {
5677                        remove = true;
5678                    }
5679                    if (remove) {
5680                        ba.removeAt(i);
5681                    }
5682                }
5683                if (ba.size() == 0) {
5684                    pmap.removeAt(ip);
5685                }
5686            }
5687        }
5688
5689        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5690                -100, callerWillRestart, true, doit, evenPersistent,
5691                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5692
5693        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5694                packageName, null, doit, evenPersistent, userId)) {
5695            if (!doit) {
5696                return true;
5697            }
5698            didSomething = true;
5699        }
5700
5701        if (mServices.bringDownDisabledPackageServicesLocked(
5702                packageName, null, userId, evenPersistent, doit)) {
5703            if (!doit) {
5704                return true;
5705            }
5706            didSomething = true;
5707        }
5708
5709        if (packageName == null) {
5710            // Remove all sticky broadcasts from this user.
5711            mStickyBroadcasts.remove(userId);
5712        }
5713
5714        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5715        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5716                userId, providers)) {
5717            if (!doit) {
5718                return true;
5719            }
5720            didSomething = true;
5721        }
5722        for (i = providers.size() - 1; i >= 0; i--) {
5723            removeDyingProviderLocked(null, providers.get(i), true);
5724        }
5725
5726        // Remove transient permissions granted from/to this package/user
5727        removeUriPermissionsForPackageLocked(packageName, userId, false);
5728
5729        if (doit) {
5730            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
5731                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5732                        packageName, null, userId, doit);
5733            }
5734        }
5735
5736        if (packageName == null || uninstalling) {
5737            // Remove pending intents.  For now we only do this when force
5738            // stopping users, because we have some problems when doing this
5739            // for packages -- app widgets are not currently cleaned up for
5740            // such packages, so they can be left with bad pending intents.
5741            if (mIntentSenderRecords.size() > 0) {
5742                Iterator<WeakReference<PendingIntentRecord>> it
5743                        = mIntentSenderRecords.values().iterator();
5744                while (it.hasNext()) {
5745                    WeakReference<PendingIntentRecord> wpir = it.next();
5746                    if (wpir == null) {
5747                        it.remove();
5748                        continue;
5749                    }
5750                    PendingIntentRecord pir = wpir.get();
5751                    if (pir == null) {
5752                        it.remove();
5753                        continue;
5754                    }
5755                    if (packageName == null) {
5756                        // Stopping user, remove all objects for the user.
5757                        if (pir.key.userId != userId) {
5758                            // Not the same user, skip it.
5759                            continue;
5760                        }
5761                    } else {
5762                        if (UserHandle.getAppId(pir.uid) != appId) {
5763                            // Different app id, skip it.
5764                            continue;
5765                        }
5766                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5767                            // Different user, skip it.
5768                            continue;
5769                        }
5770                        if (!pir.key.packageName.equals(packageName)) {
5771                            // Different package, skip it.
5772                            continue;
5773                        }
5774                    }
5775                    if (!doit) {
5776                        return true;
5777                    }
5778                    didSomething = true;
5779                    it.remove();
5780                    pir.canceled = true;
5781                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5782                        pir.key.activity.pendingResults.remove(pir.ref);
5783                    }
5784                }
5785            }
5786        }
5787
5788        if (doit) {
5789            if (purgeCache && packageName != null) {
5790                AttributeCache ac = AttributeCache.instance();
5791                if (ac != null) {
5792                    ac.removePackage(packageName);
5793                }
5794            }
5795            if (mBooted) {
5796                mStackSupervisor.resumeTopActivitiesLocked();
5797                mStackSupervisor.scheduleIdleLocked();
5798            }
5799        }
5800
5801        return didSomething;
5802    }
5803
5804    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
5805        ProcessRecord old = mProcessNames.remove(name, uid);
5806        if (old != null) {
5807            old.uidRecord.numProcs--;
5808            if (old.uidRecord.numProcs == 0) {
5809                // No more processes using this uid, tell clients it is gone.
5810                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5811                        "No more processes in " + old.uidRecord);
5812                enqueueUidChangeLocked(old.uidRecord, true);
5813                mActiveUids.remove(uid);
5814            }
5815            old.uidRecord = null;
5816        }
5817        mIsolatedProcesses.remove(uid);
5818        return old;
5819    }
5820
5821    private final void addProcessNameLocked(ProcessRecord proc) {
5822        // We shouldn't already have a process under this name, but just in case we
5823        // need to clean up whatever may be there now.
5824        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
5825        if (old != null) {
5826            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
5827        }
5828        UidRecord uidRec = mActiveUids.get(proc.uid);
5829        if (uidRec == null) {
5830            uidRec = new UidRecord(proc.uid);
5831            // This is the first appearance of the uid, report it now!
5832            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5833                    "Creating new process uid: " + uidRec);
5834            mActiveUids.put(proc.uid, uidRec);
5835            enqueueUidChangeLocked(uidRec, false);
5836        }
5837        proc.uidRecord = uidRec;
5838        uidRec.numProcs++;
5839        mProcessNames.put(proc.processName, proc.uid, proc);
5840        if (proc.isolated) {
5841            mIsolatedProcesses.put(proc.uid, proc);
5842        }
5843    }
5844
5845    private final boolean removeProcessLocked(ProcessRecord app,
5846            boolean callerWillRestart, boolean allowRestart, String reason) {
5847        final String name = app.processName;
5848        final int uid = app.uid;
5849        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
5850            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
5851
5852        removeProcessNameLocked(name, uid);
5853        if (mHeavyWeightProcess == app) {
5854            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5855                    mHeavyWeightProcess.userId, 0));
5856            mHeavyWeightProcess = null;
5857        }
5858        boolean needRestart = false;
5859        if (app.pid > 0 && app.pid != MY_PID) {
5860            int pid = app.pid;
5861            synchronized (mPidsSelfLocked) {
5862                mPidsSelfLocked.remove(pid);
5863                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5864            }
5865            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5866            if (app.isolated) {
5867                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5868            }
5869            boolean willRestart = false;
5870            if (app.persistent && !app.isolated) {
5871                if (!callerWillRestart) {
5872                    willRestart = true;
5873                } else {
5874                    needRestart = true;
5875                }
5876            }
5877            app.kill(reason, true);
5878            handleAppDiedLocked(app, willRestart, allowRestart);
5879            if (willRestart) {
5880                removeLruProcessLocked(app);
5881                addAppLocked(app.info, false, null /* ABI override */);
5882            }
5883        } else {
5884            mRemovedProcesses.add(app);
5885        }
5886
5887        return needRestart;
5888    }
5889
5890    private final void processStartTimedOutLocked(ProcessRecord app) {
5891        final int pid = app.pid;
5892        boolean gone = false;
5893        synchronized (mPidsSelfLocked) {
5894            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5895            if (knownApp != null && knownApp.thread == null) {
5896                mPidsSelfLocked.remove(pid);
5897                gone = true;
5898            }
5899        }
5900
5901        if (gone) {
5902            Slog.w(TAG, "Process " + app + " failed to attach");
5903            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5904                    pid, app.uid, app.processName);
5905            removeProcessNameLocked(app.processName, app.uid);
5906            if (mHeavyWeightProcess == app) {
5907                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5908                        mHeavyWeightProcess.userId, 0));
5909                mHeavyWeightProcess = null;
5910            }
5911            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5912            if (app.isolated) {
5913                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5914            }
5915            // Take care of any launching providers waiting for this process.
5916            checkAppInLaunchingProvidersLocked(app, true);
5917            // Take care of any services that are waiting for the process.
5918            mServices.processStartTimedOutLocked(app);
5919            app.kill("start timeout", true);
5920            removeLruProcessLocked(app);
5921            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5922                Slog.w(TAG, "Unattached app died before backup, skipping");
5923                try {
5924                    IBackupManager bm = IBackupManager.Stub.asInterface(
5925                            ServiceManager.getService(Context.BACKUP_SERVICE));
5926                    bm.agentDisconnected(app.info.packageName);
5927                } catch (RemoteException e) {
5928                    // Can't happen; the backup manager is local
5929                }
5930            }
5931            if (isPendingBroadcastProcessLocked(pid)) {
5932                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5933                skipPendingBroadcastLocked(pid);
5934            }
5935        } else {
5936            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5937        }
5938    }
5939
5940    private final boolean attachApplicationLocked(IApplicationThread thread,
5941            int pid) {
5942
5943        // Find the application record that is being attached...  either via
5944        // the pid if we are running in multiple processes, or just pull the
5945        // next app record if we are emulating process with anonymous threads.
5946        ProcessRecord app;
5947        if (pid != MY_PID && pid >= 0) {
5948            synchronized (mPidsSelfLocked) {
5949                app = mPidsSelfLocked.get(pid);
5950            }
5951        } else {
5952            app = null;
5953        }
5954
5955        if (app == null) {
5956            Slog.w(TAG, "No pending application record for pid " + pid
5957                    + " (IApplicationThread " + thread + "); dropping process");
5958            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5959            if (pid > 0 && pid != MY_PID) {
5960                Process.killProcessQuiet(pid);
5961                //TODO: killProcessGroup(app.info.uid, pid);
5962            } else {
5963                try {
5964                    thread.scheduleExit();
5965                } catch (Exception e) {
5966                    // Ignore exceptions.
5967                }
5968            }
5969            return false;
5970        }
5971
5972        // If this application record is still attached to a previous
5973        // process, clean it up now.
5974        if (app.thread != null) {
5975            handleAppDiedLocked(app, true, true);
5976        }
5977
5978        // Tell the process all about itself.
5979
5980        if (DEBUG_ALL) Slog.v(
5981                TAG, "Binding process pid " + pid + " to record " + app);
5982
5983        final String processName = app.processName;
5984        try {
5985            AppDeathRecipient adr = new AppDeathRecipient(
5986                    app, pid, thread);
5987            thread.asBinder().linkToDeath(adr, 0);
5988            app.deathRecipient = adr;
5989        } catch (RemoteException e) {
5990            app.resetPackageList(mProcessStats);
5991            startProcessLocked(app, "link fail", processName);
5992            return false;
5993        }
5994
5995        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5996
5997        app.makeActive(thread, mProcessStats);
5998        app.curAdj = app.setAdj = -100;
5999        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6000        app.forcingToForeground = null;
6001        updateProcessForegroundLocked(app, false, false);
6002        app.hasShownUi = false;
6003        app.debugging = false;
6004        app.cached = false;
6005        app.killedByAm = false;
6006
6007        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6008
6009        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6010        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6011
6012        if (!normalMode) {
6013            Slog.i(TAG, "Launching preboot mode app: " + app);
6014        }
6015
6016        if (DEBUG_ALL) Slog.v(
6017            TAG, "New app record " + app
6018            + " thread=" + thread.asBinder() + " pid=" + pid);
6019        try {
6020            int testMode = IApplicationThread.DEBUG_OFF;
6021            if (mDebugApp != null && mDebugApp.equals(processName)) {
6022                testMode = mWaitForDebugger
6023                    ? IApplicationThread.DEBUG_WAIT
6024                    : IApplicationThread.DEBUG_ON;
6025                app.debugging = true;
6026                if (mDebugTransient) {
6027                    mDebugApp = mOrigDebugApp;
6028                    mWaitForDebugger = mOrigWaitForDebugger;
6029                }
6030            }
6031            String profileFile = app.instrumentationProfileFile;
6032            ParcelFileDescriptor profileFd = null;
6033            int samplingInterval = 0;
6034            boolean profileAutoStop = false;
6035            if (mProfileApp != null && mProfileApp.equals(processName)) {
6036                mProfileProc = app;
6037                profileFile = mProfileFile;
6038                profileFd = mProfileFd;
6039                samplingInterval = mSamplingInterval;
6040                profileAutoStop = mAutoStopProfiler;
6041            }
6042            boolean enableOpenGlTrace = false;
6043            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6044                enableOpenGlTrace = true;
6045                mOpenGlTraceApp = null;
6046            }
6047            boolean enableTrackAllocation = false;
6048            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6049                enableTrackAllocation = true;
6050                mTrackAllocationApp = null;
6051            }
6052
6053            // If the app is being launched for restore or full backup, set it up specially
6054            boolean isRestrictedBackupMode = false;
6055            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6056                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6057                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6058                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6059            }
6060
6061            ensurePackageDexOpt(app.instrumentationInfo != null
6062                    ? app.instrumentationInfo.packageName
6063                    : app.info.packageName);
6064            if (app.instrumentationClass != null) {
6065                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6066            }
6067            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6068                    + processName + " with config " + mConfiguration);
6069            ApplicationInfo appInfo = app.instrumentationInfo != null
6070                    ? app.instrumentationInfo : app.info;
6071            app.compat = compatibilityInfoForPackageLocked(appInfo);
6072            if (profileFd != null) {
6073                profileFd = profileFd.dup();
6074            }
6075            ProfilerInfo profilerInfo = profileFile == null ? null
6076                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6077            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6078                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6079                    app.instrumentationUiAutomationConnection, testMode,
6080                    mBinderTransactionTrackingEnabled, enableOpenGlTrace,
6081                    enableTrackAllocation, isRestrictedBackupMode || !normalMode,
6082                    app.persistent, new Configuration(mConfiguration), app.compat,
6083                    getCommonServicesLocked(app.isolated),
6084                    mCoreSettingsObserver.getCoreSettingsLocked());
6085            updateLruProcessLocked(app, false, null);
6086            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6087        } catch (Exception e) {
6088            // todo: Yikes!  What should we do?  For now we will try to
6089            // start another process, but that could easily get us in
6090            // an infinite loop of restarting processes...
6091            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6092
6093            app.resetPackageList(mProcessStats);
6094            app.unlinkDeathRecipient();
6095            startProcessLocked(app, "bind fail", processName);
6096            return false;
6097        }
6098
6099        // Remove this record from the list of starting applications.
6100        mPersistentStartingProcesses.remove(app);
6101        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6102                "Attach application locked removing on hold: " + app);
6103        mProcessesOnHold.remove(app);
6104
6105        boolean badApp = false;
6106        boolean didSomething = false;
6107
6108        // See if the top visible activity is waiting to run in this process...
6109        if (normalMode) {
6110            try {
6111                if (mStackSupervisor.attachApplicationLocked(app)) {
6112                    didSomething = true;
6113                }
6114            } catch (Exception e) {
6115                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6116                badApp = true;
6117            }
6118        }
6119
6120        // Find any services that should be running in this process...
6121        if (!badApp) {
6122            try {
6123                didSomething |= mServices.attachApplicationLocked(app, processName);
6124            } catch (Exception e) {
6125                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6126                badApp = true;
6127            }
6128        }
6129
6130        // Check if a next-broadcast receiver is in this process...
6131        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6132            try {
6133                didSomething |= sendPendingBroadcastsLocked(app);
6134            } catch (Exception e) {
6135                // If the app died trying to launch the receiver we declare it 'bad'
6136                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6137                badApp = true;
6138            }
6139        }
6140
6141        // Check whether the next backup agent is in this process...
6142        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6143            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6144                    "New app is backup target, launching agent for " + app);
6145            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6146            try {
6147                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6148                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6149                        mBackupTarget.backupMode);
6150            } catch (Exception e) {
6151                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6152                badApp = true;
6153            }
6154        }
6155
6156        if (badApp) {
6157            app.kill("error during init", true);
6158            handleAppDiedLocked(app, false, true);
6159            return false;
6160        }
6161
6162        if (!didSomething) {
6163            updateOomAdjLocked();
6164        }
6165
6166        return true;
6167    }
6168
6169    @Override
6170    public final void attachApplication(IApplicationThread thread) {
6171        synchronized (this) {
6172            int callingPid = Binder.getCallingPid();
6173            final long origId = Binder.clearCallingIdentity();
6174            attachApplicationLocked(thread, callingPid);
6175            Binder.restoreCallingIdentity(origId);
6176        }
6177    }
6178
6179    @Override
6180    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6181        final long origId = Binder.clearCallingIdentity();
6182        synchronized (this) {
6183            ActivityStack stack = ActivityRecord.getStackLocked(token);
6184            if (stack != null) {
6185                ActivityRecord r =
6186                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6187                if (stopProfiling) {
6188                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6189                        try {
6190                            mProfileFd.close();
6191                        } catch (IOException e) {
6192                        }
6193                        clearProfilerLocked();
6194                    }
6195                }
6196            }
6197        }
6198        Binder.restoreCallingIdentity(origId);
6199    }
6200
6201    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6202        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6203                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6204    }
6205
6206    void enableScreenAfterBoot() {
6207        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6208                SystemClock.uptimeMillis());
6209        mWindowManager.enableScreenAfterBoot();
6210
6211        synchronized (this) {
6212            updateEventDispatchingLocked();
6213        }
6214    }
6215
6216    @Override
6217    public void showBootMessage(final CharSequence msg, final boolean always) {
6218        if (Binder.getCallingUid() != Process.myUid()) {
6219            // These days only the core system can call this, so apps can't get in
6220            // the way of what we show about running them.
6221        }
6222        mWindowManager.showBootMessage(msg, always);
6223    }
6224
6225    @Override
6226    public void keyguardWaitingForActivityDrawn() {
6227        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6228        final long token = Binder.clearCallingIdentity();
6229        try {
6230            synchronized (this) {
6231                if (DEBUG_LOCKSCREEN) logLockScreen("");
6232                mWindowManager.keyguardWaitingForActivityDrawn();
6233                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6234                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6235                    updateSleepIfNeededLocked();
6236                }
6237            }
6238        } finally {
6239            Binder.restoreCallingIdentity(token);
6240        }
6241    }
6242
6243    @Override
6244    public void keyguardGoingAway(boolean disableWindowAnimations,
6245            boolean keyguardGoingToNotificationShade) {
6246        enforceNotIsolatedCaller("keyguardGoingAway");
6247        final long token = Binder.clearCallingIdentity();
6248        try {
6249            synchronized (this) {
6250                if (DEBUG_LOCKSCREEN) logLockScreen("");
6251                mWindowManager.keyguardGoingAway(disableWindowAnimations,
6252                        keyguardGoingToNotificationShade);
6253                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6254                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6255                    updateSleepIfNeededLocked();
6256                }
6257            }
6258        } finally {
6259            Binder.restoreCallingIdentity(token);
6260        }
6261    }
6262
6263    final void finishBooting() {
6264        synchronized (this) {
6265            if (!mBootAnimationComplete) {
6266                mCallFinishBooting = true;
6267                return;
6268            }
6269            mCallFinishBooting = false;
6270        }
6271
6272        ArraySet<String> completedIsas = new ArraySet<String>();
6273        for (String abi : Build.SUPPORTED_ABIS) {
6274            Process.establishZygoteConnectionForAbi(abi);
6275            final String instructionSet = VMRuntime.getInstructionSet(abi);
6276            if (!completedIsas.contains(instructionSet)) {
6277                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6278                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6279                }
6280                completedIsas.add(instructionSet);
6281            }
6282        }
6283
6284        IntentFilter pkgFilter = new IntentFilter();
6285        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6286        pkgFilter.addDataScheme("package");
6287        mContext.registerReceiver(new BroadcastReceiver() {
6288            @Override
6289            public void onReceive(Context context, Intent intent) {
6290                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6291                if (pkgs != null) {
6292                    for (String pkg : pkgs) {
6293                        synchronized (ActivityManagerService.this) {
6294                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6295                                    0, "query restart")) {
6296                                setResultCode(Activity.RESULT_OK);
6297                                return;
6298                            }
6299                        }
6300                    }
6301                }
6302            }
6303        }, pkgFilter);
6304
6305        IntentFilter dumpheapFilter = new IntentFilter();
6306        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6307        mContext.registerReceiver(new BroadcastReceiver() {
6308            @Override
6309            public void onReceive(Context context, Intent intent) {
6310                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6311                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6312                } else {
6313                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6314                }
6315            }
6316        }, dumpheapFilter);
6317
6318        // Let system services know.
6319        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6320
6321        synchronized (this) {
6322            // Ensure that any processes we had put on hold are now started
6323            // up.
6324            final int NP = mProcessesOnHold.size();
6325            if (NP > 0) {
6326                ArrayList<ProcessRecord> procs =
6327                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6328                for (int ip=0; ip<NP; ip++) {
6329                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6330                            + procs.get(ip));
6331                    startProcessLocked(procs.get(ip), "on-hold", null);
6332                }
6333            }
6334
6335            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6336                // Start looking for apps that are abusing wake locks.
6337                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6338                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6339                // Tell anyone interested that we are done booting!
6340                SystemProperties.set("sys.boot_completed", "1");
6341
6342                // And trigger dev.bootcomplete if we are not showing encryption progress
6343                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6344                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6345                    SystemProperties.set("dev.bootcomplete", "1");
6346                }
6347                for (int i=0; i<mStartedUsers.size(); i++) {
6348                    UserState uss = mStartedUsers.valueAt(i);
6349                    if (uss.mState == UserState.STATE_BOOTING) {
6350                        uss.mState = UserState.STATE_RUNNING;
6351                        final int userId = mStartedUsers.keyAt(i);
6352                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6353                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6354                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6355                        broadcastIntentLocked(null, null, intent, null,
6356                                new IIntentReceiver.Stub() {
6357                                    @Override
6358                                    public void performReceive(Intent intent, int resultCode,
6359                                            String data, Bundle extras, boolean ordered,
6360                                            boolean sticky, int sendingUser) {
6361                                        synchronized (ActivityManagerService.this) {
6362                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6363                                                    true, false);
6364                                        }
6365                                    }
6366                                },
6367                                0, null, null,
6368                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6369                                AppOpsManager.OP_NONE, null, true, false,
6370                                MY_PID, Process.SYSTEM_UID, userId);
6371                    }
6372                }
6373                scheduleStartProfilesLocked();
6374            }
6375        }
6376    }
6377
6378    @Override
6379    public void bootAnimationComplete() {
6380        final boolean callFinishBooting;
6381        synchronized (this) {
6382            callFinishBooting = mCallFinishBooting;
6383            mBootAnimationComplete = true;
6384        }
6385        if (callFinishBooting) {
6386            finishBooting();
6387        }
6388    }
6389
6390    final void ensureBootCompleted() {
6391        boolean booting;
6392        boolean enableScreen;
6393        synchronized (this) {
6394            booting = mBooting;
6395            mBooting = false;
6396            enableScreen = !mBooted;
6397            mBooted = true;
6398        }
6399
6400        if (booting) {
6401            finishBooting();
6402        }
6403
6404        if (enableScreen) {
6405            enableScreenAfterBoot();
6406        }
6407    }
6408
6409    @Override
6410    public final void activityResumed(IBinder token) {
6411        final long origId = Binder.clearCallingIdentity();
6412        synchronized(this) {
6413            ActivityStack stack = ActivityRecord.getStackLocked(token);
6414            if (stack != null) {
6415                ActivityRecord.activityResumedLocked(token);
6416            }
6417        }
6418        Binder.restoreCallingIdentity(origId);
6419    }
6420
6421    @Override
6422    public final void activityPaused(IBinder token) {
6423        final long origId = Binder.clearCallingIdentity();
6424        synchronized(this) {
6425            ActivityStack stack = ActivityRecord.getStackLocked(token);
6426            if (stack != null) {
6427                stack.activityPausedLocked(token, false);
6428            }
6429        }
6430        Binder.restoreCallingIdentity(origId);
6431    }
6432
6433    @Override
6434    public final void activityStopped(IBinder token, Bundle icicle,
6435            PersistableBundle persistentState, CharSequence description) {
6436        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6437
6438        // Refuse possible leaked file descriptors
6439        if (icicle != null && icicle.hasFileDescriptors()) {
6440            throw new IllegalArgumentException("File descriptors passed in Bundle");
6441        }
6442
6443        final long origId = Binder.clearCallingIdentity();
6444
6445        synchronized (this) {
6446            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6447            if (r != null) {
6448                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6449            }
6450        }
6451
6452        trimApplications();
6453
6454        Binder.restoreCallingIdentity(origId);
6455    }
6456
6457    @Override
6458    public final void activityDestroyed(IBinder token) {
6459        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6460        synchronized (this) {
6461            ActivityStack stack = ActivityRecord.getStackLocked(token);
6462            if (stack != null) {
6463                stack.activityDestroyedLocked(token, "activityDestroyed");
6464            }
6465        }
6466    }
6467
6468    @Override
6469    public final void backgroundResourcesReleased(IBinder token) {
6470        final long origId = Binder.clearCallingIdentity();
6471        try {
6472            synchronized (this) {
6473                ActivityStack stack = ActivityRecord.getStackLocked(token);
6474                if (stack != null) {
6475                    stack.backgroundResourcesReleased();
6476                }
6477            }
6478        } finally {
6479            Binder.restoreCallingIdentity(origId);
6480        }
6481    }
6482
6483    @Override
6484    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6485        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6486    }
6487
6488    @Override
6489    public final void notifyEnterAnimationComplete(IBinder token) {
6490        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6491    }
6492
6493    @Override
6494    public String getCallingPackage(IBinder token) {
6495        synchronized (this) {
6496            ActivityRecord r = getCallingRecordLocked(token);
6497            return r != null ? r.info.packageName : null;
6498        }
6499    }
6500
6501    @Override
6502    public ComponentName getCallingActivity(IBinder token) {
6503        synchronized (this) {
6504            ActivityRecord r = getCallingRecordLocked(token);
6505            return r != null ? r.intent.getComponent() : null;
6506        }
6507    }
6508
6509    private ActivityRecord getCallingRecordLocked(IBinder token) {
6510        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6511        if (r == null) {
6512            return null;
6513        }
6514        return r.resultTo;
6515    }
6516
6517    @Override
6518    public ComponentName getActivityClassForToken(IBinder token) {
6519        synchronized(this) {
6520            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6521            if (r == null) {
6522                return null;
6523            }
6524            return r.intent.getComponent();
6525        }
6526    }
6527
6528    @Override
6529    public String getPackageForToken(IBinder token) {
6530        synchronized(this) {
6531            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6532            if (r == null) {
6533                return null;
6534            }
6535            return r.packageName;
6536        }
6537    }
6538
6539    @Override
6540    public IIntentSender getIntentSender(int type,
6541            String packageName, IBinder token, String resultWho,
6542            int requestCode, Intent[] intents, String[] resolvedTypes,
6543            int flags, Bundle options, int userId) {
6544        enforceNotIsolatedCaller("getIntentSender");
6545        // Refuse possible leaked file descriptors
6546        if (intents != null) {
6547            if (intents.length < 1) {
6548                throw new IllegalArgumentException("Intents array length must be >= 1");
6549            }
6550            for (int i=0; i<intents.length; i++) {
6551                Intent intent = intents[i];
6552                if (intent != null) {
6553                    if (intent.hasFileDescriptors()) {
6554                        throw new IllegalArgumentException("File descriptors passed in Intent");
6555                    }
6556                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6557                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6558                        throw new IllegalArgumentException(
6559                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6560                    }
6561                    intents[i] = new Intent(intent);
6562                }
6563            }
6564            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6565                throw new IllegalArgumentException(
6566                        "Intent array length does not match resolvedTypes length");
6567            }
6568        }
6569        if (options != null) {
6570            if (options.hasFileDescriptors()) {
6571                throw new IllegalArgumentException("File descriptors passed in options");
6572            }
6573        }
6574
6575        synchronized(this) {
6576            int callingUid = Binder.getCallingUid();
6577            int origUserId = userId;
6578            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6579                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6580                    ALLOW_NON_FULL, "getIntentSender", null);
6581            if (origUserId == UserHandle.USER_CURRENT) {
6582                // We don't want to evaluate this until the pending intent is
6583                // actually executed.  However, we do want to always do the
6584                // security checking for it above.
6585                userId = UserHandle.USER_CURRENT;
6586            }
6587            try {
6588                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6589                    int uid = AppGlobals.getPackageManager()
6590                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6591                    if (!UserHandle.isSameApp(callingUid, uid)) {
6592                        String msg = "Permission Denial: getIntentSender() from pid="
6593                            + Binder.getCallingPid()
6594                            + ", uid=" + Binder.getCallingUid()
6595                            + ", (need uid=" + uid + ")"
6596                            + " is not allowed to send as package " + packageName;
6597                        Slog.w(TAG, msg);
6598                        throw new SecurityException(msg);
6599                    }
6600                }
6601
6602                return getIntentSenderLocked(type, packageName, callingUid, userId,
6603                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6604
6605            } catch (RemoteException e) {
6606                throw new SecurityException(e);
6607            }
6608        }
6609    }
6610
6611    IIntentSender getIntentSenderLocked(int type, String packageName,
6612            int callingUid, int userId, IBinder token, String resultWho,
6613            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6614            Bundle options) {
6615        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6616        ActivityRecord activity = null;
6617        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6618            activity = ActivityRecord.isInStackLocked(token);
6619            if (activity == null) {
6620                return null;
6621            }
6622            if (activity.finishing) {
6623                return null;
6624            }
6625        }
6626
6627        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6628        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6629        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6630        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6631                |PendingIntent.FLAG_UPDATE_CURRENT);
6632
6633        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6634                type, packageName, activity, resultWho,
6635                requestCode, intents, resolvedTypes, flags, options, userId);
6636        WeakReference<PendingIntentRecord> ref;
6637        ref = mIntentSenderRecords.get(key);
6638        PendingIntentRecord rec = ref != null ? ref.get() : null;
6639        if (rec != null) {
6640            if (!cancelCurrent) {
6641                if (updateCurrent) {
6642                    if (rec.key.requestIntent != null) {
6643                        rec.key.requestIntent.replaceExtras(intents != null ?
6644                                intents[intents.length - 1] : null);
6645                    }
6646                    if (intents != null) {
6647                        intents[intents.length-1] = rec.key.requestIntent;
6648                        rec.key.allIntents = intents;
6649                        rec.key.allResolvedTypes = resolvedTypes;
6650                    } else {
6651                        rec.key.allIntents = null;
6652                        rec.key.allResolvedTypes = null;
6653                    }
6654                }
6655                return rec;
6656            }
6657            rec.canceled = true;
6658            mIntentSenderRecords.remove(key);
6659        }
6660        if (noCreate) {
6661            return rec;
6662        }
6663        rec = new PendingIntentRecord(this, key, callingUid);
6664        mIntentSenderRecords.put(key, rec.ref);
6665        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6666            if (activity.pendingResults == null) {
6667                activity.pendingResults
6668                        = new HashSet<WeakReference<PendingIntentRecord>>();
6669            }
6670            activity.pendingResults.add(rec.ref);
6671        }
6672        return rec;
6673    }
6674
6675    @Override
6676    public void cancelIntentSender(IIntentSender sender) {
6677        if (!(sender instanceof PendingIntentRecord)) {
6678            return;
6679        }
6680        synchronized(this) {
6681            PendingIntentRecord rec = (PendingIntentRecord)sender;
6682            try {
6683                int uid = AppGlobals.getPackageManager()
6684                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6685                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6686                    String msg = "Permission Denial: cancelIntentSender() from pid="
6687                        + Binder.getCallingPid()
6688                        + ", uid=" + Binder.getCallingUid()
6689                        + " is not allowed to cancel packges "
6690                        + rec.key.packageName;
6691                    Slog.w(TAG, msg);
6692                    throw new SecurityException(msg);
6693                }
6694            } catch (RemoteException e) {
6695                throw new SecurityException(e);
6696            }
6697            cancelIntentSenderLocked(rec, true);
6698        }
6699    }
6700
6701    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6702        rec.canceled = true;
6703        mIntentSenderRecords.remove(rec.key);
6704        if (cleanActivity && rec.key.activity != null) {
6705            rec.key.activity.pendingResults.remove(rec.ref);
6706        }
6707    }
6708
6709    @Override
6710    public String getPackageForIntentSender(IIntentSender pendingResult) {
6711        if (!(pendingResult instanceof PendingIntentRecord)) {
6712            return null;
6713        }
6714        try {
6715            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6716            return res.key.packageName;
6717        } catch (ClassCastException e) {
6718        }
6719        return null;
6720    }
6721
6722    @Override
6723    public int getUidForIntentSender(IIntentSender sender) {
6724        if (sender instanceof PendingIntentRecord) {
6725            try {
6726                PendingIntentRecord res = (PendingIntentRecord)sender;
6727                return res.uid;
6728            } catch (ClassCastException e) {
6729            }
6730        }
6731        return -1;
6732    }
6733
6734    @Override
6735    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6736        if (!(pendingResult instanceof PendingIntentRecord)) {
6737            return false;
6738        }
6739        try {
6740            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6741            if (res.key.allIntents == null) {
6742                return false;
6743            }
6744            for (int i=0; i<res.key.allIntents.length; i++) {
6745                Intent intent = res.key.allIntents[i];
6746                if (intent.getPackage() != null && intent.getComponent() != null) {
6747                    return false;
6748                }
6749            }
6750            return true;
6751        } catch (ClassCastException e) {
6752        }
6753        return false;
6754    }
6755
6756    @Override
6757    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6758        if (!(pendingResult instanceof PendingIntentRecord)) {
6759            return false;
6760        }
6761        try {
6762            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6763            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6764                return true;
6765            }
6766            return false;
6767        } catch (ClassCastException e) {
6768        }
6769        return false;
6770    }
6771
6772    @Override
6773    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6774        if (!(pendingResult instanceof PendingIntentRecord)) {
6775            return null;
6776        }
6777        try {
6778            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6779            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6780        } catch (ClassCastException e) {
6781        }
6782        return null;
6783    }
6784
6785    @Override
6786    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6787        if (!(pendingResult instanceof PendingIntentRecord)) {
6788            return null;
6789        }
6790        try {
6791            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6792            synchronized (this) {
6793                return getTagForIntentSenderLocked(res, prefix);
6794            }
6795        } catch (ClassCastException e) {
6796        }
6797        return null;
6798    }
6799
6800    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
6801        final Intent intent = res.key.requestIntent;
6802        if (intent != null) {
6803            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6804                    || res.lastTagPrefix.equals(prefix))) {
6805                return res.lastTag;
6806            }
6807            res.lastTagPrefix = prefix;
6808            final StringBuilder sb = new StringBuilder(128);
6809            if (prefix != null) {
6810                sb.append(prefix);
6811            }
6812            if (intent.getAction() != null) {
6813                sb.append(intent.getAction());
6814            } else if (intent.getComponent() != null) {
6815                intent.getComponent().appendShortString(sb);
6816            } else {
6817                sb.append("?");
6818            }
6819            return res.lastTag = sb.toString();
6820        }
6821        return null;
6822    }
6823
6824    @Override
6825    public void setProcessLimit(int max) {
6826        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6827                "setProcessLimit()");
6828        synchronized (this) {
6829            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6830            mProcessLimitOverride = max;
6831        }
6832        trimApplications();
6833    }
6834
6835    @Override
6836    public int getProcessLimit() {
6837        synchronized (this) {
6838            return mProcessLimitOverride;
6839        }
6840    }
6841
6842    void foregroundTokenDied(ForegroundToken token) {
6843        synchronized (ActivityManagerService.this) {
6844            synchronized (mPidsSelfLocked) {
6845                ForegroundToken cur
6846                    = mForegroundProcesses.get(token.pid);
6847                if (cur != token) {
6848                    return;
6849                }
6850                mForegroundProcesses.remove(token.pid);
6851                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6852                if (pr == null) {
6853                    return;
6854                }
6855                pr.forcingToForeground = null;
6856                updateProcessForegroundLocked(pr, false, false);
6857            }
6858            updateOomAdjLocked();
6859        }
6860    }
6861
6862    @Override
6863    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6864        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6865                "setProcessForeground()");
6866        synchronized(this) {
6867            boolean changed = false;
6868
6869            synchronized (mPidsSelfLocked) {
6870                ProcessRecord pr = mPidsSelfLocked.get(pid);
6871                if (pr == null && isForeground) {
6872                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6873                    return;
6874                }
6875                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6876                if (oldToken != null) {
6877                    oldToken.token.unlinkToDeath(oldToken, 0);
6878                    mForegroundProcesses.remove(pid);
6879                    if (pr != null) {
6880                        pr.forcingToForeground = null;
6881                    }
6882                    changed = true;
6883                }
6884                if (isForeground && token != null) {
6885                    ForegroundToken newToken = new ForegroundToken() {
6886                        @Override
6887                        public void binderDied() {
6888                            foregroundTokenDied(this);
6889                        }
6890                    };
6891                    newToken.pid = pid;
6892                    newToken.token = token;
6893                    try {
6894                        token.linkToDeath(newToken, 0);
6895                        mForegroundProcesses.put(pid, newToken);
6896                        pr.forcingToForeground = token;
6897                        changed = true;
6898                    } catch (RemoteException e) {
6899                        // If the process died while doing this, we will later
6900                        // do the cleanup with the process death link.
6901                    }
6902                }
6903            }
6904
6905            if (changed) {
6906                updateOomAdjLocked();
6907            }
6908        }
6909    }
6910
6911    // =========================================================
6912    // PROCESS INFO
6913    // =========================================================
6914
6915    static class ProcessInfoService extends IProcessInfoService.Stub {
6916        final ActivityManagerService mActivityManagerService;
6917        ProcessInfoService(ActivityManagerService activityManagerService) {
6918            mActivityManagerService = activityManagerService;
6919        }
6920
6921        @Override
6922        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
6923            mActivityManagerService.getProcessStatesForPIDs(/*in*/ pids, /*out*/ states);
6924        }
6925    }
6926
6927    /**
6928     * For each PID in the given input array, write the current process state
6929     * for that process into the output array, or -1 to indicate that no
6930     * process with the given PID exists.
6931     */
6932    public void getProcessStatesForPIDs(/*in*/ int[] pids, /*out*/ int[] states) {
6933        if (pids == null) {
6934            throw new NullPointerException("pids");
6935        } else if (states == null) {
6936            throw new NullPointerException("states");
6937        } else if (pids.length != states.length) {
6938            throw new IllegalArgumentException("input and output arrays have different lengths!");
6939        }
6940
6941        synchronized (mPidsSelfLocked) {
6942            for (int i = 0; i < pids.length; i++) {
6943                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
6944                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
6945                        pr.curProcState;
6946            }
6947        }
6948    }
6949
6950    // =========================================================
6951    // PERMISSIONS
6952    // =========================================================
6953
6954    static class PermissionController extends IPermissionController.Stub {
6955        ActivityManagerService mActivityManagerService;
6956        PermissionController(ActivityManagerService activityManagerService) {
6957            mActivityManagerService = activityManagerService;
6958        }
6959
6960        @Override
6961        public boolean checkPermission(String permission, int pid, int uid) {
6962            return mActivityManagerService.checkPermission(permission, pid,
6963                    uid) == PackageManager.PERMISSION_GRANTED;
6964        }
6965
6966        @Override
6967        public String[] getPackagesForUid(int uid) {
6968            return mActivityManagerService.mContext.getPackageManager()
6969                    .getPackagesForUid(uid);
6970        }
6971
6972        @Override
6973        public boolean isRuntimePermission(String permission) {
6974            try {
6975                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
6976                        .getPermissionInfo(permission, 0);
6977                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
6978            } catch (NameNotFoundException nnfe) {
6979                Slog.e(TAG, "No such permission: "+ permission, nnfe);
6980            }
6981            return false;
6982        }
6983    }
6984
6985    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6986        @Override
6987        public int checkComponentPermission(String permission, int pid, int uid,
6988                int owningUid, boolean exported) {
6989            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6990                    owningUid, exported);
6991        }
6992
6993        @Override
6994        public Object getAMSLock() {
6995            return ActivityManagerService.this;
6996        }
6997    }
6998
6999    /**
7000     * This can be called with or without the global lock held.
7001     */
7002    int checkComponentPermission(String permission, int pid, int uid,
7003            int owningUid, boolean exported) {
7004        if (pid == MY_PID) {
7005            return PackageManager.PERMISSION_GRANTED;
7006        }
7007        return ActivityManager.checkComponentPermission(permission, uid,
7008                owningUid, exported);
7009    }
7010
7011    /**
7012     * As the only public entry point for permissions checking, this method
7013     * can enforce the semantic that requesting a check on a null global
7014     * permission is automatically denied.  (Internally a null permission
7015     * string is used when calling {@link #checkComponentPermission} in cases
7016     * when only uid-based security is needed.)
7017     *
7018     * This can be called with or without the global lock held.
7019     */
7020    @Override
7021    public int checkPermission(String permission, int pid, int uid) {
7022        if (permission == null) {
7023            return PackageManager.PERMISSION_DENIED;
7024        }
7025        return checkComponentPermission(permission, pid, uid, -1, true);
7026    }
7027
7028    @Override
7029    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7030        if (permission == null) {
7031            return PackageManager.PERMISSION_DENIED;
7032        }
7033
7034        // We might be performing an operation on behalf of an indirect binder
7035        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7036        // client identity accordingly before proceeding.
7037        Identity tlsIdentity = sCallerIdentity.get();
7038        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7039            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7040                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7041            uid = tlsIdentity.uid;
7042            pid = tlsIdentity.pid;
7043        }
7044
7045        return checkComponentPermission(permission, pid, uid, -1, true);
7046    }
7047
7048    /**
7049     * Binder IPC calls go through the public entry point.
7050     * This can be called with or without the global lock held.
7051     */
7052    int checkCallingPermission(String permission) {
7053        return checkPermission(permission,
7054                Binder.getCallingPid(),
7055                UserHandle.getAppId(Binder.getCallingUid()));
7056    }
7057
7058    /**
7059     * This can be called with or without the global lock held.
7060     */
7061    void enforceCallingPermission(String permission, String func) {
7062        if (checkCallingPermission(permission)
7063                == PackageManager.PERMISSION_GRANTED) {
7064            return;
7065        }
7066
7067        String msg = "Permission Denial: " + func + " from pid="
7068                + Binder.getCallingPid()
7069                + ", uid=" + Binder.getCallingUid()
7070                + " requires " + permission;
7071        Slog.w(TAG, msg);
7072        throw new SecurityException(msg);
7073    }
7074
7075    /**
7076     * Determine if UID is holding permissions required to access {@link Uri} in
7077     * the given {@link ProviderInfo}. Final permission checking is always done
7078     * in {@link ContentProvider}.
7079     */
7080    private final boolean checkHoldingPermissionsLocked(
7081            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7082        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7083                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7084        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7085            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7086                    != PERMISSION_GRANTED) {
7087                return false;
7088            }
7089        }
7090        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7091    }
7092
7093    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7094            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7095        if (pi.applicationInfo.uid == uid) {
7096            return true;
7097        } else if (!pi.exported) {
7098            return false;
7099        }
7100
7101        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7102        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7103        try {
7104            // check if target holds top-level <provider> permissions
7105            if (!readMet && pi.readPermission != null && considerUidPermissions
7106                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7107                readMet = true;
7108            }
7109            if (!writeMet && pi.writePermission != null && considerUidPermissions
7110                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7111                writeMet = true;
7112            }
7113
7114            // track if unprotected read/write is allowed; any denied
7115            // <path-permission> below removes this ability
7116            boolean allowDefaultRead = pi.readPermission == null;
7117            boolean allowDefaultWrite = pi.writePermission == null;
7118
7119            // check if target holds any <path-permission> that match uri
7120            final PathPermission[] pps = pi.pathPermissions;
7121            if (pps != null) {
7122                final String path = grantUri.uri.getPath();
7123                int i = pps.length;
7124                while (i > 0 && (!readMet || !writeMet)) {
7125                    i--;
7126                    PathPermission pp = pps[i];
7127                    if (pp.match(path)) {
7128                        if (!readMet) {
7129                            final String pprperm = pp.getReadPermission();
7130                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7131                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7132                                    + ": match=" + pp.match(path)
7133                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7134                            if (pprperm != null) {
7135                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7136                                        == PERMISSION_GRANTED) {
7137                                    readMet = true;
7138                                } else {
7139                                    allowDefaultRead = false;
7140                                }
7141                            }
7142                        }
7143                        if (!writeMet) {
7144                            final String ppwperm = pp.getWritePermission();
7145                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7146                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7147                                    + ": match=" + pp.match(path)
7148                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7149                            if (ppwperm != null) {
7150                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7151                                        == PERMISSION_GRANTED) {
7152                                    writeMet = true;
7153                                } else {
7154                                    allowDefaultWrite = false;
7155                                }
7156                            }
7157                        }
7158                    }
7159                }
7160            }
7161
7162            // grant unprotected <provider> read/write, if not blocked by
7163            // <path-permission> above
7164            if (allowDefaultRead) readMet = true;
7165            if (allowDefaultWrite) writeMet = true;
7166
7167        } catch (RemoteException e) {
7168            return false;
7169        }
7170
7171        return readMet && writeMet;
7172    }
7173
7174    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7175        ProviderInfo pi = null;
7176        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7177        if (cpr != null) {
7178            pi = cpr.info;
7179        } else {
7180            try {
7181                pi = AppGlobals.getPackageManager().resolveContentProvider(
7182                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7183            } catch (RemoteException ex) {
7184            }
7185        }
7186        return pi;
7187    }
7188
7189    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7190        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7191        if (targetUris != null) {
7192            return targetUris.get(grantUri);
7193        }
7194        return null;
7195    }
7196
7197    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7198            String targetPkg, int targetUid, GrantUri grantUri) {
7199        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7200        if (targetUris == null) {
7201            targetUris = Maps.newArrayMap();
7202            mGrantedUriPermissions.put(targetUid, targetUris);
7203        }
7204
7205        UriPermission perm = targetUris.get(grantUri);
7206        if (perm == null) {
7207            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7208            targetUris.put(grantUri, perm);
7209        }
7210
7211        return perm;
7212    }
7213
7214    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7215            final int modeFlags) {
7216        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7217        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7218                : UriPermission.STRENGTH_OWNED;
7219
7220        // Root gets to do everything.
7221        if (uid == 0) {
7222            return true;
7223        }
7224
7225        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7226        if (perms == null) return false;
7227
7228        // First look for exact match
7229        final UriPermission exactPerm = perms.get(grantUri);
7230        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7231            return true;
7232        }
7233
7234        // No exact match, look for prefixes
7235        final int N = perms.size();
7236        for (int i = 0; i < N; i++) {
7237            final UriPermission perm = perms.valueAt(i);
7238            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7239                    && perm.getStrength(modeFlags) >= minStrength) {
7240                return true;
7241            }
7242        }
7243
7244        return false;
7245    }
7246
7247    /**
7248     * @param uri This uri must NOT contain an embedded userId.
7249     * @param userId The userId in which the uri is to be resolved.
7250     */
7251    @Override
7252    public int checkUriPermission(Uri uri, int pid, int uid,
7253            final int modeFlags, int userId, IBinder callerToken) {
7254        enforceNotIsolatedCaller("checkUriPermission");
7255
7256        // Another redirected-binder-call permissions check as in
7257        // {@link checkPermissionWithToken}.
7258        Identity tlsIdentity = sCallerIdentity.get();
7259        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7260            uid = tlsIdentity.uid;
7261            pid = tlsIdentity.pid;
7262        }
7263
7264        // Our own process gets to do everything.
7265        if (pid == MY_PID) {
7266            return PackageManager.PERMISSION_GRANTED;
7267        }
7268        synchronized (this) {
7269            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7270                    ? PackageManager.PERMISSION_GRANTED
7271                    : PackageManager.PERMISSION_DENIED;
7272        }
7273    }
7274
7275    /**
7276     * Check if the targetPkg can be granted permission to access uri by
7277     * the callingUid using the given modeFlags.  Throws a security exception
7278     * if callingUid is not allowed to do this.  Returns the uid of the target
7279     * if the URI permission grant should be performed; returns -1 if it is not
7280     * needed (for example targetPkg already has permission to access the URI).
7281     * If you already know the uid of the target, you can supply it in
7282     * lastTargetUid else set that to -1.
7283     */
7284    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7285            final int modeFlags, int lastTargetUid) {
7286        if (!Intent.isAccessUriMode(modeFlags)) {
7287            return -1;
7288        }
7289
7290        if (targetPkg != null) {
7291            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7292                    "Checking grant " + targetPkg + " permission to " + grantUri);
7293        }
7294
7295        final IPackageManager pm = AppGlobals.getPackageManager();
7296
7297        // If this is not a content: uri, we can't do anything with it.
7298        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7299            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7300                    "Can't grant URI permission for non-content URI: " + grantUri);
7301            return -1;
7302        }
7303
7304        final String authority = grantUri.uri.getAuthority();
7305        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7306        if (pi == null) {
7307            Slog.w(TAG, "No content provider found for permission check: " +
7308                    grantUri.uri.toSafeString());
7309            return -1;
7310        }
7311
7312        int targetUid = lastTargetUid;
7313        if (targetUid < 0 && targetPkg != null) {
7314            try {
7315                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7316                if (targetUid < 0) {
7317                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7318                            "Can't grant URI permission no uid for: " + targetPkg);
7319                    return -1;
7320                }
7321            } catch (RemoteException ex) {
7322                return -1;
7323            }
7324        }
7325
7326        if (targetUid >= 0) {
7327            // First...  does the target actually need this permission?
7328            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7329                // No need to grant the target this permission.
7330                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7331                        "Target " + targetPkg + " already has full permission to " + grantUri);
7332                return -1;
7333            }
7334        } else {
7335            // First...  there is no target package, so can anyone access it?
7336            boolean allowed = pi.exported;
7337            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7338                if (pi.readPermission != null) {
7339                    allowed = false;
7340                }
7341            }
7342            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7343                if (pi.writePermission != null) {
7344                    allowed = false;
7345                }
7346            }
7347            if (allowed) {
7348                return -1;
7349            }
7350        }
7351
7352        /* There is a special cross user grant if:
7353         * - The target is on another user.
7354         * - Apps on the current user can access the uri without any uid permissions.
7355         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7356         * grant uri permissions.
7357         */
7358        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7359                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7360                modeFlags, false /*without considering the uid permissions*/);
7361
7362        // Second...  is the provider allowing granting of URI permissions?
7363        if (!specialCrossUserGrant) {
7364            if (!pi.grantUriPermissions) {
7365                throw new SecurityException("Provider " + pi.packageName
7366                        + "/" + pi.name
7367                        + " does not allow granting of Uri permissions (uri "
7368                        + grantUri + ")");
7369            }
7370            if (pi.uriPermissionPatterns != null) {
7371                final int N = pi.uriPermissionPatterns.length;
7372                boolean allowed = false;
7373                for (int i=0; i<N; i++) {
7374                    if (pi.uriPermissionPatterns[i] != null
7375                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7376                        allowed = true;
7377                        break;
7378                    }
7379                }
7380                if (!allowed) {
7381                    throw new SecurityException("Provider " + pi.packageName
7382                            + "/" + pi.name
7383                            + " does not allow granting of permission to path of Uri "
7384                            + grantUri);
7385                }
7386            }
7387        }
7388
7389        // Third...  does the caller itself have permission to access
7390        // this uri?
7391        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7392            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7393                // Require they hold a strong enough Uri permission
7394                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7395                    throw new SecurityException("Uid " + callingUid
7396                            + " does not have permission to uri " + grantUri);
7397                }
7398            }
7399        }
7400        return targetUid;
7401    }
7402
7403    /**
7404     * @param uri This uri must NOT contain an embedded userId.
7405     * @param userId The userId in which the uri is to be resolved.
7406     */
7407    @Override
7408    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7409            final int modeFlags, int userId) {
7410        enforceNotIsolatedCaller("checkGrantUriPermission");
7411        synchronized(this) {
7412            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7413                    new GrantUri(userId, uri, false), modeFlags, -1);
7414        }
7415    }
7416
7417    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7418            final int modeFlags, UriPermissionOwner owner) {
7419        if (!Intent.isAccessUriMode(modeFlags)) {
7420            return;
7421        }
7422
7423        // So here we are: the caller has the assumed permission
7424        // to the uri, and the target doesn't.  Let's now give this to
7425        // the target.
7426
7427        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7428                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7429
7430        final String authority = grantUri.uri.getAuthority();
7431        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7432        if (pi == null) {
7433            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7434            return;
7435        }
7436
7437        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7438            grantUri.prefix = true;
7439        }
7440        final UriPermission perm = findOrCreateUriPermissionLocked(
7441                pi.packageName, targetPkg, targetUid, grantUri);
7442        perm.grantModes(modeFlags, owner);
7443    }
7444
7445    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7446            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7447        if (targetPkg == null) {
7448            throw new NullPointerException("targetPkg");
7449        }
7450        int targetUid;
7451        final IPackageManager pm = AppGlobals.getPackageManager();
7452        try {
7453            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7454        } catch (RemoteException ex) {
7455            return;
7456        }
7457
7458        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7459                targetUid);
7460        if (targetUid < 0) {
7461            return;
7462        }
7463
7464        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7465                owner);
7466    }
7467
7468    static class NeededUriGrants extends ArrayList<GrantUri> {
7469        final String targetPkg;
7470        final int targetUid;
7471        final int flags;
7472
7473        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7474            this.targetPkg = targetPkg;
7475            this.targetUid = targetUid;
7476            this.flags = flags;
7477        }
7478    }
7479
7480    /**
7481     * Like checkGrantUriPermissionLocked, but takes an Intent.
7482     */
7483    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7484            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7485        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7486                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7487                + " clip=" + (intent != null ? intent.getClipData() : null)
7488                + " from " + intent + "; flags=0x"
7489                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7490
7491        if (targetPkg == null) {
7492            throw new NullPointerException("targetPkg");
7493        }
7494
7495        if (intent == null) {
7496            return null;
7497        }
7498        Uri data = intent.getData();
7499        ClipData clip = intent.getClipData();
7500        if (data == null && clip == null) {
7501            return null;
7502        }
7503        // Default userId for uris in the intent (if they don't specify it themselves)
7504        int contentUserHint = intent.getContentUserHint();
7505        if (contentUserHint == UserHandle.USER_CURRENT) {
7506            contentUserHint = UserHandle.getUserId(callingUid);
7507        }
7508        final IPackageManager pm = AppGlobals.getPackageManager();
7509        int targetUid;
7510        if (needed != null) {
7511            targetUid = needed.targetUid;
7512        } else {
7513            try {
7514                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7515            } catch (RemoteException ex) {
7516                return null;
7517            }
7518            if (targetUid < 0) {
7519                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7520                        "Can't grant URI permission no uid for: " + targetPkg
7521                        + " on user " + targetUserId);
7522                return null;
7523            }
7524        }
7525        if (data != null) {
7526            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7527            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7528                    targetUid);
7529            if (targetUid > 0) {
7530                if (needed == null) {
7531                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7532                }
7533                needed.add(grantUri);
7534            }
7535        }
7536        if (clip != null) {
7537            for (int i=0; i<clip.getItemCount(); i++) {
7538                Uri uri = clip.getItemAt(i).getUri();
7539                if (uri != null) {
7540                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7541                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7542                            targetUid);
7543                    if (targetUid > 0) {
7544                        if (needed == null) {
7545                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7546                        }
7547                        needed.add(grantUri);
7548                    }
7549                } else {
7550                    Intent clipIntent = clip.getItemAt(i).getIntent();
7551                    if (clipIntent != null) {
7552                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7553                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7554                        if (newNeeded != null) {
7555                            needed = newNeeded;
7556                        }
7557                    }
7558                }
7559            }
7560        }
7561
7562        return needed;
7563    }
7564
7565    /**
7566     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7567     */
7568    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7569            UriPermissionOwner owner) {
7570        if (needed != null) {
7571            for (int i=0; i<needed.size(); i++) {
7572                GrantUri grantUri = needed.get(i);
7573                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7574                        grantUri, needed.flags, owner);
7575            }
7576        }
7577    }
7578
7579    void grantUriPermissionFromIntentLocked(int callingUid,
7580            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7581        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7582                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7583        if (needed == null) {
7584            return;
7585        }
7586
7587        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7588    }
7589
7590    /**
7591     * @param uri This uri must NOT contain an embedded userId.
7592     * @param userId The userId in which the uri is to be resolved.
7593     */
7594    @Override
7595    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7596            final int modeFlags, int userId) {
7597        enforceNotIsolatedCaller("grantUriPermission");
7598        GrantUri grantUri = new GrantUri(userId, uri, false);
7599        synchronized(this) {
7600            final ProcessRecord r = getRecordForAppLocked(caller);
7601            if (r == null) {
7602                throw new SecurityException("Unable to find app for caller "
7603                        + caller
7604                        + " when granting permission to uri " + grantUri);
7605            }
7606            if (targetPkg == null) {
7607                throw new IllegalArgumentException("null target");
7608            }
7609            if (grantUri == null) {
7610                throw new IllegalArgumentException("null uri");
7611            }
7612
7613            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7614                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7615                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7616                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7617
7618            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7619                    UserHandle.getUserId(r.uid));
7620        }
7621    }
7622
7623    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7624        if (perm.modeFlags == 0) {
7625            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7626                    perm.targetUid);
7627            if (perms != null) {
7628                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7629                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7630
7631                perms.remove(perm.uri);
7632                if (perms.isEmpty()) {
7633                    mGrantedUriPermissions.remove(perm.targetUid);
7634                }
7635            }
7636        }
7637    }
7638
7639    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7640        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7641                "Revoking all granted permissions to " + grantUri);
7642
7643        final IPackageManager pm = AppGlobals.getPackageManager();
7644        final String authority = grantUri.uri.getAuthority();
7645        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7646        if (pi == null) {
7647            Slog.w(TAG, "No content provider found for permission revoke: "
7648                    + grantUri.toSafeString());
7649            return;
7650        }
7651
7652        // Does the caller have this permission on the URI?
7653        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7654            // If they don't have direct access to the URI, then revoke any
7655            // ownerless URI permissions that have been granted to them.
7656            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7657            if (perms != null) {
7658                boolean persistChanged = false;
7659                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7660                    final UriPermission perm = it.next();
7661                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7662                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7663                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7664                                "Revoking non-owned " + perm.targetUid
7665                                + " permission to " + perm.uri);
7666                        persistChanged |= perm.revokeModes(
7667                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7668                        if (perm.modeFlags == 0) {
7669                            it.remove();
7670                        }
7671                    }
7672                }
7673                if (perms.isEmpty()) {
7674                    mGrantedUriPermissions.remove(callingUid);
7675                }
7676                if (persistChanged) {
7677                    schedulePersistUriGrants();
7678                }
7679            }
7680            return;
7681        }
7682
7683        boolean persistChanged = false;
7684
7685        // Go through all of the permissions and remove any that match.
7686        int N = mGrantedUriPermissions.size();
7687        for (int i = 0; i < N; i++) {
7688            final int targetUid = mGrantedUriPermissions.keyAt(i);
7689            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7690
7691            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7692                final UriPermission perm = it.next();
7693                if (perm.uri.sourceUserId == grantUri.sourceUserId
7694                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7695                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7696                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7697                    persistChanged |= perm.revokeModes(
7698                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7699                    if (perm.modeFlags == 0) {
7700                        it.remove();
7701                    }
7702                }
7703            }
7704
7705            if (perms.isEmpty()) {
7706                mGrantedUriPermissions.remove(targetUid);
7707                N--;
7708                i--;
7709            }
7710        }
7711
7712        if (persistChanged) {
7713            schedulePersistUriGrants();
7714        }
7715    }
7716
7717    /**
7718     * @param uri This uri must NOT contain an embedded userId.
7719     * @param userId The userId in which the uri is to be resolved.
7720     */
7721    @Override
7722    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7723            int userId) {
7724        enforceNotIsolatedCaller("revokeUriPermission");
7725        synchronized(this) {
7726            final ProcessRecord r = getRecordForAppLocked(caller);
7727            if (r == null) {
7728                throw new SecurityException("Unable to find app for caller "
7729                        + caller
7730                        + " when revoking permission to uri " + uri);
7731            }
7732            if (uri == null) {
7733                Slog.w(TAG, "revokeUriPermission: null uri");
7734                return;
7735            }
7736
7737            if (!Intent.isAccessUriMode(modeFlags)) {
7738                return;
7739            }
7740
7741            final String authority = uri.getAuthority();
7742            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7743            if (pi == null) {
7744                Slog.w(TAG, "No content provider found for permission revoke: "
7745                        + uri.toSafeString());
7746                return;
7747            }
7748
7749            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7750        }
7751    }
7752
7753    /**
7754     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7755     * given package.
7756     *
7757     * @param packageName Package name to match, or {@code null} to apply to all
7758     *            packages.
7759     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7760     *            to all users.
7761     * @param persistable If persistable grants should be removed.
7762     */
7763    private void removeUriPermissionsForPackageLocked(
7764            String packageName, int userHandle, boolean persistable) {
7765        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7766            throw new IllegalArgumentException("Must narrow by either package or user");
7767        }
7768
7769        boolean persistChanged = false;
7770
7771        int N = mGrantedUriPermissions.size();
7772        for (int i = 0; i < N; i++) {
7773            final int targetUid = mGrantedUriPermissions.keyAt(i);
7774            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7775
7776            // Only inspect grants matching user
7777            if (userHandle == UserHandle.USER_ALL
7778                    || userHandle == UserHandle.getUserId(targetUid)) {
7779                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7780                    final UriPermission perm = it.next();
7781
7782                    // Only inspect grants matching package
7783                    if (packageName == null || perm.sourcePkg.equals(packageName)
7784                            || perm.targetPkg.equals(packageName)) {
7785                        persistChanged |= perm.revokeModes(persistable
7786                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7787
7788                        // Only remove when no modes remain; any persisted grants
7789                        // will keep this alive.
7790                        if (perm.modeFlags == 0) {
7791                            it.remove();
7792                        }
7793                    }
7794                }
7795
7796                if (perms.isEmpty()) {
7797                    mGrantedUriPermissions.remove(targetUid);
7798                    N--;
7799                    i--;
7800                }
7801            }
7802        }
7803
7804        if (persistChanged) {
7805            schedulePersistUriGrants();
7806        }
7807    }
7808
7809    @Override
7810    public IBinder newUriPermissionOwner(String name) {
7811        enforceNotIsolatedCaller("newUriPermissionOwner");
7812        synchronized(this) {
7813            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7814            return owner.getExternalTokenLocked();
7815        }
7816    }
7817
7818    /**
7819     * @param uri This uri must NOT contain an embedded userId.
7820     * @param sourceUserId The userId in which the uri is to be resolved.
7821     * @param targetUserId The userId of the app that receives the grant.
7822     */
7823    @Override
7824    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7825            final int modeFlags, int sourceUserId, int targetUserId) {
7826        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7827                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7828        synchronized(this) {
7829            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7830            if (owner == null) {
7831                throw new IllegalArgumentException("Unknown owner: " + token);
7832            }
7833            if (fromUid != Binder.getCallingUid()) {
7834                if (Binder.getCallingUid() != Process.myUid()) {
7835                    // Only system code can grant URI permissions on behalf
7836                    // of other users.
7837                    throw new SecurityException("nice try");
7838                }
7839            }
7840            if (targetPkg == null) {
7841                throw new IllegalArgumentException("null target");
7842            }
7843            if (uri == null) {
7844                throw new IllegalArgumentException("null uri");
7845            }
7846
7847            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7848                    modeFlags, owner, targetUserId);
7849        }
7850    }
7851
7852    /**
7853     * @param uri This uri must NOT contain an embedded userId.
7854     * @param userId The userId in which the uri is to be resolved.
7855     */
7856    @Override
7857    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7858        synchronized(this) {
7859            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7860            if (owner == null) {
7861                throw new IllegalArgumentException("Unknown owner: " + token);
7862            }
7863
7864            if (uri == null) {
7865                owner.removeUriPermissionsLocked(mode);
7866            } else {
7867                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7868            }
7869        }
7870    }
7871
7872    private void schedulePersistUriGrants() {
7873        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7874            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7875                    10 * DateUtils.SECOND_IN_MILLIS);
7876        }
7877    }
7878
7879    private void writeGrantedUriPermissions() {
7880        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
7881
7882        // Snapshot permissions so we can persist without lock
7883        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7884        synchronized (this) {
7885            final int size = mGrantedUriPermissions.size();
7886            for (int i = 0; i < size; i++) {
7887                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7888                for (UriPermission perm : perms.values()) {
7889                    if (perm.persistedModeFlags != 0) {
7890                        persist.add(perm.snapshot());
7891                    }
7892                }
7893            }
7894        }
7895
7896        FileOutputStream fos = null;
7897        try {
7898            fos = mGrantFile.startWrite();
7899
7900            XmlSerializer out = new FastXmlSerializer();
7901            out.setOutput(fos, StandardCharsets.UTF_8.name());
7902            out.startDocument(null, true);
7903            out.startTag(null, TAG_URI_GRANTS);
7904            for (UriPermission.Snapshot perm : persist) {
7905                out.startTag(null, TAG_URI_GRANT);
7906                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7907                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7908                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7909                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7910                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7911                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7912                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7913                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7914                out.endTag(null, TAG_URI_GRANT);
7915            }
7916            out.endTag(null, TAG_URI_GRANTS);
7917            out.endDocument();
7918
7919            mGrantFile.finishWrite(fos);
7920        } catch (IOException e) {
7921            if (fos != null) {
7922                mGrantFile.failWrite(fos);
7923            }
7924        }
7925    }
7926
7927    private void readGrantedUriPermissionsLocked() {
7928        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
7929
7930        final long now = System.currentTimeMillis();
7931
7932        FileInputStream fis = null;
7933        try {
7934            fis = mGrantFile.openRead();
7935            final XmlPullParser in = Xml.newPullParser();
7936            in.setInput(fis, StandardCharsets.UTF_8.name());
7937
7938            int type;
7939            while ((type = in.next()) != END_DOCUMENT) {
7940                final String tag = in.getName();
7941                if (type == START_TAG) {
7942                    if (TAG_URI_GRANT.equals(tag)) {
7943                        final int sourceUserId;
7944                        final int targetUserId;
7945                        final int userHandle = readIntAttribute(in,
7946                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7947                        if (userHandle != UserHandle.USER_NULL) {
7948                            // For backwards compatibility.
7949                            sourceUserId = userHandle;
7950                            targetUserId = userHandle;
7951                        } else {
7952                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7953                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7954                        }
7955                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7956                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7957                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7958                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7959                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7960                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7961
7962                        // Sanity check that provider still belongs to source package
7963                        final ProviderInfo pi = getProviderInfoLocked(
7964                                uri.getAuthority(), sourceUserId);
7965                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7966                            int targetUid = -1;
7967                            try {
7968                                targetUid = AppGlobals.getPackageManager()
7969                                        .getPackageUid(targetPkg, targetUserId);
7970                            } catch (RemoteException e) {
7971                            }
7972                            if (targetUid != -1) {
7973                                final UriPermission perm = findOrCreateUriPermissionLocked(
7974                                        sourcePkg, targetPkg, targetUid,
7975                                        new GrantUri(sourceUserId, uri, prefix));
7976                                perm.initPersistedModes(modeFlags, createdTime);
7977                            }
7978                        } else {
7979                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7980                                    + " but instead found " + pi);
7981                        }
7982                    }
7983                }
7984            }
7985        } catch (FileNotFoundException e) {
7986            // Missing grants is okay
7987        } catch (IOException e) {
7988            Slog.wtf(TAG, "Failed reading Uri grants", e);
7989        } catch (XmlPullParserException e) {
7990            Slog.wtf(TAG, "Failed reading Uri grants", e);
7991        } finally {
7992            IoUtils.closeQuietly(fis);
7993        }
7994    }
7995
7996    /**
7997     * @param uri This uri must NOT contain an embedded userId.
7998     * @param userId The userId in which the uri is to be resolved.
7999     */
8000    @Override
8001    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8002        enforceNotIsolatedCaller("takePersistableUriPermission");
8003
8004        Preconditions.checkFlagsArgument(modeFlags,
8005                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8006
8007        synchronized (this) {
8008            final int callingUid = Binder.getCallingUid();
8009            boolean persistChanged = false;
8010            GrantUri grantUri = new GrantUri(userId, uri, false);
8011
8012            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8013                    new GrantUri(userId, uri, false));
8014            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8015                    new GrantUri(userId, uri, true));
8016
8017            final boolean exactValid = (exactPerm != null)
8018                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8019            final boolean prefixValid = (prefixPerm != null)
8020                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8021
8022            if (!(exactValid || prefixValid)) {
8023                throw new SecurityException("No persistable permission grants found for UID "
8024                        + callingUid + " and Uri " + grantUri.toSafeString());
8025            }
8026
8027            if (exactValid) {
8028                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8029            }
8030            if (prefixValid) {
8031                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8032            }
8033
8034            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8035
8036            if (persistChanged) {
8037                schedulePersistUriGrants();
8038            }
8039        }
8040    }
8041
8042    /**
8043     * @param uri This uri must NOT contain an embedded userId.
8044     * @param userId The userId in which the uri is to be resolved.
8045     */
8046    @Override
8047    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8048        enforceNotIsolatedCaller("releasePersistableUriPermission");
8049
8050        Preconditions.checkFlagsArgument(modeFlags,
8051                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8052
8053        synchronized (this) {
8054            final int callingUid = Binder.getCallingUid();
8055            boolean persistChanged = false;
8056
8057            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8058                    new GrantUri(userId, uri, false));
8059            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8060                    new GrantUri(userId, uri, true));
8061            if (exactPerm == null && prefixPerm == null) {
8062                throw new SecurityException("No permission grants found for UID " + callingUid
8063                        + " and Uri " + uri.toSafeString());
8064            }
8065
8066            if (exactPerm != null) {
8067                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8068                removeUriPermissionIfNeededLocked(exactPerm);
8069            }
8070            if (prefixPerm != null) {
8071                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8072                removeUriPermissionIfNeededLocked(prefixPerm);
8073            }
8074
8075            if (persistChanged) {
8076                schedulePersistUriGrants();
8077            }
8078        }
8079    }
8080
8081    /**
8082     * Prune any older {@link UriPermission} for the given UID until outstanding
8083     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8084     *
8085     * @return if any mutations occured that require persisting.
8086     */
8087    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8088        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8089        if (perms == null) return false;
8090        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8091
8092        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8093        for (UriPermission perm : perms.values()) {
8094            if (perm.persistedModeFlags != 0) {
8095                persisted.add(perm);
8096            }
8097        }
8098
8099        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8100        if (trimCount <= 0) return false;
8101
8102        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8103        for (int i = 0; i < trimCount; i++) {
8104            final UriPermission perm = persisted.get(i);
8105
8106            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8107                    "Trimming grant created at " + perm.persistedCreateTime);
8108
8109            perm.releasePersistableModes(~0);
8110            removeUriPermissionIfNeededLocked(perm);
8111        }
8112
8113        return true;
8114    }
8115
8116    @Override
8117    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8118            String packageName, boolean incoming) {
8119        enforceNotIsolatedCaller("getPersistedUriPermissions");
8120        Preconditions.checkNotNull(packageName, "packageName");
8121
8122        final int callingUid = Binder.getCallingUid();
8123        final IPackageManager pm = AppGlobals.getPackageManager();
8124        try {
8125            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8126            if (packageUid != callingUid) {
8127                throw new SecurityException(
8128                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8129            }
8130        } catch (RemoteException e) {
8131            throw new SecurityException("Failed to verify package name ownership");
8132        }
8133
8134        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8135        synchronized (this) {
8136            if (incoming) {
8137                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8138                        callingUid);
8139                if (perms == null) {
8140                    Slog.w(TAG, "No permission grants found for " + packageName);
8141                } else {
8142                    for (UriPermission perm : perms.values()) {
8143                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8144                            result.add(perm.buildPersistedPublicApiObject());
8145                        }
8146                    }
8147                }
8148            } else {
8149                final int size = mGrantedUriPermissions.size();
8150                for (int i = 0; i < size; i++) {
8151                    final ArrayMap<GrantUri, UriPermission> perms =
8152                            mGrantedUriPermissions.valueAt(i);
8153                    for (UriPermission perm : perms.values()) {
8154                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8155                            result.add(perm.buildPersistedPublicApiObject());
8156                        }
8157                    }
8158                }
8159            }
8160        }
8161        return new ParceledListSlice<android.content.UriPermission>(result);
8162    }
8163
8164    @Override
8165    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8166        synchronized (this) {
8167            ProcessRecord app =
8168                who != null ? getRecordForAppLocked(who) : null;
8169            if (app == null) return;
8170
8171            Message msg = Message.obtain();
8172            msg.what = WAIT_FOR_DEBUGGER_MSG;
8173            msg.obj = app;
8174            msg.arg1 = waiting ? 1 : 0;
8175            mUiHandler.sendMessage(msg);
8176        }
8177    }
8178
8179    @Override
8180    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8181        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8182        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8183        outInfo.availMem = Process.getFreeMemory();
8184        outInfo.totalMem = Process.getTotalMemory();
8185        outInfo.threshold = homeAppMem;
8186        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8187        outInfo.hiddenAppThreshold = cachedAppMem;
8188        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8189                ProcessList.SERVICE_ADJ);
8190        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8191                ProcessList.VISIBLE_APP_ADJ);
8192        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8193                ProcessList.FOREGROUND_APP_ADJ);
8194    }
8195
8196    // =========================================================
8197    // TASK MANAGEMENT
8198    // =========================================================
8199
8200    @Override
8201    public List<IAppTask> getAppTasks(String callingPackage) {
8202        int callingUid = Binder.getCallingUid();
8203        long ident = Binder.clearCallingIdentity();
8204
8205        synchronized(this) {
8206            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8207            try {
8208                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8209
8210                final int N = mRecentTasks.size();
8211                for (int i = 0; i < N; i++) {
8212                    TaskRecord tr = mRecentTasks.get(i);
8213                    // Skip tasks that do not match the caller.  We don't need to verify
8214                    // callingPackage, because we are also limiting to callingUid and know
8215                    // that will limit to the correct security sandbox.
8216                    if (tr.effectiveUid != callingUid) {
8217                        continue;
8218                    }
8219                    Intent intent = tr.getBaseIntent();
8220                    if (intent == null ||
8221                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8222                        continue;
8223                    }
8224                    ActivityManager.RecentTaskInfo taskInfo =
8225                            createRecentTaskInfoFromTaskRecord(tr);
8226                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8227                    list.add(taskImpl);
8228                }
8229            } finally {
8230                Binder.restoreCallingIdentity(ident);
8231            }
8232            return list;
8233        }
8234    }
8235
8236    @Override
8237    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8238        final int callingUid = Binder.getCallingUid();
8239        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8240
8241        synchronized(this) {
8242            if (DEBUG_ALL) Slog.v(
8243                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8244
8245            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8246                    callingUid);
8247
8248            // TODO: Improve with MRU list from all ActivityStacks.
8249            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8250        }
8251
8252        return list;
8253    }
8254
8255    /**
8256     * Creates a new RecentTaskInfo from a TaskRecord.
8257     */
8258    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8259        // Update the task description to reflect any changes in the task stack
8260        tr.updateTaskDescription();
8261
8262        // Compose the recent task info
8263        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8264        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8265        rti.persistentId = tr.taskId;
8266        rti.baseIntent = new Intent(tr.getBaseIntent());
8267        rti.origActivity = tr.origActivity;
8268        rti.realActivity = tr.realActivity;
8269        rti.description = tr.lastDescription;
8270        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8271        rti.userId = tr.userId;
8272        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8273        rti.firstActiveTime = tr.firstActiveTime;
8274        rti.lastActiveTime = tr.lastActiveTime;
8275        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8276        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8277        rti.numActivities = 0;
8278
8279        ActivityRecord base = null;
8280        ActivityRecord top = null;
8281        ActivityRecord tmp;
8282
8283        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8284            tmp = tr.mActivities.get(i);
8285            if (tmp.finishing) {
8286                continue;
8287            }
8288            base = tmp;
8289            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8290                top = base;
8291            }
8292            rti.numActivities++;
8293        }
8294
8295        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8296        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8297
8298        return rti;
8299    }
8300
8301    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8302        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8303                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8304        if (!allowed) {
8305            if (checkPermission(android.Manifest.permission.GET_TASKS,
8306                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8307                // Temporary compatibility: some existing apps on the system image may
8308                // still be requesting the old permission and not switched to the new
8309                // one; if so, we'll still allow them full access.  This means we need
8310                // to see if they are holding the old permission and are a system app.
8311                try {
8312                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8313                        allowed = true;
8314                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8315                                + " is using old GET_TASKS but privileged; allowing");
8316                    }
8317                } catch (RemoteException e) {
8318                }
8319            }
8320        }
8321        if (!allowed) {
8322            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8323                    + " does not hold REAL_GET_TASKS; limiting output");
8324        }
8325        return allowed;
8326    }
8327
8328    @Override
8329    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8330        final int callingUid = Binder.getCallingUid();
8331        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8332                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8333
8334        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8335        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8336        synchronized (this) {
8337            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8338                    callingUid);
8339            final boolean detailed = checkCallingPermission(
8340                    android.Manifest.permission.GET_DETAILED_TASKS)
8341                    == PackageManager.PERMISSION_GRANTED;
8342
8343            final int recentsCount = mRecentTasks.size();
8344            ArrayList<ActivityManager.RecentTaskInfo> res =
8345                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8346
8347            final Set<Integer> includedUsers;
8348            if (includeProfiles) {
8349                includedUsers = getProfileIdsLocked(userId);
8350            } else {
8351                includedUsers = new HashSet<>();
8352            }
8353            includedUsers.add(Integer.valueOf(userId));
8354
8355            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8356                TaskRecord tr = mRecentTasks.get(i);
8357                // Only add calling user or related users recent tasks
8358                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8359                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8360                    continue;
8361                }
8362
8363                // Return the entry if desired by the caller.  We always return
8364                // the first entry, because callers always expect this to be the
8365                // foreground app.  We may filter others if the caller has
8366                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8367                // we should exclude the entry.
8368
8369                if (i == 0
8370                        || withExcluded
8371                        || (tr.intent == null)
8372                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8373                                == 0)) {
8374                    if (!allowed) {
8375                        // If the caller doesn't have the GET_TASKS permission, then only
8376                        // allow them to see a small subset of tasks -- their own and home.
8377                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8378                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8379                            continue;
8380                        }
8381                    }
8382                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8383                        if (tr.stack != null && tr.stack.isHomeStack()) {
8384                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8385                                    "Skipping, home stack task: " + tr);
8386                            continue;
8387                        }
8388                    }
8389                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8390                        // Don't include auto remove tasks that are finished or finishing.
8391                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8392                                "Skipping, auto-remove without activity: " + tr);
8393                        continue;
8394                    }
8395                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8396                            && !tr.isAvailable) {
8397                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8398                                "Skipping, unavail real act: " + tr);
8399                        continue;
8400                    }
8401
8402                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8403                    if (!detailed) {
8404                        rti.baseIntent.replaceExtras((Bundle)null);
8405                    }
8406
8407                    res.add(rti);
8408                    maxNum--;
8409                }
8410            }
8411            return res;
8412        }
8413    }
8414
8415    @Override
8416    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8417        synchronized (this) {
8418            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8419                    "getTaskThumbnail()");
8420            TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id, false);
8421            if (tr != null) {
8422                return tr.getTaskThumbnailLocked();
8423            }
8424        }
8425        return null;
8426    }
8427
8428    @Override
8429    public int addAppTask(IBinder activityToken, Intent intent,
8430            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8431        final int callingUid = Binder.getCallingUid();
8432        final long callingIdent = Binder.clearCallingIdentity();
8433
8434        try {
8435            synchronized (this) {
8436                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8437                if (r == null) {
8438                    throw new IllegalArgumentException("Activity does not exist; token="
8439                            + activityToken);
8440                }
8441                ComponentName comp = intent.getComponent();
8442                if (comp == null) {
8443                    throw new IllegalArgumentException("Intent " + intent
8444                            + " must specify explicit component");
8445                }
8446                if (thumbnail.getWidth() != mThumbnailWidth
8447                        || thumbnail.getHeight() != mThumbnailHeight) {
8448                    throw new IllegalArgumentException("Bad thumbnail size: got "
8449                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8450                            + mThumbnailWidth + "x" + mThumbnailHeight);
8451                }
8452                if (intent.getSelector() != null) {
8453                    intent.setSelector(null);
8454                }
8455                if (intent.getSourceBounds() != null) {
8456                    intent.setSourceBounds(null);
8457                }
8458                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8459                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8460                        // The caller has added this as an auto-remove task...  that makes no
8461                        // sense, so turn off auto-remove.
8462                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8463                    }
8464                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8465                    // Must be a new task.
8466                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8467                }
8468                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8469                    mLastAddedTaskActivity = null;
8470                }
8471                ActivityInfo ainfo = mLastAddedTaskActivity;
8472                if (ainfo == null) {
8473                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8474                            comp, 0, UserHandle.getUserId(callingUid));
8475                    if (ainfo.applicationInfo.uid != callingUid) {
8476                        throw new SecurityException(
8477                                "Can't add task for another application: target uid="
8478                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8479                    }
8480                }
8481
8482                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8483                        intent, description);
8484
8485                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
8486                if (trimIdx >= 0) {
8487                    // If this would have caused a trim, then we'll abort because that
8488                    // means it would be added at the end of the list but then just removed.
8489                    return INVALID_TASK_ID;
8490                }
8491
8492                final int N = mRecentTasks.size();
8493                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8494                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8495                    tr.removedFromRecents();
8496                }
8497
8498                task.inRecents = true;
8499                mRecentTasks.add(task);
8500                r.task.stack.addTask(task, false, false);
8501
8502                task.setLastThumbnail(thumbnail);
8503                task.freeLastThumbnail();
8504
8505                return task.taskId;
8506            }
8507        } finally {
8508            Binder.restoreCallingIdentity(callingIdent);
8509        }
8510    }
8511
8512    @Override
8513    public Point getAppTaskThumbnailSize() {
8514        synchronized (this) {
8515            return new Point(mThumbnailWidth,  mThumbnailHeight);
8516        }
8517    }
8518
8519    @Override
8520    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8521        synchronized (this) {
8522            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8523            if (r != null) {
8524                r.setTaskDescription(td);
8525                r.task.updateTaskDescription();
8526            }
8527        }
8528    }
8529
8530    @Override
8531    public void setTaskResizeable(int taskId, boolean resizeable) {
8532        synchronized (this) {
8533            TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8534            if (task == null) {
8535                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
8536                return;
8537            }
8538            if (task.mResizeable != resizeable) {
8539                task.mResizeable = resizeable;
8540                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8541                mStackSupervisor.resumeTopActivitiesLocked();
8542            }
8543        }
8544    }
8545
8546    @Override
8547    public void resizeTask(int taskId, Rect bounds) {
8548        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8549                "resizeTask()");
8550        long ident = Binder.clearCallingIdentity();
8551        try {
8552            synchronized (this) {
8553                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8554                if (task == null) {
8555                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
8556                    return;
8557                }
8558                mStackSupervisor.resizeTaskLocked(task, bounds);
8559            }
8560        } finally {
8561            Binder.restoreCallingIdentity(ident);
8562        }
8563    }
8564
8565    @Override
8566    public Bitmap getTaskDescriptionIcon(String filename) {
8567        if (!FileUtils.isValidExtFilename(filename)
8568                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8569            throw new IllegalArgumentException("Bad filename: " + filename);
8570        }
8571        return mTaskPersister.getTaskDescriptionIcon(filename);
8572    }
8573
8574    @Override
8575    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8576            throws RemoteException {
8577        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8578                opts.getCustomInPlaceResId() == 0) {
8579            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8580                    "with valid animation");
8581        }
8582        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8583        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8584                opts.getCustomInPlaceResId());
8585        mWindowManager.executeAppTransition();
8586    }
8587
8588    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8589        mRecentTasks.remove(tr);
8590        tr.removedFromRecents();
8591        ComponentName component = tr.getBaseIntent().getComponent();
8592        if (component == null) {
8593            Slog.w(TAG, "No component for base intent of task: " + tr);
8594            return;
8595        }
8596
8597        // Find any running services associated with this app and stop if needed.
8598        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8599
8600        if (!killProcess) {
8601            return;
8602        }
8603
8604        // Determine if the process(es) for this task should be killed.
8605        final String pkg = component.getPackageName();
8606        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
8607        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8608        for (int i = 0; i < pmap.size(); i++) {
8609
8610            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8611            for (int j = 0; j < uids.size(); j++) {
8612                ProcessRecord proc = uids.valueAt(j);
8613                if (proc.userId != tr.userId) {
8614                    // Don't kill process for a different user.
8615                    continue;
8616                }
8617                if (proc == mHomeProcess) {
8618                    // Don't kill the home process along with tasks from the same package.
8619                    continue;
8620                }
8621                if (!proc.pkgList.containsKey(pkg)) {
8622                    // Don't kill process that is not associated with this task.
8623                    continue;
8624                }
8625
8626                for (int k = 0; k < proc.activities.size(); k++) {
8627                    TaskRecord otherTask = proc.activities.get(k).task;
8628                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8629                        // Don't kill process(es) that has an activity in a different task that is
8630                        // also in recents.
8631                        return;
8632                    }
8633                }
8634
8635                if (proc.foregroundServices) {
8636                    // Don't kill process(es) with foreground service.
8637                    return;
8638                }
8639
8640                // Add process to kill list.
8641                procsToKill.add(proc);
8642            }
8643        }
8644
8645        // Kill the running processes.
8646        for (int i = 0; i < procsToKill.size(); i++) {
8647            ProcessRecord pr = procsToKill.get(i);
8648            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
8649                    && pr.curReceiver == null) {
8650                pr.kill("remove task", true);
8651            } else {
8652                // We delay killing processes that are not in the background or running a receiver.
8653                pr.waitingToKill = "remove task";
8654            }
8655        }
8656    }
8657
8658    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8659        // Remove all tasks with activities in the specified package from the list of recent tasks
8660        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8661            TaskRecord tr = mRecentTasks.get(i);
8662            if (tr.userId != userId) continue;
8663
8664            ComponentName cn = tr.intent.getComponent();
8665            if (cn != null && cn.getPackageName().equals(packageName)) {
8666                // If the package name matches, remove the task.
8667                removeTaskByIdLocked(tr.taskId, true);
8668            }
8669        }
8670    }
8671
8672    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
8673            int userId) {
8674
8675        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8676            TaskRecord tr = mRecentTasks.get(i);
8677            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
8678                continue;
8679            }
8680
8681            ComponentName cn = tr.intent.getComponent();
8682            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
8683                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
8684            if (sameComponent) {
8685                removeTaskByIdLocked(tr.taskId, false);
8686            }
8687        }
8688    }
8689
8690    /**
8691     * Removes the task with the specified task id.
8692     *
8693     * @param taskId Identifier of the task to be removed.
8694     * @param killProcess Kill any process associated with the task if possible.
8695     * @return Returns true if the given task was found and removed.
8696     */
8697    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8698        TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8699        if (tr != null) {
8700            tr.removeTaskActivitiesLocked();
8701            cleanUpRemovedTaskLocked(tr, killProcess);
8702            if (tr.isPersistable) {
8703                notifyTaskPersisterLocked(null, true);
8704            }
8705            return true;
8706        }
8707        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8708        return false;
8709    }
8710
8711    @Override
8712    public boolean removeTask(int taskId) {
8713        synchronized (this) {
8714            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8715                    "removeTask()");
8716            long ident = Binder.clearCallingIdentity();
8717            try {
8718                return removeTaskByIdLocked(taskId, true);
8719            } finally {
8720                Binder.restoreCallingIdentity(ident);
8721            }
8722        }
8723    }
8724
8725    /**
8726     * TODO: Add mController hook
8727     */
8728    @Override
8729    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8730        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
8731
8732        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
8733        synchronized(this) {
8734            moveTaskToFrontLocked(taskId, flags, options);
8735        }
8736    }
8737
8738    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8739        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8740                Binder.getCallingUid(), -1, -1, "Task to front")) {
8741            ActivityOptions.abort(options);
8742            return;
8743        }
8744        final long origId = Binder.clearCallingIdentity();
8745        try {
8746            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8747            if (task == null) {
8748                Slog.d(TAG, "Could not find task for id: "+ taskId);
8749                return;
8750            }
8751            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8752                mStackSupervisor.showLockTaskToast();
8753                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8754                return;
8755            }
8756            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8757            if (prev != null && prev.isRecentsActivity()) {
8758                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8759            }
8760            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
8761        } finally {
8762            Binder.restoreCallingIdentity(origId);
8763        }
8764        ActivityOptions.abort(options);
8765    }
8766
8767    /**
8768     * Moves an activity, and all of the other activities within the same task, to the bottom
8769     * of the history stack.  The activity's order within the task is unchanged.
8770     *
8771     * @param token A reference to the activity we wish to move
8772     * @param nonRoot If false then this only works if the activity is the root
8773     *                of a task; if true it will work for any activity in a task.
8774     * @return Returns true if the move completed, false if not.
8775     */
8776    @Override
8777    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8778        enforceNotIsolatedCaller("moveActivityTaskToBack");
8779        synchronized(this) {
8780            final long origId = Binder.clearCallingIdentity();
8781            try {
8782                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8783                final TaskRecord task = mRecentTasks.taskForIdLocked(taskId);
8784                if (task != null) {
8785                    if (mStackSupervisor.isLockedTask(task)) {
8786                        mStackSupervisor.showLockTaskToast();
8787                        return false;
8788                    }
8789                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
8790                }
8791            } finally {
8792                Binder.restoreCallingIdentity(origId);
8793            }
8794        }
8795        return false;
8796    }
8797
8798    @Override
8799    public void moveTaskBackwards(int task) {
8800        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8801                "moveTaskBackwards()");
8802
8803        synchronized(this) {
8804            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8805                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8806                return;
8807            }
8808            final long origId = Binder.clearCallingIdentity();
8809            moveTaskBackwardsLocked(task);
8810            Binder.restoreCallingIdentity(origId);
8811        }
8812    }
8813
8814    private final void moveTaskBackwardsLocked(int task) {
8815        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8816    }
8817
8818    @Override
8819    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
8820            IActivityContainerCallback callback) throws RemoteException {
8821        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8822                "createActivityContainer()");
8823        synchronized (this) {
8824            if (parentActivityToken == null) {
8825                throw new IllegalArgumentException("parent token must not be null");
8826            }
8827            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
8828            if (r == null) {
8829                return null;
8830            }
8831            if (callback == null) {
8832                throw new IllegalArgumentException("callback must not be null");
8833            }
8834            return mStackSupervisor.createVirtualActivityContainer(r, callback);
8835        }
8836    }
8837
8838    @Override
8839    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8840        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8841                "deleteActivityContainer()");
8842        synchronized (this) {
8843            mStackSupervisor.deleteActivityContainer(container);
8844        }
8845    }
8846
8847    @Override
8848    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
8849        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8850                "createStackOnDisplay()");
8851        synchronized (this) {
8852            final int stackId = mStackSupervisor.getNextStackId();
8853            final ActivityStack stack = mStackSupervisor.createStackOnDisplay(stackId, displayId);
8854            if (stack == null) {
8855                return null;
8856            }
8857            return stack.mActivityContainer;
8858        }
8859    }
8860
8861    @Override
8862    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
8863        synchronized (this) {
8864            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8865            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
8866                return stack.mActivityContainer.getDisplayId();
8867            }
8868            return Display.DEFAULT_DISPLAY;
8869        }
8870    }
8871
8872    @Override
8873    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8874        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8875                "moveTaskToStack()");
8876        if (stackId == HOME_STACK_ID) {
8877            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8878                    new RuntimeException("here").fillInStackTrace());
8879        }
8880        synchronized (this) {
8881            long ident = Binder.clearCallingIdentity();
8882            try {
8883                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
8884                        + " to stackId=" + stackId + " toTop=" + toTop);
8885                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop);
8886            } finally {
8887                Binder.restoreCallingIdentity(ident);
8888            }
8889        }
8890    }
8891
8892    @Override
8893    public void resizeStack(int stackId, Rect bounds) {
8894        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8895                "resizeStack()");
8896        long ident = Binder.clearCallingIdentity();
8897        try {
8898            synchronized (this) {
8899                mStackSupervisor.resizeStackLocked(stackId, bounds);
8900            }
8901        } finally {
8902            Binder.restoreCallingIdentity(ident);
8903        }
8904    }
8905
8906    @Override
8907    public List<StackInfo> getAllStackInfos() {
8908        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8909                "getAllStackInfos()");
8910        long ident = Binder.clearCallingIdentity();
8911        try {
8912            synchronized (this) {
8913                return mStackSupervisor.getAllStackInfosLocked();
8914            }
8915        } finally {
8916            Binder.restoreCallingIdentity(ident);
8917        }
8918    }
8919
8920    @Override
8921    public StackInfo getStackInfo(int stackId) {
8922        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8923                "getStackInfo()");
8924        long ident = Binder.clearCallingIdentity();
8925        try {
8926            synchronized (this) {
8927                return mStackSupervisor.getStackInfoLocked(stackId);
8928            }
8929        } finally {
8930            Binder.restoreCallingIdentity(ident);
8931        }
8932    }
8933
8934    @Override
8935    public boolean isInHomeStack(int taskId) {
8936        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8937                "getStackInfo()");
8938        long ident = Binder.clearCallingIdentity();
8939        try {
8940            synchronized (this) {
8941                TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8942                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8943            }
8944        } finally {
8945            Binder.restoreCallingIdentity(ident);
8946        }
8947    }
8948
8949    @Override
8950    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8951        synchronized(this) {
8952            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8953        }
8954    }
8955
8956    @Override
8957    public void updateDeviceOwner(String packageName) {
8958        final int callingUid = Binder.getCallingUid();
8959        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
8960            throw new SecurityException("updateDeviceOwner called from non-system process");
8961        }
8962        synchronized (this) {
8963            mDeviceOwnerName = packageName;
8964        }
8965    }
8966
8967    @Override
8968    public void updateLockTaskPackages(int userId, String[] packages) {
8969        final int callingUid = Binder.getCallingUid();
8970        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
8971            throw new SecurityException("updateLockTaskPackage called from non-system process");
8972        }
8973        synchronized (this) {
8974            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
8975                    Arrays.toString(packages));
8976            mLockTaskPackages.put(userId, packages);
8977            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
8978        }
8979    }
8980
8981
8982    void startLockTaskModeLocked(TaskRecord task) {
8983        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
8984        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
8985            return;
8986        }
8987
8988        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
8989        // is initiated by system after the pinning request was shown and locked mode is initiated
8990        // by an authorized app directly
8991        final int callingUid = Binder.getCallingUid();
8992        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
8993        long ident = Binder.clearCallingIdentity();
8994        try {
8995            final ActivityStack stack = mStackSupervisor.getFocusedStack();
8996            if (!isSystemInitiated) {
8997                task.mLockTaskUid = callingUid;
8998                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
8999                    // startLockTask() called by app and task mode is lockTaskModeDefault.
9000                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9001                    StatusBarManagerInternal statusBarManager =
9002                            LocalServices.getService(StatusBarManagerInternal.class);
9003                    if (statusBarManager != null) {
9004                        statusBarManager.showScreenPinningRequest();
9005                    }
9006                    return;
9007                }
9008
9009                if (stack == null || task != stack.topTask()) {
9010                    throw new IllegalArgumentException("Invalid task, not in foreground");
9011                }
9012            }
9013            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9014                    "Locking fully");
9015            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9016                    ActivityManager.LOCK_TASK_MODE_PINNED :
9017                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9018                    "startLockTask", true);
9019        } finally {
9020            Binder.restoreCallingIdentity(ident);
9021        }
9022    }
9023
9024    @Override
9025    public void startLockTaskMode(int taskId) {
9026        synchronized (this) {
9027            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9028            if (task != null) {
9029                startLockTaskModeLocked(task);
9030            }
9031        }
9032    }
9033
9034    @Override
9035    public void startLockTaskMode(IBinder token) {
9036        synchronized (this) {
9037            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9038            if (r == null) {
9039                return;
9040            }
9041            final TaskRecord task = r.task;
9042            if (task != null) {
9043                startLockTaskModeLocked(task);
9044            }
9045        }
9046    }
9047
9048    @Override
9049    public void startLockTaskModeOnCurrent() throws RemoteException {
9050        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9051                "startLockTaskModeOnCurrent");
9052        long ident = Binder.clearCallingIdentity();
9053        try {
9054            synchronized (this) {
9055                ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9056                if (r != null) {
9057                    startLockTaskModeLocked(r.task);
9058                }
9059            }
9060        } finally {
9061            Binder.restoreCallingIdentity(ident);
9062        }
9063    }
9064
9065    @Override
9066    public void stopLockTaskMode() {
9067        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9068        if (lockTask == null) {
9069            // Our work here is done.
9070            return;
9071        }
9072
9073        final int callingUid = Binder.getCallingUid();
9074        final int lockTaskUid = lockTask.mLockTaskUid;
9075        // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9076        // It is possible lockTaskMode was started by the system process because
9077        // android:lockTaskMode is set to a locking value in the application manifest instead of
9078        // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9079        // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9080        if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9081                callingUid != lockTaskUid
9082                && (lockTaskUid != 0
9083                    || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9084            throw new SecurityException("Invalid uid, expected " + lockTaskUid
9085                    + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9086        }
9087
9088        long ident = Binder.clearCallingIdentity();
9089        try {
9090            Log.d(TAG, "stopLockTaskMode");
9091            // Stop lock task
9092            synchronized (this) {
9093                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9094                        "stopLockTask", true);
9095            }
9096        } finally {
9097            Binder.restoreCallingIdentity(ident);
9098        }
9099    }
9100
9101    @Override
9102    public void stopLockTaskModeOnCurrent() throws RemoteException {
9103        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9104                "stopLockTaskModeOnCurrent");
9105        long ident = Binder.clearCallingIdentity();
9106        try {
9107            stopLockTaskMode();
9108        } finally {
9109            Binder.restoreCallingIdentity(ident);
9110        }
9111    }
9112
9113    @Override
9114    public boolean isInLockTaskMode() {
9115        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9116    }
9117
9118    @Override
9119    public int getLockTaskModeState() {
9120        synchronized (this) {
9121            return mStackSupervisor.getLockTaskModeState();
9122        }
9123    }
9124
9125    @Override
9126    public void showLockTaskEscapeMessage(IBinder token) {
9127        synchronized (this) {
9128            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9129            if (r == null) {
9130                return;
9131            }
9132            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9133        }
9134    }
9135
9136    // =========================================================
9137    // CONTENT PROVIDERS
9138    // =========================================================
9139
9140    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9141        List<ProviderInfo> providers = null;
9142        try {
9143            providers = AppGlobals.getPackageManager().
9144                queryContentProviders(app.processName, app.uid,
9145                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
9146        } catch (RemoteException ex) {
9147        }
9148        if (DEBUG_MU) Slog.v(TAG_MU,
9149                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9150        int userId = app.userId;
9151        if (providers != null) {
9152            int N = providers.size();
9153            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9154            for (int i=0; i<N; i++) {
9155                ProviderInfo cpi =
9156                    (ProviderInfo)providers.get(i);
9157                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9158                        cpi.name, cpi.flags);
9159                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_OWNER) {
9160                    // This is a singleton provider, but a user besides the
9161                    // default user is asking to initialize a process it runs
9162                    // in...  well, no, it doesn't actually run in this process,
9163                    // it runs in the process of the default user.  Get rid of it.
9164                    providers.remove(i);
9165                    N--;
9166                    i--;
9167                    continue;
9168                }
9169
9170                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9171                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9172                if (cpr == null) {
9173                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9174                    mProviderMap.putProviderByClass(comp, cpr);
9175                }
9176                if (DEBUG_MU) Slog.v(TAG_MU,
9177                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9178                app.pubProviders.put(cpi.name, cpr);
9179                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9180                    // Don't add this if it is a platform component that is marked
9181                    // to run in multiple processes, because this is actually
9182                    // part of the framework so doesn't make sense to track as a
9183                    // separate apk in the process.
9184                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9185                            mProcessStats);
9186                }
9187                ensurePackageDexOpt(cpi.applicationInfo.packageName);
9188            }
9189        }
9190        return providers;
9191    }
9192
9193    /**
9194     * Check if {@link ProcessRecord} has a possible chance at accessing the
9195     * given {@link ProviderInfo}. Final permission checking is always done
9196     * in {@link ContentProvider}.
9197     */
9198    private final String checkContentProviderPermissionLocked(
9199            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9200        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9201        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9202        boolean checkedGrants = false;
9203        if (checkUser) {
9204            // Looking for cross-user grants before enforcing the typical cross-users permissions
9205            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
9206            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9207                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9208                    return null;
9209                }
9210                checkedGrants = true;
9211            }
9212            userId = handleIncomingUser(callingPid, callingUid, userId,
9213                    false, ALLOW_NON_FULL,
9214                    "checkContentProviderPermissionLocked " + cpi.authority, null);
9215            if (userId != tmpTargetUserId) {
9216                // When we actually went to determine the final targer user ID, this ended
9217                // up different than our initial check for the authority.  This is because
9218                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9219                // SELF.  So we need to re-check the grants again.
9220                checkedGrants = false;
9221            }
9222        }
9223        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9224                cpi.applicationInfo.uid, cpi.exported)
9225                == PackageManager.PERMISSION_GRANTED) {
9226            return null;
9227        }
9228        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9229                cpi.applicationInfo.uid, cpi.exported)
9230                == PackageManager.PERMISSION_GRANTED) {
9231            return null;
9232        }
9233
9234        PathPermission[] pps = cpi.pathPermissions;
9235        if (pps != null) {
9236            int i = pps.length;
9237            while (i > 0) {
9238                i--;
9239                PathPermission pp = pps[i];
9240                String pprperm = pp.getReadPermission();
9241                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9242                        cpi.applicationInfo.uid, cpi.exported)
9243                        == PackageManager.PERMISSION_GRANTED) {
9244                    return null;
9245                }
9246                String ppwperm = pp.getWritePermission();
9247                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9248                        cpi.applicationInfo.uid, cpi.exported)
9249                        == PackageManager.PERMISSION_GRANTED) {
9250                    return null;
9251                }
9252            }
9253        }
9254        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9255            return null;
9256        }
9257
9258        String msg;
9259        if (!cpi.exported) {
9260            msg = "Permission Denial: opening provider " + cpi.name
9261                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9262                    + ", uid=" + callingUid + ") that is not exported from uid "
9263                    + cpi.applicationInfo.uid;
9264        } else {
9265            msg = "Permission Denial: opening provider " + cpi.name
9266                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9267                    + ", uid=" + callingUid + ") requires "
9268                    + cpi.readPermission + " or " + cpi.writePermission;
9269        }
9270        Slog.w(TAG, msg);
9271        return msg;
9272    }
9273
9274    /**
9275     * Returns if the ContentProvider has granted a uri to callingUid
9276     */
9277    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9278        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9279        if (perms != null) {
9280            for (int i=perms.size()-1; i>=0; i--) {
9281                GrantUri grantUri = perms.keyAt(i);
9282                if (grantUri.sourceUserId == userId || !checkUser) {
9283                    if (matchesProvider(grantUri.uri, cpi)) {
9284                        return true;
9285                    }
9286                }
9287            }
9288        }
9289        return false;
9290    }
9291
9292    /**
9293     * Returns true if the uri authority is one of the authorities specified in the provider.
9294     */
9295    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9296        String uriAuth = uri.getAuthority();
9297        String cpiAuth = cpi.authority;
9298        if (cpiAuth.indexOf(';') == -1) {
9299            return cpiAuth.equals(uriAuth);
9300        }
9301        String[] cpiAuths = cpiAuth.split(";");
9302        int length = cpiAuths.length;
9303        for (int i = 0; i < length; i++) {
9304            if (cpiAuths[i].equals(uriAuth)) return true;
9305        }
9306        return false;
9307    }
9308
9309    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9310            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9311        if (r != null) {
9312            for (int i=0; i<r.conProviders.size(); i++) {
9313                ContentProviderConnection conn = r.conProviders.get(i);
9314                if (conn.provider == cpr) {
9315                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9316                            "Adding provider requested by "
9317                            + r.processName + " from process "
9318                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9319                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9320                    if (stable) {
9321                        conn.stableCount++;
9322                        conn.numStableIncs++;
9323                    } else {
9324                        conn.unstableCount++;
9325                        conn.numUnstableIncs++;
9326                    }
9327                    return conn;
9328                }
9329            }
9330            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9331            if (stable) {
9332                conn.stableCount = 1;
9333                conn.numStableIncs = 1;
9334            } else {
9335                conn.unstableCount = 1;
9336                conn.numUnstableIncs = 1;
9337            }
9338            cpr.connections.add(conn);
9339            r.conProviders.add(conn);
9340            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9341            return conn;
9342        }
9343        cpr.addExternalProcessHandleLocked(externalProcessToken);
9344        return null;
9345    }
9346
9347    boolean decProviderCountLocked(ContentProviderConnection conn,
9348            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9349        if (conn != null) {
9350            cpr = conn.provider;
9351            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9352                    "Removing provider requested by "
9353                    + conn.client.processName + " from process "
9354                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9355                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9356            if (stable) {
9357                conn.stableCount--;
9358            } else {
9359                conn.unstableCount--;
9360            }
9361            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9362                cpr.connections.remove(conn);
9363                conn.client.conProviders.remove(conn);
9364                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9365                return true;
9366            }
9367            return false;
9368        }
9369        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9370        return false;
9371    }
9372
9373    private void checkTime(long startTime, String where) {
9374        long now = SystemClock.elapsedRealtime();
9375        if ((now-startTime) > 1000) {
9376            // If we are taking more than a second, log about it.
9377            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9378        }
9379    }
9380
9381    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9382            String name, IBinder token, boolean stable, int userId) {
9383        ContentProviderRecord cpr;
9384        ContentProviderConnection conn = null;
9385        ProviderInfo cpi = null;
9386
9387        synchronized(this) {
9388            long startTime = SystemClock.elapsedRealtime();
9389
9390            ProcessRecord r = null;
9391            if (caller != null) {
9392                r = getRecordForAppLocked(caller);
9393                if (r == null) {
9394                    throw new SecurityException(
9395                            "Unable to find app for caller " + caller
9396                          + " (pid=" + Binder.getCallingPid()
9397                          + ") when getting content provider " + name);
9398                }
9399            }
9400
9401            boolean checkCrossUser = true;
9402
9403            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9404
9405            // First check if this content provider has been published...
9406            cpr = mProviderMap.getProviderByName(name, userId);
9407            // If that didn't work, check if it exists for user 0 and then
9408            // verify that it's a singleton provider before using it.
9409            if (cpr == null && userId != UserHandle.USER_OWNER) {
9410                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9411                if (cpr != null) {
9412                    cpi = cpr.info;
9413                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9414                            cpi.name, cpi.flags)
9415                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9416                        userId = UserHandle.USER_OWNER;
9417                        checkCrossUser = false;
9418                    } else {
9419                        cpr = null;
9420                        cpi = null;
9421                    }
9422                }
9423            }
9424
9425            boolean providerRunning = cpr != null;
9426            if (providerRunning) {
9427                cpi = cpr.info;
9428                String msg;
9429                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9430                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9431                        != null) {
9432                    throw new SecurityException(msg);
9433                }
9434                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9435
9436                if (r != null && cpr.canRunHere(r)) {
9437                    // This provider has been published or is in the process
9438                    // of being published...  but it is also allowed to run
9439                    // in the caller's process, so don't make a connection
9440                    // and just let the caller instantiate its own instance.
9441                    ContentProviderHolder holder = cpr.newHolder(null);
9442                    // don't give caller the provider object, it needs
9443                    // to make its own.
9444                    holder.provider = null;
9445                    return holder;
9446                }
9447
9448                final long origId = Binder.clearCallingIdentity();
9449
9450                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9451
9452                // In this case the provider instance already exists, so we can
9453                // return it right away.
9454                conn = incProviderCountLocked(r, cpr, token, stable);
9455                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9456                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9457                        // If this is a perceptible app accessing the provider,
9458                        // make sure to count it as being accessed and thus
9459                        // back up on the LRU list.  This is good because
9460                        // content providers are often expensive to start.
9461                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9462                        updateLruProcessLocked(cpr.proc, false, null);
9463                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9464                    }
9465                }
9466
9467                if (cpr.proc != null) {
9468                    if (false) {
9469                        if (cpr.name.flattenToShortString().equals(
9470                                "com.android.providers.calendar/.CalendarProvider2")) {
9471                            Slog.v(TAG, "****************** KILLING "
9472                                + cpr.name.flattenToShortString());
9473                            Process.killProcess(cpr.proc.pid);
9474                        }
9475                    }
9476                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9477                    boolean success = updateOomAdjLocked(cpr.proc);
9478                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
9479                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9480                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
9481                    // NOTE: there is still a race here where a signal could be
9482                    // pending on the process even though we managed to update its
9483                    // adj level.  Not sure what to do about this, but at least
9484                    // the race is now smaller.
9485                    if (!success) {
9486                        // Uh oh...  it looks like the provider's process
9487                        // has been killed on us.  We need to wait for a new
9488                        // process to be started, and make sure its death
9489                        // doesn't kill our process.
9490                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
9491                                + " is crashing; detaching " + r);
9492                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9493                        checkTime(startTime, "getContentProviderImpl: before appDied");
9494                        appDiedLocked(cpr.proc);
9495                        checkTime(startTime, "getContentProviderImpl: after appDied");
9496                        if (!lastRef) {
9497                            // This wasn't the last ref our process had on
9498                            // the provider...  we have now been killed, bail.
9499                            return null;
9500                        }
9501                        providerRunning = false;
9502                        conn = null;
9503                    }
9504                }
9505
9506                Binder.restoreCallingIdentity(origId);
9507            }
9508
9509            boolean singleton;
9510            if (!providerRunning) {
9511                try {
9512                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9513                    cpi = AppGlobals.getPackageManager().
9514                        resolveContentProvider(name,
9515                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9516                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9517                } catch (RemoteException ex) {
9518                }
9519                if (cpi == null) {
9520                    return null;
9521                }
9522                // If the provider is a singleton AND
9523                // (it's a call within the same user || the provider is a
9524                // privileged app)
9525                // Then allow connecting to the singleton provider
9526                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9527                        cpi.name, cpi.flags)
9528                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9529                if (singleton) {
9530                    userId = UserHandle.USER_OWNER;
9531                }
9532                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9533                checkTime(startTime, "getContentProviderImpl: got app info for user");
9534
9535                String msg;
9536                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9537                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9538                        != null) {
9539                    throw new SecurityException(msg);
9540                }
9541                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9542
9543                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9544                        && !cpi.processName.equals("system")) {
9545                    // If this content provider does not run in the system
9546                    // process, and the system is not yet ready to run other
9547                    // processes, then fail fast instead of hanging.
9548                    throw new IllegalArgumentException(
9549                            "Attempt to launch content provider before system ready");
9550                }
9551
9552                // Make sure that the user who owns this provider is running.  If not,
9553                // we don't want to allow it to run.
9554                if (!isUserRunningLocked(userId, false)) {
9555                    Slog.w(TAG, "Unable to launch app "
9556                            + cpi.applicationInfo.packageName + "/"
9557                            + cpi.applicationInfo.uid + " for provider "
9558                            + name + ": user " + userId + " is stopped");
9559                    return null;
9560                }
9561
9562                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9563                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9564                cpr = mProviderMap.getProviderByClass(comp, userId);
9565                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9566                final boolean firstClass = cpr == null;
9567                if (firstClass) {
9568                    final long ident = Binder.clearCallingIdentity();
9569                    try {
9570                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9571                        ApplicationInfo ai =
9572                            AppGlobals.getPackageManager().
9573                                getApplicationInfo(
9574                                        cpi.applicationInfo.packageName,
9575                                        STOCK_PM_FLAGS, userId);
9576                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9577                        if (ai == null) {
9578                            Slog.w(TAG, "No package info for content provider "
9579                                    + cpi.name);
9580                            return null;
9581                        }
9582                        ai = getAppInfoForUser(ai, userId);
9583                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9584                    } catch (RemoteException ex) {
9585                        // pm is in same process, this will never happen.
9586                    } finally {
9587                        Binder.restoreCallingIdentity(ident);
9588                    }
9589                }
9590
9591                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9592
9593                if (r != null && cpr.canRunHere(r)) {
9594                    // If this is a multiprocess provider, then just return its
9595                    // info and allow the caller to instantiate it.  Only do
9596                    // this if the provider is the same user as the caller's
9597                    // process, or can run as root (so can be in any process).
9598                    return cpr.newHolder(null);
9599                }
9600
9601                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
9602                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
9603                            + cpr.info.name + " callers=" + Debug.getCallers(6));
9604
9605                // This is single process, and our app is now connecting to it.
9606                // See if we are already in the process of launching this
9607                // provider.
9608                final int N = mLaunchingProviders.size();
9609                int i;
9610                for (i = 0; i < N; i++) {
9611                    if (mLaunchingProviders.get(i) == cpr) {
9612                        break;
9613                    }
9614                }
9615
9616                // If the provider is not already being launched, then get it
9617                // started.
9618                if (i >= N) {
9619                    final long origId = Binder.clearCallingIdentity();
9620
9621                    try {
9622                        // Content provider is now in use, its package can't be stopped.
9623                        try {
9624                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9625                            AppGlobals.getPackageManager().setPackageStoppedState(
9626                                    cpr.appInfo.packageName, false, userId);
9627                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9628                        } catch (RemoteException e) {
9629                        } catch (IllegalArgumentException e) {
9630                            Slog.w(TAG, "Failed trying to unstop package "
9631                                    + cpr.appInfo.packageName + ": " + e);
9632                        }
9633
9634                        // Use existing process if already started
9635                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9636                        ProcessRecord proc = getProcessRecordLocked(
9637                                cpi.processName, cpr.appInfo.uid, false);
9638                        if (proc != null && proc.thread != null) {
9639                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
9640                                    "Installing in existing process " + proc);
9641                            if (!proc.pubProviders.containsKey(cpi.name)) {
9642                                checkTime(startTime, "getContentProviderImpl: scheduling install");
9643                                proc.pubProviders.put(cpi.name, cpr);
9644                                try {
9645                                    proc.thread.scheduleInstallProvider(cpi);
9646                                } catch (RemoteException e) {
9647                                }
9648                            }
9649                        } else {
9650                            checkTime(startTime, "getContentProviderImpl: before start process");
9651                            proc = startProcessLocked(cpi.processName,
9652                                    cpr.appInfo, false, 0, "content provider",
9653                                    new ComponentName(cpi.applicationInfo.packageName,
9654                                            cpi.name), false, false, false);
9655                            checkTime(startTime, "getContentProviderImpl: after start process");
9656                            if (proc == null) {
9657                                Slog.w(TAG, "Unable to launch app "
9658                                        + cpi.applicationInfo.packageName + "/"
9659                                        + cpi.applicationInfo.uid + " for provider "
9660                                        + name + ": process is bad");
9661                                return null;
9662                            }
9663                        }
9664                        cpr.launchingApp = proc;
9665                        mLaunchingProviders.add(cpr);
9666                    } finally {
9667                        Binder.restoreCallingIdentity(origId);
9668                    }
9669                }
9670
9671                checkTime(startTime, "getContentProviderImpl: updating data structures");
9672
9673                // Make sure the provider is published (the same provider class
9674                // may be published under multiple names).
9675                if (firstClass) {
9676                    mProviderMap.putProviderByClass(comp, cpr);
9677                }
9678
9679                mProviderMap.putProviderByName(name, cpr);
9680                conn = incProviderCountLocked(r, cpr, token, stable);
9681                if (conn != null) {
9682                    conn.waiting = true;
9683                }
9684            }
9685            checkTime(startTime, "getContentProviderImpl: done!");
9686        }
9687
9688        // Wait for the provider to be published...
9689        synchronized (cpr) {
9690            while (cpr.provider == null) {
9691                if (cpr.launchingApp == null) {
9692                    Slog.w(TAG, "Unable to launch app "
9693                            + cpi.applicationInfo.packageName + "/"
9694                            + cpi.applicationInfo.uid + " for provider "
9695                            + name + ": launching app became null");
9696                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9697                            UserHandle.getUserId(cpi.applicationInfo.uid),
9698                            cpi.applicationInfo.packageName,
9699                            cpi.applicationInfo.uid, name);
9700                    return null;
9701                }
9702                try {
9703                    if (DEBUG_MU) Slog.v(TAG_MU,
9704                            "Waiting to start provider " + cpr
9705                            + " launchingApp=" + cpr.launchingApp);
9706                    if (conn != null) {
9707                        conn.waiting = true;
9708                    }
9709                    cpr.wait();
9710                } catch (InterruptedException ex) {
9711                } finally {
9712                    if (conn != null) {
9713                        conn.waiting = false;
9714                    }
9715                }
9716            }
9717        }
9718        return cpr != null ? cpr.newHolder(conn) : null;
9719    }
9720
9721    @Override
9722    public final ContentProviderHolder getContentProvider(
9723            IApplicationThread caller, String name, int userId, boolean stable) {
9724        enforceNotIsolatedCaller("getContentProvider");
9725        if (caller == null) {
9726            String msg = "null IApplicationThread when getting content provider "
9727                    + name;
9728            Slog.w(TAG, msg);
9729            throw new SecurityException(msg);
9730        }
9731        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9732        // with cross-user grant.
9733        return getContentProviderImpl(caller, name, null, stable, userId);
9734    }
9735
9736    public ContentProviderHolder getContentProviderExternal(
9737            String name, int userId, IBinder token) {
9738        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9739            "Do not have permission in call getContentProviderExternal()");
9740        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9741                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9742        return getContentProviderExternalUnchecked(name, token, userId);
9743    }
9744
9745    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9746            IBinder token, int userId) {
9747        return getContentProviderImpl(null, name, token, true, userId);
9748    }
9749
9750    /**
9751     * Drop a content provider from a ProcessRecord's bookkeeping
9752     */
9753    public void removeContentProvider(IBinder connection, boolean stable) {
9754        enforceNotIsolatedCaller("removeContentProvider");
9755        long ident = Binder.clearCallingIdentity();
9756        try {
9757            synchronized (this) {
9758                ContentProviderConnection conn;
9759                try {
9760                    conn = (ContentProviderConnection)connection;
9761                } catch (ClassCastException e) {
9762                    String msg ="removeContentProvider: " + connection
9763                            + " not a ContentProviderConnection";
9764                    Slog.w(TAG, msg);
9765                    throw new IllegalArgumentException(msg);
9766                }
9767                if (conn == null) {
9768                    throw new NullPointerException("connection is null");
9769                }
9770                if (decProviderCountLocked(conn, null, null, stable)) {
9771                    updateOomAdjLocked();
9772                }
9773            }
9774        } finally {
9775            Binder.restoreCallingIdentity(ident);
9776        }
9777    }
9778
9779    public void removeContentProviderExternal(String name, IBinder token) {
9780        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9781            "Do not have permission in call removeContentProviderExternal()");
9782        int userId = UserHandle.getCallingUserId();
9783        long ident = Binder.clearCallingIdentity();
9784        try {
9785            removeContentProviderExternalUnchecked(name, token, userId);
9786        } finally {
9787            Binder.restoreCallingIdentity(ident);
9788        }
9789    }
9790
9791    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9792        synchronized (this) {
9793            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9794            if(cpr == null) {
9795                //remove from mProvidersByClass
9796                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
9797                return;
9798            }
9799
9800            //update content provider record entry info
9801            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9802            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9803            if (localCpr.hasExternalProcessHandles()) {
9804                if (localCpr.removeExternalProcessHandleLocked(token)) {
9805                    updateOomAdjLocked();
9806                } else {
9807                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9808                            + " with no external reference for token: "
9809                            + token + ".");
9810                }
9811            } else {
9812                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9813                        + " with no external references.");
9814            }
9815        }
9816    }
9817
9818    public final void publishContentProviders(IApplicationThread caller,
9819            List<ContentProviderHolder> providers) {
9820        if (providers == null) {
9821            return;
9822        }
9823
9824        enforceNotIsolatedCaller("publishContentProviders");
9825        synchronized (this) {
9826            final ProcessRecord r = getRecordForAppLocked(caller);
9827            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9828            if (r == null) {
9829                throw new SecurityException(
9830                        "Unable to find app for caller " + caller
9831                      + " (pid=" + Binder.getCallingPid()
9832                      + ") when publishing content providers");
9833            }
9834
9835            final long origId = Binder.clearCallingIdentity();
9836
9837            final int N = providers.size();
9838            for (int i=0; i<N; i++) {
9839                ContentProviderHolder src = providers.get(i);
9840                if (src == null || src.info == null || src.provider == null) {
9841                    continue;
9842                }
9843                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9844                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9845                if (dst != null) {
9846                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9847                    mProviderMap.putProviderByClass(comp, dst);
9848                    String names[] = dst.info.authority.split(";");
9849                    for (int j = 0; j < names.length; j++) {
9850                        mProviderMap.putProviderByName(names[j], dst);
9851                    }
9852
9853                    int NL = mLaunchingProviders.size();
9854                    int j;
9855                    for (j=0; j<NL; j++) {
9856                        if (mLaunchingProviders.get(j) == dst) {
9857                            mLaunchingProviders.remove(j);
9858                            j--;
9859                            NL--;
9860                        }
9861                    }
9862                    synchronized (dst) {
9863                        dst.provider = src.provider;
9864                        dst.proc = r;
9865                        dst.notifyAll();
9866                    }
9867                    updateOomAdjLocked(r);
9868                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
9869                            src.info.authority);
9870                }
9871            }
9872
9873            Binder.restoreCallingIdentity(origId);
9874        }
9875    }
9876
9877    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9878        ContentProviderConnection conn;
9879        try {
9880            conn = (ContentProviderConnection)connection;
9881        } catch (ClassCastException e) {
9882            String msg ="refContentProvider: " + connection
9883                    + " not a ContentProviderConnection";
9884            Slog.w(TAG, msg);
9885            throw new IllegalArgumentException(msg);
9886        }
9887        if (conn == null) {
9888            throw new NullPointerException("connection is null");
9889        }
9890
9891        synchronized (this) {
9892            if (stable > 0) {
9893                conn.numStableIncs += stable;
9894            }
9895            stable = conn.stableCount + stable;
9896            if (stable < 0) {
9897                throw new IllegalStateException("stableCount < 0: " + stable);
9898            }
9899
9900            if (unstable > 0) {
9901                conn.numUnstableIncs += unstable;
9902            }
9903            unstable = conn.unstableCount + unstable;
9904            if (unstable < 0) {
9905                throw new IllegalStateException("unstableCount < 0: " + unstable);
9906            }
9907
9908            if ((stable+unstable) <= 0) {
9909                throw new IllegalStateException("ref counts can't go to zero here: stable="
9910                        + stable + " unstable=" + unstable);
9911            }
9912            conn.stableCount = stable;
9913            conn.unstableCount = unstable;
9914            return !conn.dead;
9915        }
9916    }
9917
9918    public void unstableProviderDied(IBinder connection) {
9919        ContentProviderConnection conn;
9920        try {
9921            conn = (ContentProviderConnection)connection;
9922        } catch (ClassCastException e) {
9923            String msg ="refContentProvider: " + connection
9924                    + " not a ContentProviderConnection";
9925            Slog.w(TAG, msg);
9926            throw new IllegalArgumentException(msg);
9927        }
9928        if (conn == null) {
9929            throw new NullPointerException("connection is null");
9930        }
9931
9932        // Safely retrieve the content provider associated with the connection.
9933        IContentProvider provider;
9934        synchronized (this) {
9935            provider = conn.provider.provider;
9936        }
9937
9938        if (provider == null) {
9939            // Um, yeah, we're way ahead of you.
9940            return;
9941        }
9942
9943        // Make sure the caller is being honest with us.
9944        if (provider.asBinder().pingBinder()) {
9945            // Er, no, still looks good to us.
9946            synchronized (this) {
9947                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9948                        + " says " + conn + " died, but we don't agree");
9949                return;
9950            }
9951        }
9952
9953        // Well look at that!  It's dead!
9954        synchronized (this) {
9955            if (conn.provider.provider != provider) {
9956                // But something changed...  good enough.
9957                return;
9958            }
9959
9960            ProcessRecord proc = conn.provider.proc;
9961            if (proc == null || proc.thread == null) {
9962                // Seems like the process is already cleaned up.
9963                return;
9964            }
9965
9966            // As far as we're concerned, this is just like receiving a
9967            // death notification...  just a bit prematurely.
9968            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9969                    + ") early provider death");
9970            final long ident = Binder.clearCallingIdentity();
9971            try {
9972                appDiedLocked(proc);
9973            } finally {
9974                Binder.restoreCallingIdentity(ident);
9975            }
9976        }
9977    }
9978
9979    @Override
9980    public void appNotRespondingViaProvider(IBinder connection) {
9981        enforceCallingPermission(
9982                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9983
9984        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9985        if (conn == null) {
9986            Slog.w(TAG, "ContentProviderConnection is null");
9987            return;
9988        }
9989
9990        final ProcessRecord host = conn.provider.proc;
9991        if (host == null) {
9992            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9993            return;
9994        }
9995
9996        final long token = Binder.clearCallingIdentity();
9997        try {
9998            appNotResponding(host, null, null, false, "ContentProvider not responding");
9999        } finally {
10000            Binder.restoreCallingIdentity(token);
10001        }
10002    }
10003
10004    public final void installSystemProviders() {
10005        List<ProviderInfo> providers;
10006        synchronized (this) {
10007            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10008            providers = generateApplicationProvidersLocked(app);
10009            if (providers != null) {
10010                for (int i=providers.size()-1; i>=0; i--) {
10011                    ProviderInfo pi = (ProviderInfo)providers.get(i);
10012                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10013                        Slog.w(TAG, "Not installing system proc provider " + pi.name
10014                                + ": not system .apk");
10015                        providers.remove(i);
10016                    }
10017                }
10018            }
10019        }
10020        if (providers != null) {
10021            mSystemThread.installSystemProviders(providers);
10022        }
10023
10024        mCoreSettingsObserver = new CoreSettingsObserver(this);
10025
10026        //mUsageStatsService.monitorPackages();
10027    }
10028
10029    /**
10030     * Allows apps to retrieve the MIME type of a URI.
10031     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
10032     * users, then it does not need permission to access the ContentProvider.
10033     * Either, it needs cross-user uri grants.
10034     *
10035     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
10036     *
10037     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
10038     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
10039     */
10040    public String getProviderMimeType(Uri uri, int userId) {
10041        enforceNotIsolatedCaller("getProviderMimeType");
10042        final String name = uri.getAuthority();
10043        int callingUid = Binder.getCallingUid();
10044        int callingPid = Binder.getCallingPid();
10045        long ident = 0;
10046        boolean clearedIdentity = false;
10047        userId = unsafeConvertIncomingUser(userId);
10048        if (canClearIdentity(callingPid, callingUid, userId)) {
10049            clearedIdentity = true;
10050            ident = Binder.clearCallingIdentity();
10051        }
10052        ContentProviderHolder holder = null;
10053        try {
10054            holder = getContentProviderExternalUnchecked(name, null, userId);
10055            if (holder != null) {
10056                return holder.provider.getType(uri);
10057            }
10058        } catch (RemoteException e) {
10059            Log.w(TAG, "Content provider dead retrieving " + uri, e);
10060            return null;
10061        } finally {
10062            // We need to clear the identity to call removeContentProviderExternalUnchecked
10063            if (!clearedIdentity) {
10064                ident = Binder.clearCallingIdentity();
10065            }
10066            try {
10067                if (holder != null) {
10068                    removeContentProviderExternalUnchecked(name, null, userId);
10069                }
10070            } finally {
10071                Binder.restoreCallingIdentity(ident);
10072            }
10073        }
10074
10075        return null;
10076    }
10077
10078    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
10079        if (UserHandle.getUserId(callingUid) == userId) {
10080            return true;
10081        }
10082        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
10083                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
10084                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
10085                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
10086                return true;
10087        }
10088        return false;
10089    }
10090
10091    // =========================================================
10092    // GLOBAL MANAGEMENT
10093    // =========================================================
10094
10095    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
10096            boolean isolated, int isolatedUid) {
10097        String proc = customProcess != null ? customProcess : info.processName;
10098        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10099        final int userId = UserHandle.getUserId(info.uid);
10100        int uid = info.uid;
10101        if (isolated) {
10102            if (isolatedUid == 0) {
10103                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
10104                while (true) {
10105                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
10106                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
10107                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
10108                    }
10109                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
10110                    mNextIsolatedProcessUid++;
10111                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
10112                        // No process for this uid, use it.
10113                        break;
10114                    }
10115                    stepsLeft--;
10116                    if (stepsLeft <= 0) {
10117                        return null;
10118                    }
10119                }
10120            } else {
10121                // Special case for startIsolatedProcess (internal only), where
10122                // the uid of the isolated process is specified by the caller.
10123                uid = isolatedUid;
10124            }
10125        }
10126        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
10127        if (!mBooted && !mBooting
10128                && userId == UserHandle.USER_OWNER
10129                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10130            r.persistent = true;
10131        }
10132        addProcessNameLocked(r);
10133        return r;
10134    }
10135
10136    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
10137            String abiOverride) {
10138        ProcessRecord app;
10139        if (!isolated) {
10140            app = getProcessRecordLocked(info.processName, info.uid, true);
10141        } else {
10142            app = null;
10143        }
10144
10145        if (app == null) {
10146            app = newProcessRecordLocked(info, null, isolated, 0);
10147            updateLruProcessLocked(app, false, null);
10148            updateOomAdjLocked();
10149        }
10150
10151        // This package really, really can not be stopped.
10152        try {
10153            AppGlobals.getPackageManager().setPackageStoppedState(
10154                    info.packageName, false, UserHandle.getUserId(app.uid));
10155        } catch (RemoteException e) {
10156        } catch (IllegalArgumentException e) {
10157            Slog.w(TAG, "Failed trying to unstop package "
10158                    + info.packageName + ": " + e);
10159        }
10160
10161        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10162            app.persistent = true;
10163            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10164        }
10165        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10166            mPersistentStartingProcesses.add(app);
10167            startProcessLocked(app, "added application", app.processName, abiOverride,
10168                    null /* entryPoint */, null /* entryPointArgs */);
10169        }
10170
10171        return app;
10172    }
10173
10174    public void unhandledBack() {
10175        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10176                "unhandledBack()");
10177
10178        synchronized(this) {
10179            final long origId = Binder.clearCallingIdentity();
10180            try {
10181                getFocusedStack().unhandledBackLocked();
10182            } finally {
10183                Binder.restoreCallingIdentity(origId);
10184            }
10185        }
10186    }
10187
10188    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10189        enforceNotIsolatedCaller("openContentUri");
10190        final int userId = UserHandle.getCallingUserId();
10191        String name = uri.getAuthority();
10192        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10193        ParcelFileDescriptor pfd = null;
10194        if (cph != null) {
10195            // We record the binder invoker's uid in thread-local storage before
10196            // going to the content provider to open the file.  Later, in the code
10197            // that handles all permissions checks, we look for this uid and use
10198            // that rather than the Activity Manager's own uid.  The effect is that
10199            // we do the check against the caller's permissions even though it looks
10200            // to the content provider like the Activity Manager itself is making
10201            // the request.
10202            Binder token = new Binder();
10203            sCallerIdentity.set(new Identity(
10204                    token, Binder.getCallingPid(), Binder.getCallingUid()));
10205            try {
10206                pfd = cph.provider.openFile(null, uri, "r", null, token);
10207            } catch (FileNotFoundException e) {
10208                // do nothing; pfd will be returned null
10209            } finally {
10210                // Ensure that whatever happens, we clean up the identity state
10211                sCallerIdentity.remove();
10212                // Ensure we're done with the provider.
10213                removeContentProviderExternalUnchecked(name, null, userId);
10214            }
10215        } else {
10216            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10217        }
10218        return pfd;
10219    }
10220
10221    // Actually is sleeping or shutting down or whatever else in the future
10222    // is an inactive state.
10223    public boolean isSleepingOrShuttingDown() {
10224        return isSleeping() || mShuttingDown;
10225    }
10226
10227    public boolean isSleeping() {
10228        return mSleeping;
10229    }
10230
10231    void onWakefulnessChanged(int wakefulness) {
10232        synchronized(this) {
10233            mWakefulness = wakefulness;
10234            updateSleepIfNeededLocked();
10235        }
10236    }
10237
10238    void finishRunningVoiceLocked() {
10239        if (mRunningVoice != null) {
10240            mRunningVoice = null;
10241            mVoiceWakeLock.release();
10242            updateSleepIfNeededLocked();
10243        }
10244    }
10245
10246    void startTimeTrackingFocusedActivityLocked() {
10247        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
10248            mCurAppTimeTracker.start(mFocusedActivity.packageName);
10249        }
10250    }
10251
10252    void updateSleepIfNeededLocked() {
10253        if (mSleeping && !shouldSleepLocked()) {
10254            mSleeping = false;
10255            startTimeTrackingFocusedActivityLocked();
10256            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
10257            mStackSupervisor.comeOutOfSleepIfNeededLocked();
10258            updateOomAdjLocked();
10259        } else if (!mSleeping && shouldSleepLocked()) {
10260            mSleeping = true;
10261            if (mCurAppTimeTracker != null) {
10262                mCurAppTimeTracker.stop();
10263            }
10264            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
10265            mStackSupervisor.goingToSleepLocked();
10266            updateOomAdjLocked();
10267
10268            // Initialize the wake times of all processes.
10269            checkExcessivePowerUsageLocked(false);
10270            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10271            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10272            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10273        }
10274    }
10275
10276    private boolean shouldSleepLocked() {
10277        // Resume applications while running a voice interactor.
10278        if (mRunningVoice != null) {
10279            return false;
10280        }
10281
10282        // TODO: Transform the lock screen state into a sleep token instead.
10283        switch (mWakefulness) {
10284            case PowerManagerInternal.WAKEFULNESS_AWAKE:
10285            case PowerManagerInternal.WAKEFULNESS_DREAMING:
10286            case PowerManagerInternal.WAKEFULNESS_DOZING:
10287                // Pause applications whenever the lock screen is shown or any sleep
10288                // tokens have been acquired.
10289                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
10290            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10291            default:
10292                // If we're asleep then pause applications unconditionally.
10293                return true;
10294        }
10295    }
10296
10297    /** Pokes the task persister. */
10298    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10299        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10300            // Never persist the home stack.
10301            return;
10302        }
10303        mTaskPersister.wakeup(task, flush);
10304    }
10305
10306    /** Notifies all listeners when the task stack has changed. */
10307    void notifyTaskStackChangedLocked() {
10308        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10309        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10310        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10311    }
10312
10313    @Override
10314    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
10315        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
10316    }
10317
10318    @Override
10319    public boolean shutdown(int timeout) {
10320        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10321                != PackageManager.PERMISSION_GRANTED) {
10322            throw new SecurityException("Requires permission "
10323                    + android.Manifest.permission.SHUTDOWN);
10324        }
10325
10326        boolean timedout = false;
10327
10328        synchronized(this) {
10329            mShuttingDown = true;
10330            updateEventDispatchingLocked();
10331            timedout = mStackSupervisor.shutdownLocked(timeout);
10332        }
10333
10334        mAppOpsService.shutdown();
10335        if (mUsageStatsService != null) {
10336            mUsageStatsService.prepareShutdown();
10337        }
10338        mBatteryStatsService.shutdown();
10339        synchronized (this) {
10340            mProcessStats.shutdownLocked();
10341            notifyTaskPersisterLocked(null, true);
10342        }
10343
10344        return timedout;
10345    }
10346
10347    public final void activitySlept(IBinder token) {
10348        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
10349
10350        final long origId = Binder.clearCallingIdentity();
10351
10352        synchronized (this) {
10353            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10354            if (r != null) {
10355                mStackSupervisor.activitySleptLocked(r);
10356            }
10357        }
10358
10359        Binder.restoreCallingIdentity(origId);
10360    }
10361
10362    private String lockScreenShownToString() {
10363        switch (mLockScreenShown) {
10364            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10365            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10366            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10367            default: return "Unknown=" + mLockScreenShown;
10368        }
10369    }
10370
10371    void logLockScreen(String msg) {
10372        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
10373                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10374                + PowerManagerInternal.wakefulnessToString(mWakefulness)
10375                + " mSleeping=" + mSleeping);
10376    }
10377
10378    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
10379        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
10380        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
10381            boolean wasRunningVoice = mRunningVoice != null;
10382            mRunningVoice = session;
10383            if (!wasRunningVoice) {
10384                mVoiceWakeLock.acquire();
10385                updateSleepIfNeededLocked();
10386            }
10387        }
10388    }
10389
10390    private void updateEventDispatchingLocked() {
10391        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10392    }
10393
10394    public void setLockScreenShown(boolean shown) {
10395        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10396                != PackageManager.PERMISSION_GRANTED) {
10397            throw new SecurityException("Requires permission "
10398                    + android.Manifest.permission.DEVICE_POWER);
10399        }
10400
10401        synchronized(this) {
10402            long ident = Binder.clearCallingIdentity();
10403            try {
10404                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10405                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10406                updateSleepIfNeededLocked();
10407            } finally {
10408                Binder.restoreCallingIdentity(ident);
10409            }
10410        }
10411    }
10412
10413    @Override
10414    public void stopAppSwitches() {
10415        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10416                != PackageManager.PERMISSION_GRANTED) {
10417            throw new SecurityException("Requires permission "
10418                    + android.Manifest.permission.STOP_APP_SWITCHES);
10419        }
10420
10421        synchronized(this) {
10422            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10423                    + APP_SWITCH_DELAY_TIME;
10424            mDidAppSwitch = false;
10425            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10426            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10427            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10428        }
10429    }
10430
10431    public void resumeAppSwitches() {
10432        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10433                != PackageManager.PERMISSION_GRANTED) {
10434            throw new SecurityException("Requires permission "
10435                    + android.Manifest.permission.STOP_APP_SWITCHES);
10436        }
10437
10438        synchronized(this) {
10439            // Note that we don't execute any pending app switches... we will
10440            // let those wait until either the timeout, or the next start
10441            // activity request.
10442            mAppSwitchesAllowedTime = 0;
10443        }
10444    }
10445
10446    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10447            int callingPid, int callingUid, String name) {
10448        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10449            return true;
10450        }
10451
10452        int perm = checkComponentPermission(
10453                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10454                sourceUid, -1, true);
10455        if (perm == PackageManager.PERMISSION_GRANTED) {
10456            return true;
10457        }
10458
10459        // If the actual IPC caller is different from the logical source, then
10460        // also see if they are allowed to control app switches.
10461        if (callingUid != -1 && callingUid != sourceUid) {
10462            perm = checkComponentPermission(
10463                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10464                    callingUid, -1, true);
10465            if (perm == PackageManager.PERMISSION_GRANTED) {
10466                return true;
10467            }
10468        }
10469
10470        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10471        return false;
10472    }
10473
10474    public void setDebugApp(String packageName, boolean waitForDebugger,
10475            boolean persistent) {
10476        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10477                "setDebugApp()");
10478
10479        long ident = Binder.clearCallingIdentity();
10480        try {
10481            // Note that this is not really thread safe if there are multiple
10482            // callers into it at the same time, but that's not a situation we
10483            // care about.
10484            if (persistent) {
10485                final ContentResolver resolver = mContext.getContentResolver();
10486                Settings.Global.putString(
10487                    resolver, Settings.Global.DEBUG_APP,
10488                    packageName);
10489                Settings.Global.putInt(
10490                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10491                    waitForDebugger ? 1 : 0);
10492            }
10493
10494            synchronized (this) {
10495                if (!persistent) {
10496                    mOrigDebugApp = mDebugApp;
10497                    mOrigWaitForDebugger = mWaitForDebugger;
10498                }
10499                mDebugApp = packageName;
10500                mWaitForDebugger = waitForDebugger;
10501                mDebugTransient = !persistent;
10502                if (packageName != null) {
10503                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10504                            false, UserHandle.USER_ALL, "set debug app");
10505                }
10506            }
10507        } finally {
10508            Binder.restoreCallingIdentity(ident);
10509        }
10510    }
10511
10512    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10513        synchronized (this) {
10514            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10515            if (!isDebuggable) {
10516                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10517                    throw new SecurityException("Process not debuggable: " + app.packageName);
10518                }
10519            }
10520
10521            mOpenGlTraceApp = processName;
10522        }
10523    }
10524
10525    void setTrackAllocationApp(ApplicationInfo app, String processName) {
10526        synchronized (this) {
10527            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10528            if (!isDebuggable) {
10529                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10530                    throw new SecurityException("Process not debuggable: " + app.packageName);
10531                }
10532            }
10533
10534            mTrackAllocationApp = processName;
10535        }
10536    }
10537
10538    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10539        synchronized (this) {
10540            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10541            if (!isDebuggable) {
10542                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10543                    throw new SecurityException("Process not debuggable: " + app.packageName);
10544                }
10545            }
10546            mProfileApp = processName;
10547            mProfileFile = profilerInfo.profileFile;
10548            if (mProfileFd != null) {
10549                try {
10550                    mProfileFd.close();
10551                } catch (IOException e) {
10552                }
10553                mProfileFd = null;
10554            }
10555            mProfileFd = profilerInfo.profileFd;
10556            mSamplingInterval = profilerInfo.samplingInterval;
10557            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10558            mProfileType = 0;
10559        }
10560    }
10561
10562    @Override
10563    public void setAlwaysFinish(boolean enabled) {
10564        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10565                "setAlwaysFinish()");
10566
10567        Settings.Global.putInt(
10568                mContext.getContentResolver(),
10569                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10570
10571        synchronized (this) {
10572            mAlwaysFinishActivities = enabled;
10573        }
10574    }
10575
10576    @Override
10577    public void setActivityController(IActivityController controller) {
10578        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10579                "setActivityController()");
10580        synchronized (this) {
10581            mController = controller;
10582            Watchdog.getInstance().setActivityController(controller);
10583        }
10584    }
10585
10586    @Override
10587    public void setUserIsMonkey(boolean userIsMonkey) {
10588        synchronized (this) {
10589            synchronized (mPidsSelfLocked) {
10590                final int callingPid = Binder.getCallingPid();
10591                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10592                if (precessRecord == null) {
10593                    throw new SecurityException("Unknown process: " + callingPid);
10594                }
10595                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10596                    throw new SecurityException("Only an instrumentation process "
10597                            + "with a UiAutomation can call setUserIsMonkey");
10598                }
10599            }
10600            mUserIsMonkey = userIsMonkey;
10601        }
10602    }
10603
10604    @Override
10605    public boolean isUserAMonkey() {
10606        synchronized (this) {
10607            // If there is a controller also implies the user is a monkey.
10608            return (mUserIsMonkey || mController != null);
10609        }
10610    }
10611
10612    public void requestBugReport() {
10613        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10614        SystemProperties.set("ctl.start", "bugreport");
10615    }
10616
10617    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10618        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10619    }
10620
10621    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10622        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10623            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10624        }
10625        return KEY_DISPATCHING_TIMEOUT;
10626    }
10627
10628    @Override
10629    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10630        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10631                != PackageManager.PERMISSION_GRANTED) {
10632            throw new SecurityException("Requires permission "
10633                    + android.Manifest.permission.FILTER_EVENTS);
10634        }
10635        ProcessRecord proc;
10636        long timeout;
10637        synchronized (this) {
10638            synchronized (mPidsSelfLocked) {
10639                proc = mPidsSelfLocked.get(pid);
10640            }
10641            timeout = getInputDispatchingTimeoutLocked(proc);
10642        }
10643
10644        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10645            return -1;
10646        }
10647
10648        return timeout;
10649    }
10650
10651    /**
10652     * Handle input dispatching timeouts.
10653     * Returns whether input dispatching should be aborted or not.
10654     */
10655    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10656            final ActivityRecord activity, final ActivityRecord parent,
10657            final boolean aboveSystem, String reason) {
10658        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10659                != PackageManager.PERMISSION_GRANTED) {
10660            throw new SecurityException("Requires permission "
10661                    + android.Manifest.permission.FILTER_EVENTS);
10662        }
10663
10664        final String annotation;
10665        if (reason == null) {
10666            annotation = "Input dispatching timed out";
10667        } else {
10668            annotation = "Input dispatching timed out (" + reason + ")";
10669        }
10670
10671        if (proc != null) {
10672            synchronized (this) {
10673                if (proc.debugging) {
10674                    return false;
10675                }
10676
10677                if (mDidDexOpt) {
10678                    // Give more time since we were dexopting.
10679                    mDidDexOpt = false;
10680                    return false;
10681                }
10682
10683                if (proc.instrumentationClass != null) {
10684                    Bundle info = new Bundle();
10685                    info.putString("shortMsg", "keyDispatchingTimedOut");
10686                    info.putString("longMsg", annotation);
10687                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10688                    return true;
10689                }
10690            }
10691            mHandler.post(new Runnable() {
10692                @Override
10693                public void run() {
10694                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10695                }
10696            });
10697        }
10698
10699        return true;
10700    }
10701
10702    @Override
10703    public Bundle getAssistContextExtras(int requestType) {
10704        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
10705                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
10706        if (pae == null) {
10707            return null;
10708        }
10709        synchronized (pae) {
10710            while (!pae.haveResult) {
10711                try {
10712                    pae.wait();
10713                } catch (InterruptedException e) {
10714                }
10715            }
10716        }
10717        synchronized (this) {
10718            buildAssistBundleLocked(pae, pae.result);
10719            mPendingAssistExtras.remove(pae);
10720            mHandler.removeCallbacks(pae);
10721        }
10722        return pae.extras;
10723    }
10724
10725    @Override
10726    public boolean isScreenCaptureAllowedOnCurrentActivity() {
10727        int userId = mCurrentUserId;
10728        synchronized (this) {
10729            ActivityRecord activity = getFocusedStack().topActivity();
10730            if (activity == null) {
10731                return false;
10732            }
10733            userId = activity.userId;
10734        }
10735        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
10736                Context.DEVICE_POLICY_SERVICE);
10737        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
10738    }
10739
10740    @Override
10741    public void requestAssistContextExtras(int requestType, IResultReceiver receiver) {
10742        enqueueAssistContext(requestType, null, null, receiver, UserHandle.getCallingUserId(),
10743                null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT);
10744    }
10745
10746    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10747            IResultReceiver receiver, int userHandle, Bundle args, long timeout) {
10748        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10749                "enqueueAssistContext()");
10750        synchronized (this) {
10751            ActivityRecord activity = getFocusedStack().topActivity();
10752            if (activity == null) {
10753                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
10754                return null;
10755            }
10756            if (activity.app == null || activity.app.thread == null) {
10757                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10758                return null;
10759            }
10760            if (activity.app.pid == Binder.getCallingPid()) {
10761                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10762                return null;
10763            }
10764            PendingAssistExtras pae;
10765            Bundle extras = new Bundle();
10766            if (args != null) {
10767                extras.putAll(args);
10768            }
10769            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10770            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
10771            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
10772            try {
10773                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10774                        requestType);
10775                mPendingAssistExtras.add(pae);
10776                mHandler.postDelayed(pae, timeout);
10777            } catch (RemoteException e) {
10778                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10779                return null;
10780            }
10781            return pae;
10782        }
10783    }
10784
10785    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
10786        IResultReceiver receiver;
10787        synchronized (this) {
10788            mPendingAssistExtras.remove(pae);
10789            receiver = pae.receiver;
10790        }
10791        if (receiver != null) {
10792            // Caller wants result sent back to them.
10793            try {
10794                pae.receiver.send(0, null);
10795            } catch (RemoteException e) {
10796            }
10797        }
10798    }
10799
10800    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
10801        if (result != null) {
10802            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
10803        }
10804        if (pae.hint != null) {
10805            pae.extras.putBoolean(pae.hint, true);
10806        }
10807    }
10808
10809    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
10810            AssistContent content, Uri referrer) {
10811        PendingAssistExtras pae = (PendingAssistExtras)token;
10812        synchronized (pae) {
10813            pae.result = extras;
10814            pae.structure = structure;
10815            pae.content = content;
10816            if (referrer != null) {
10817                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
10818            }
10819            pae.haveResult = true;
10820            pae.notifyAll();
10821            if (pae.intent == null && pae.receiver == null) {
10822                // Caller is just waiting for the result.
10823                return;
10824            }
10825        }
10826
10827        // We are now ready to launch the assist activity.
10828        synchronized (this) {
10829            buildAssistBundleLocked(pae, extras);
10830            boolean exists = mPendingAssistExtras.remove(pae);
10831            mHandler.removeCallbacks(pae);
10832            if (!exists) {
10833                // Timed out.
10834                return;
10835            }
10836            if (pae.receiver != null) {
10837                // Caller wants result sent back to them.
10838                Bundle topBundle = new Bundle();
10839                topBundle.putBundle("data", pae.extras);
10840                topBundle.putParcelable("structure", pae.structure);
10841                topBundle.putParcelable("content", pae.content);
10842                try {
10843                    pae.receiver.send(0, topBundle);
10844                } catch (RemoteException e) {
10845                }
10846                return;
10847            }
10848        }
10849
10850        long ident = Binder.clearCallingIdentity();
10851        try {
10852            pae.intent.replaceExtras(pae.extras);
10853            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10854                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
10855                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10856            closeSystemDialogs("assist");
10857            try {
10858                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10859            } catch (ActivityNotFoundException e) {
10860                Slog.w(TAG, "No activity to handle assist action.", e);
10861            }
10862        } finally {
10863            Binder.restoreCallingIdentity(ident);
10864        }
10865    }
10866
10867    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
10868            Bundle args) {
10869        return enqueueAssistContext(requestType, intent, hint, null, userHandle, args,
10870                PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
10871    }
10872
10873    public void registerProcessObserver(IProcessObserver observer) {
10874        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10875                "registerProcessObserver()");
10876        synchronized (this) {
10877            mProcessObservers.register(observer);
10878        }
10879    }
10880
10881    @Override
10882    public void unregisterProcessObserver(IProcessObserver observer) {
10883        synchronized (this) {
10884            mProcessObservers.unregister(observer);
10885        }
10886    }
10887
10888    public void registerUidObserver(IUidObserver observer) {
10889        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10890                "registerUidObserver()");
10891        synchronized (this) {
10892            mUidObservers.register(observer);
10893        }
10894    }
10895
10896    @Override
10897    public void unregisterUidObserver(IUidObserver observer) {
10898        synchronized (this) {
10899            mUidObservers.unregister(observer);
10900        }
10901    }
10902
10903    @Override
10904    public boolean convertFromTranslucent(IBinder token) {
10905        final long origId = Binder.clearCallingIdentity();
10906        try {
10907            synchronized (this) {
10908                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10909                if (r == null) {
10910                    return false;
10911                }
10912                final boolean translucentChanged = r.changeWindowTranslucency(true);
10913                if (translucentChanged) {
10914                    r.task.stack.releaseBackgroundResources(r);
10915                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10916                }
10917                mWindowManager.setAppFullscreen(token, true);
10918                return translucentChanged;
10919            }
10920        } finally {
10921            Binder.restoreCallingIdentity(origId);
10922        }
10923    }
10924
10925    @Override
10926    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10927        final long origId = Binder.clearCallingIdentity();
10928        try {
10929            synchronized (this) {
10930                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10931                if (r == null) {
10932                    return false;
10933                }
10934                int index = r.task.mActivities.lastIndexOf(r);
10935                if (index > 0) {
10936                    ActivityRecord under = r.task.mActivities.get(index - 1);
10937                    under.returningOptions = options;
10938                }
10939                final boolean translucentChanged = r.changeWindowTranslucency(false);
10940                if (translucentChanged) {
10941                    r.task.stack.convertActivityToTranslucent(r);
10942                }
10943                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10944                mWindowManager.setAppFullscreen(token, false);
10945                return translucentChanged;
10946            }
10947        } finally {
10948            Binder.restoreCallingIdentity(origId);
10949        }
10950    }
10951
10952    @Override
10953    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10954        final long origId = Binder.clearCallingIdentity();
10955        try {
10956            synchronized (this) {
10957                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10958                if (r != null) {
10959                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10960                }
10961            }
10962            return false;
10963        } finally {
10964            Binder.restoreCallingIdentity(origId);
10965        }
10966    }
10967
10968    @Override
10969    public boolean isBackgroundVisibleBehind(IBinder token) {
10970        final long origId = Binder.clearCallingIdentity();
10971        try {
10972            synchronized (this) {
10973                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10974                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10975                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
10976                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10977                return visible;
10978            }
10979        } finally {
10980            Binder.restoreCallingIdentity(origId);
10981        }
10982    }
10983
10984    @Override
10985    public ActivityOptions getActivityOptions(IBinder token) {
10986        final long origId = Binder.clearCallingIdentity();
10987        try {
10988            synchronized (this) {
10989                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10990                if (r != null) {
10991                    final ActivityOptions activityOptions = r.pendingOptions;
10992                    r.pendingOptions = null;
10993                    return activityOptions;
10994                }
10995                return null;
10996            }
10997        } finally {
10998            Binder.restoreCallingIdentity(origId);
10999        }
11000    }
11001
11002    @Override
11003    public void setImmersive(IBinder token, boolean immersive) {
11004        synchronized(this) {
11005            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11006            if (r == null) {
11007                throw new IllegalArgumentException();
11008            }
11009            r.immersive = immersive;
11010
11011            // update associated state if we're frontmost
11012            if (r == mFocusedActivity) {
11013                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
11014                applyUpdateLockStateLocked(r);
11015            }
11016        }
11017    }
11018
11019    @Override
11020    public boolean isImmersive(IBinder token) {
11021        synchronized (this) {
11022            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11023            if (r == null) {
11024                throw new IllegalArgumentException();
11025            }
11026            return r.immersive;
11027        }
11028    }
11029
11030    public boolean isTopActivityImmersive() {
11031        enforceNotIsolatedCaller("startActivity");
11032        synchronized (this) {
11033            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
11034            return (r != null) ? r.immersive : false;
11035        }
11036    }
11037
11038    @Override
11039    public boolean isTopOfTask(IBinder token) {
11040        synchronized (this) {
11041            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11042            if (r == null) {
11043                throw new IllegalArgumentException();
11044            }
11045            return r.task.getTopActivity() == r;
11046        }
11047    }
11048
11049    public final void enterSafeMode() {
11050        synchronized(this) {
11051            // It only makes sense to do this before the system is ready
11052            // and started launching other packages.
11053            if (!mSystemReady) {
11054                try {
11055                    AppGlobals.getPackageManager().enterSafeMode();
11056                } catch (RemoteException e) {
11057                }
11058            }
11059
11060            mSafeMode = true;
11061        }
11062    }
11063
11064    public final void showSafeModeOverlay() {
11065        View v = LayoutInflater.from(mContext).inflate(
11066                com.android.internal.R.layout.safe_mode, null);
11067        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
11068        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
11069        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
11070        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
11071        lp.gravity = Gravity.BOTTOM | Gravity.START;
11072        lp.format = v.getBackground().getOpacity();
11073        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
11074                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
11075        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
11076        ((WindowManager)mContext.getSystemService(
11077                Context.WINDOW_SERVICE)).addView(v, lp);
11078    }
11079
11080    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
11081        if (!(sender instanceof PendingIntentRecord)) {
11082            return;
11083        }
11084        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11085        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11086        synchronized (stats) {
11087            if (mBatteryStatsService.isOnBattery()) {
11088                mBatteryStatsService.enforceCallingPermission();
11089                int MY_UID = Binder.getCallingUid();
11090                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11091                BatteryStatsImpl.Uid.Pkg pkg =
11092                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
11093                            sourcePkg != null ? sourcePkg : rec.key.packageName);
11094                pkg.noteWakeupAlarmLocked(tag);
11095            }
11096        }
11097    }
11098
11099    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
11100        if (!(sender instanceof PendingIntentRecord)) {
11101            return;
11102        }
11103        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11104        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11105        synchronized (stats) {
11106            mBatteryStatsService.enforceCallingPermission();
11107            int MY_UID = Binder.getCallingUid();
11108            int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11109            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
11110        }
11111    }
11112
11113    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
11114        if (!(sender instanceof PendingIntentRecord)) {
11115            return;
11116        }
11117        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11118        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11119        synchronized (stats) {
11120            mBatteryStatsService.enforceCallingPermission();
11121            int MY_UID = Binder.getCallingUid();
11122            int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11123            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
11124        }
11125    }
11126
11127    public boolean killPids(int[] pids, String pReason, boolean secure) {
11128        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11129            throw new SecurityException("killPids only available to the system");
11130        }
11131        String reason = (pReason == null) ? "Unknown" : pReason;
11132        // XXX Note: don't acquire main activity lock here, because the window
11133        // manager calls in with its locks held.
11134
11135        boolean killed = false;
11136        synchronized (mPidsSelfLocked) {
11137            int[] types = new int[pids.length];
11138            int worstType = 0;
11139            for (int i=0; i<pids.length; i++) {
11140                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11141                if (proc != null) {
11142                    int type = proc.setAdj;
11143                    types[i] = type;
11144                    if (type > worstType) {
11145                        worstType = type;
11146                    }
11147                }
11148            }
11149
11150            // If the worst oom_adj is somewhere in the cached proc LRU range,
11151            // then constrain it so we will kill all cached procs.
11152            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
11153                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
11154                worstType = ProcessList.CACHED_APP_MIN_ADJ;
11155            }
11156
11157            // If this is not a secure call, don't let it kill processes that
11158            // are important.
11159            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
11160                worstType = ProcessList.SERVICE_ADJ;
11161            }
11162
11163            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
11164            for (int i=0; i<pids.length; i++) {
11165                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11166                if (proc == null) {
11167                    continue;
11168                }
11169                int adj = proc.setAdj;
11170                if (adj >= worstType && !proc.killedByAm) {
11171                    proc.kill(reason, true);
11172                    killed = true;
11173                }
11174            }
11175        }
11176        return killed;
11177    }
11178
11179    @Override
11180    public void killUid(int uid, String reason) {
11181        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
11182        synchronized (this) {
11183            final long identity = Binder.clearCallingIdentity();
11184            try {
11185                killPackageProcessesLocked(null, UserHandle.getAppId(uid),
11186                        UserHandle.getUserId(uid),
11187                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
11188                        reason != null ? reason : "kill uid");
11189            } finally {
11190                Binder.restoreCallingIdentity(identity);
11191            }
11192        }
11193    }
11194
11195    @Override
11196    public boolean killProcessesBelowForeground(String reason) {
11197        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11198            throw new SecurityException("killProcessesBelowForeground() only available to system");
11199        }
11200
11201        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
11202    }
11203
11204    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
11205        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11206            throw new SecurityException("killProcessesBelowAdj() only available to system");
11207        }
11208
11209        boolean killed = false;
11210        synchronized (mPidsSelfLocked) {
11211            final int size = mPidsSelfLocked.size();
11212            for (int i = 0; i < size; i++) {
11213                final int pid = mPidsSelfLocked.keyAt(i);
11214                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11215                if (proc == null) continue;
11216
11217                final int adj = proc.setAdj;
11218                if (adj > belowAdj && !proc.killedByAm) {
11219                    proc.kill(reason, true);
11220                    killed = true;
11221                }
11222            }
11223        }
11224        return killed;
11225    }
11226
11227    @Override
11228    public void hang(final IBinder who, boolean allowRestart) {
11229        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11230                != PackageManager.PERMISSION_GRANTED) {
11231            throw new SecurityException("Requires permission "
11232                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11233        }
11234
11235        final IBinder.DeathRecipient death = new DeathRecipient() {
11236            @Override
11237            public void binderDied() {
11238                synchronized (this) {
11239                    notifyAll();
11240                }
11241            }
11242        };
11243
11244        try {
11245            who.linkToDeath(death, 0);
11246        } catch (RemoteException e) {
11247            Slog.w(TAG, "hang: given caller IBinder is already dead.");
11248            return;
11249        }
11250
11251        synchronized (this) {
11252            Watchdog.getInstance().setAllowRestart(allowRestart);
11253            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
11254            synchronized (death) {
11255                while (who.isBinderAlive()) {
11256                    try {
11257                        death.wait();
11258                    } catch (InterruptedException e) {
11259                    }
11260                }
11261            }
11262            Watchdog.getInstance().setAllowRestart(true);
11263        }
11264    }
11265
11266    @Override
11267    public void restart() {
11268        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11269                != PackageManager.PERMISSION_GRANTED) {
11270            throw new SecurityException("Requires permission "
11271                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11272        }
11273
11274        Log.i(TAG, "Sending shutdown broadcast...");
11275
11276        BroadcastReceiver br = new BroadcastReceiver() {
11277            @Override public void onReceive(Context context, Intent intent) {
11278                // Now the broadcast is done, finish up the low-level shutdown.
11279                Log.i(TAG, "Shutting down activity manager...");
11280                shutdown(10000);
11281                Log.i(TAG, "Shutdown complete, restarting!");
11282                Process.killProcess(Process.myPid());
11283                System.exit(10);
11284            }
11285        };
11286
11287        // First send the high-level shut down broadcast.
11288        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
11289        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
11290        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
11291        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
11292        mContext.sendOrderedBroadcastAsUser(intent,
11293                UserHandle.ALL, null, br, mHandler, 0, null, null);
11294        */
11295        br.onReceive(mContext, intent);
11296    }
11297
11298    private long getLowRamTimeSinceIdle(long now) {
11299        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
11300    }
11301
11302    @Override
11303    public void performIdleMaintenance() {
11304        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11305                != PackageManager.PERMISSION_GRANTED) {
11306            throw new SecurityException("Requires permission "
11307                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11308        }
11309
11310        synchronized (this) {
11311            final long now = SystemClock.uptimeMillis();
11312            final long timeSinceLastIdle = now - mLastIdleTime;
11313            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
11314            mLastIdleTime = now;
11315            mLowRamTimeSinceLastIdle = 0;
11316            if (mLowRamStartTime != 0) {
11317                mLowRamStartTime = now;
11318            }
11319
11320            StringBuilder sb = new StringBuilder(128);
11321            sb.append("Idle maintenance over ");
11322            TimeUtils.formatDuration(timeSinceLastIdle, sb);
11323            sb.append(" low RAM for ");
11324            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11325            Slog.i(TAG, sb.toString());
11326
11327            // If at least 1/3 of our time since the last idle period has been spent
11328            // with RAM low, then we want to kill processes.
11329            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
11330
11331            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11332                ProcessRecord proc = mLruProcesses.get(i);
11333                if (proc.notCachedSinceIdle) {
11334                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
11335                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
11336                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
11337                        if (doKilling && proc.initialIdlePss != 0
11338                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
11339                            sb = new StringBuilder(128);
11340                            sb.append("Kill");
11341                            sb.append(proc.processName);
11342                            sb.append(" in idle maint: pss=");
11343                            sb.append(proc.lastPss);
11344                            sb.append(", initialPss=");
11345                            sb.append(proc.initialIdlePss);
11346                            sb.append(", period=");
11347                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
11348                            sb.append(", lowRamPeriod=");
11349                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11350                            Slog.wtfQuiet(TAG, sb.toString());
11351                            proc.kill("idle maint (pss " + proc.lastPss
11352                                    + " from " + proc.initialIdlePss + ")", true);
11353                        }
11354                    }
11355                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
11356                    proc.notCachedSinceIdle = true;
11357                    proc.initialIdlePss = 0;
11358                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
11359                            mTestPssMode, isSleeping(), now);
11360                }
11361            }
11362
11363            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
11364            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
11365        }
11366    }
11367
11368    private void retrieveSettings() {
11369        final ContentResolver resolver = mContext.getContentResolver();
11370        String debugApp = Settings.Global.getString(
11371            resolver, Settings.Global.DEBUG_APP);
11372        boolean waitForDebugger = Settings.Global.getInt(
11373            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11374        boolean alwaysFinishActivities = Settings.Global.getInt(
11375            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11376        boolean forceRtl = Settings.Global.getInt(
11377                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11378        // Transfer any global setting for forcing RTL layout, into a System Property
11379        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11380
11381        Configuration configuration = new Configuration();
11382        Settings.System.getConfiguration(resolver, configuration);
11383        if (forceRtl) {
11384            // This will take care of setting the correct layout direction flags
11385            configuration.setLayoutDirection(configuration.locale);
11386        }
11387
11388        synchronized (this) {
11389            mDebugApp = mOrigDebugApp = debugApp;
11390            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11391            mAlwaysFinishActivities = alwaysFinishActivities;
11392            // This happens before any activities are started, so we can
11393            // change mConfiguration in-place.
11394            updateConfigurationLocked(configuration, null, true);
11395            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
11396                    "Initial config: " + mConfiguration);
11397        }
11398    }
11399
11400    /** Loads resources after the current configuration has been set. */
11401    private void loadResourcesOnSystemReady() {
11402        final Resources res = mContext.getResources();
11403        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11404        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11405        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11406    }
11407
11408    public boolean testIsSystemReady() {
11409        // no need to synchronize(this) just to read & return the value
11410        return mSystemReady;
11411    }
11412
11413    private static File getCalledPreBootReceiversFile() {
11414        File dataDir = Environment.getDataDirectory();
11415        File systemDir = new File(dataDir, "system");
11416        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11417        return fname;
11418    }
11419
11420    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11421        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11422        File file = getCalledPreBootReceiversFile();
11423        FileInputStream fis = null;
11424        try {
11425            fis = new FileInputStream(file);
11426            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11427            int fvers = dis.readInt();
11428            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11429                String vers = dis.readUTF();
11430                String codename = dis.readUTF();
11431                String build = dis.readUTF();
11432                if (android.os.Build.VERSION.RELEASE.equals(vers)
11433                        && android.os.Build.VERSION.CODENAME.equals(codename)
11434                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11435                    int num = dis.readInt();
11436                    while (num > 0) {
11437                        num--;
11438                        String pkg = dis.readUTF();
11439                        String cls = dis.readUTF();
11440                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11441                    }
11442                }
11443            }
11444        } catch (FileNotFoundException e) {
11445        } catch (IOException e) {
11446            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11447        } finally {
11448            if (fis != null) {
11449                try {
11450                    fis.close();
11451                } catch (IOException e) {
11452                }
11453            }
11454        }
11455        return lastDoneReceivers;
11456    }
11457
11458    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11459        File file = getCalledPreBootReceiversFile();
11460        FileOutputStream fos = null;
11461        DataOutputStream dos = null;
11462        try {
11463            fos = new FileOutputStream(file);
11464            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11465            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11466            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11467            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11468            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11469            dos.writeInt(list.size());
11470            for (int i=0; i<list.size(); i++) {
11471                dos.writeUTF(list.get(i).getPackageName());
11472                dos.writeUTF(list.get(i).getClassName());
11473            }
11474        } catch (IOException e) {
11475            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11476            file.delete();
11477        } finally {
11478            FileUtils.sync(fos);
11479            if (dos != null) {
11480                try {
11481                    dos.close();
11482                } catch (IOException e) {
11483                    // TODO Auto-generated catch block
11484                    e.printStackTrace();
11485                }
11486            }
11487        }
11488    }
11489
11490    final class PreBootContinuation extends IIntentReceiver.Stub {
11491        final Intent intent;
11492        final Runnable onFinishCallback;
11493        final ArrayList<ComponentName> doneReceivers;
11494        final List<ResolveInfo> ris;
11495        final int[] users;
11496        int lastRi = -1;
11497        int curRi = 0;
11498        int curUser = 0;
11499
11500        PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
11501                ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
11502            intent = _intent;
11503            onFinishCallback = _onFinishCallback;
11504            doneReceivers = _doneReceivers;
11505            ris = _ris;
11506            users = _users;
11507        }
11508
11509        void go() {
11510            if (lastRi != curRi) {
11511                ActivityInfo ai = ris.get(curRi).activityInfo;
11512                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11513                intent.setComponent(comp);
11514                doneReceivers.add(comp);
11515                lastRi = curRi;
11516                CharSequence label = ai.loadLabel(mContext.getPackageManager());
11517                showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
11518            }
11519            Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
11520                    + " for user " + users[curUser]);
11521            EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
11522            broadcastIntentLocked(null, null, intent, null, this,
11523                    0, null, null, null, AppOpsManager.OP_NONE,
11524                    null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
11525        }
11526
11527        public void performReceive(Intent intent, int resultCode,
11528                String data, Bundle extras, boolean ordered,
11529                boolean sticky, int sendingUser) {
11530            curUser++;
11531            if (curUser >= users.length) {
11532                curUser = 0;
11533                curRi++;
11534                if (curRi >= ris.size()) {
11535                    // All done sending broadcasts!
11536                    if (onFinishCallback != null) {
11537                        // The raw IIntentReceiver interface is called
11538                        // with the AM lock held, so redispatch to
11539                        // execute our code without the lock.
11540                        mHandler.post(onFinishCallback);
11541                    }
11542                    return;
11543                }
11544            }
11545            go();
11546        }
11547    }
11548
11549    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11550            ArrayList<ComponentName> doneReceivers, int userId) {
11551        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11552        List<ResolveInfo> ris = null;
11553        try {
11554            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11555                    intent, null, 0, userId);
11556        } catch (RemoteException e) {
11557        }
11558        if (ris == null) {
11559            return false;
11560        }
11561        for (int i=ris.size()-1; i>=0; i--) {
11562            if ((ris.get(i).activityInfo.applicationInfo.flags
11563                    &ApplicationInfo.FLAG_SYSTEM) == 0) {
11564                ris.remove(i);
11565            }
11566        }
11567        intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11568
11569        // For User 0, load the version number. When delivering to a new user, deliver
11570        // to all receivers.
11571        if (userId == UserHandle.USER_OWNER) {
11572            ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11573            for (int i=0; i<ris.size(); i++) {
11574                ActivityInfo ai = ris.get(i).activityInfo;
11575                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11576                if (lastDoneReceivers.contains(comp)) {
11577                    // We already did the pre boot receiver for this app with the current
11578                    // platform version, so don't do it again...
11579                    ris.remove(i);
11580                    i--;
11581                    // ...however, do keep it as one that has been done, so we don't
11582                    // forget about it when rewriting the file of last done receivers.
11583                    doneReceivers.add(comp);
11584                }
11585            }
11586        }
11587
11588        if (ris.size() <= 0) {
11589            return false;
11590        }
11591
11592        // If primary user, send broadcast to all available users, else just to userId
11593        final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11594                : new int[] { userId };
11595        if (users.length <= 0) {
11596            return false;
11597        }
11598
11599        PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
11600                ris, users);
11601        cont.go();
11602        return true;
11603    }
11604
11605    public void systemReady(final Runnable goingCallback) {
11606        synchronized(this) {
11607            if (mSystemReady) {
11608                // If we're done calling all the receivers, run the next "boot phase" passed in
11609                // by the SystemServer
11610                if (goingCallback != null) {
11611                    goingCallback.run();
11612                }
11613                return;
11614            }
11615
11616            mLocalDeviceIdleController
11617                    = LocalServices.getService(DeviceIdleController.LocalService.class);
11618
11619            // Make sure we have the current profile info, since it is needed for
11620            // security checks.
11621            updateCurrentProfileIdsLocked();
11622
11623            mRecentTasks.clear();
11624            mRecentTasks.addAll(mTaskPersister.restoreTasksLocked());
11625            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
11626            mTaskPersister.startPersisting();
11627
11628            // Check to see if there are any update receivers to run.
11629            if (!mDidUpdate) {
11630                if (mWaitingUpdate) {
11631                    return;
11632                }
11633                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11634                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11635                    public void run() {
11636                        synchronized (ActivityManagerService.this) {
11637                            mDidUpdate = true;
11638                        }
11639                        showBootMessage(mContext.getText(
11640                                R.string.android_upgrading_complete),
11641                                false);
11642                        writeLastDonePreBootReceivers(doneReceivers);
11643                        systemReady(goingCallback);
11644                    }
11645                }, doneReceivers, UserHandle.USER_OWNER);
11646
11647                if (mWaitingUpdate) {
11648                    return;
11649                }
11650                mDidUpdate = true;
11651            }
11652
11653            mAppOpsService.systemReady();
11654            mSystemReady = true;
11655        }
11656
11657        ArrayList<ProcessRecord> procsToKill = null;
11658        synchronized(mPidsSelfLocked) {
11659            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11660                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11661                if (!isAllowedWhileBooting(proc.info)){
11662                    if (procsToKill == null) {
11663                        procsToKill = new ArrayList<ProcessRecord>();
11664                    }
11665                    procsToKill.add(proc);
11666                }
11667            }
11668        }
11669
11670        synchronized(this) {
11671            if (procsToKill != null) {
11672                for (int i=procsToKill.size()-1; i>=0; i--) {
11673                    ProcessRecord proc = procsToKill.get(i);
11674                    Slog.i(TAG, "Removing system update proc: " + proc);
11675                    removeProcessLocked(proc, true, false, "system update done");
11676                }
11677            }
11678
11679            // Now that we have cleaned up any update processes, we
11680            // are ready to start launching real processes and know that
11681            // we won't trample on them any more.
11682            mProcessesReady = true;
11683        }
11684
11685        Slog.i(TAG, "System now ready");
11686        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11687            SystemClock.uptimeMillis());
11688
11689        synchronized(this) {
11690            // Make sure we have no pre-ready processes sitting around.
11691
11692            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11693                ResolveInfo ri = mContext.getPackageManager()
11694                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11695                                STOCK_PM_FLAGS);
11696                CharSequence errorMsg = null;
11697                if (ri != null) {
11698                    ActivityInfo ai = ri.activityInfo;
11699                    ApplicationInfo app = ai.applicationInfo;
11700                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11701                        mTopAction = Intent.ACTION_FACTORY_TEST;
11702                        mTopData = null;
11703                        mTopComponent = new ComponentName(app.packageName,
11704                                ai.name);
11705                    } else {
11706                        errorMsg = mContext.getResources().getText(
11707                                com.android.internal.R.string.factorytest_not_system);
11708                    }
11709                } else {
11710                    errorMsg = mContext.getResources().getText(
11711                            com.android.internal.R.string.factorytest_no_action);
11712                }
11713                if (errorMsg != null) {
11714                    mTopAction = null;
11715                    mTopData = null;
11716                    mTopComponent = null;
11717                    Message msg = Message.obtain();
11718                    msg.what = SHOW_FACTORY_ERROR_MSG;
11719                    msg.getData().putCharSequence("msg", errorMsg);
11720                    mUiHandler.sendMessage(msg);
11721                }
11722            }
11723        }
11724
11725        retrieveSettings();
11726        loadResourcesOnSystemReady();
11727
11728        synchronized (this) {
11729            readGrantedUriPermissionsLocked();
11730        }
11731
11732        if (goingCallback != null) goingCallback.run();
11733
11734        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11735                Integer.toString(mCurrentUserId), mCurrentUserId);
11736        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11737                Integer.toString(mCurrentUserId), mCurrentUserId);
11738        mSystemServiceManager.startUser(mCurrentUserId);
11739
11740        synchronized (this) {
11741            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11742                try {
11743                    List apps = AppGlobals.getPackageManager().
11744                        getPersistentApplications(STOCK_PM_FLAGS);
11745                    if (apps != null) {
11746                        int N = apps.size();
11747                        int i;
11748                        for (i=0; i<N; i++) {
11749                            ApplicationInfo info
11750                                = (ApplicationInfo)apps.get(i);
11751                            if (info != null &&
11752                                    !info.packageName.equals("android")) {
11753                                addAppLocked(info, false, null /* ABI override */);
11754                            }
11755                        }
11756                    }
11757                } catch (RemoteException ex) {
11758                    // pm is in same process, this will never happen.
11759                }
11760            }
11761
11762            // Start up initial activity.
11763            mBooting = true;
11764            startHomeActivityLocked(mCurrentUserId, "systemReady");
11765
11766            try {
11767                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11768                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11769                            + " data partition or your device will be unstable.");
11770                    mUiHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11771                }
11772            } catch (RemoteException e) {
11773            }
11774
11775            if (!Build.isBuildConsistent()) {
11776                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11777                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11778            }
11779
11780            long ident = Binder.clearCallingIdentity();
11781            try {
11782                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11783                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11784                        | Intent.FLAG_RECEIVER_FOREGROUND);
11785                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11786                broadcastIntentLocked(null, null, intent,
11787                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11788                        null, false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11789                intent = new Intent(Intent.ACTION_USER_STARTING);
11790                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11791                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11792                broadcastIntentLocked(null, null, intent,
11793                        null, new IIntentReceiver.Stub() {
11794                            @Override
11795                            public void performReceive(Intent intent, int resultCode, String data,
11796                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11797                                    throws RemoteException {
11798                            }
11799                        }, 0, null, null,
11800                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11801                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11802            } catch (Throwable t) {
11803                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11804            } finally {
11805                Binder.restoreCallingIdentity(ident);
11806            }
11807            mStackSupervisor.resumeTopActivitiesLocked();
11808            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11809        }
11810    }
11811
11812    private boolean makeAppCrashingLocked(ProcessRecord app,
11813            String shortMsg, String longMsg, String stackTrace) {
11814        app.crashing = true;
11815        app.crashingReport = generateProcessError(app,
11816                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11817        startAppProblemLocked(app);
11818        app.stopFreezingAllLocked();
11819        return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
11820    }
11821
11822    private void makeAppNotRespondingLocked(ProcessRecord app,
11823            String activity, String shortMsg, String longMsg) {
11824        app.notResponding = true;
11825        app.notRespondingReport = generateProcessError(app,
11826                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11827                activity, shortMsg, longMsg, null);
11828        startAppProblemLocked(app);
11829        app.stopFreezingAllLocked();
11830    }
11831
11832    /**
11833     * Generate a process error record, suitable for attachment to a ProcessRecord.
11834     *
11835     * @param app The ProcessRecord in which the error occurred.
11836     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11837     *                      ActivityManager.AppErrorStateInfo
11838     * @param activity The activity associated with the crash, if known.
11839     * @param shortMsg Short message describing the crash.
11840     * @param longMsg Long message describing the crash.
11841     * @param stackTrace Full crash stack trace, may be null.
11842     *
11843     * @return Returns a fully-formed AppErrorStateInfo record.
11844     */
11845    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11846            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11847        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11848
11849        report.condition = condition;
11850        report.processName = app.processName;
11851        report.pid = app.pid;
11852        report.uid = app.info.uid;
11853        report.tag = activity;
11854        report.shortMsg = shortMsg;
11855        report.longMsg = longMsg;
11856        report.stackTrace = stackTrace;
11857
11858        return report;
11859    }
11860
11861    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11862        synchronized (this) {
11863            app.crashing = false;
11864            app.crashingReport = null;
11865            app.notResponding = false;
11866            app.notRespondingReport = null;
11867            if (app.anrDialog == fromDialog) {
11868                app.anrDialog = null;
11869            }
11870            if (app.waitDialog == fromDialog) {
11871                app.waitDialog = null;
11872            }
11873            if (app.pid > 0 && app.pid != MY_PID) {
11874                handleAppCrashLocked(app, "user-terminated" /*reason*/,
11875                        null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
11876                app.kill("user request after error", true);
11877            }
11878        }
11879    }
11880
11881    private boolean handleAppCrashLocked(ProcessRecord app, String reason,
11882            String shortMsg, String longMsg, String stackTrace) {
11883        long now = SystemClock.uptimeMillis();
11884
11885        Long crashTime;
11886        if (!app.isolated) {
11887            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11888        } else {
11889            crashTime = null;
11890        }
11891        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11892            // This process loses!
11893            Slog.w(TAG, "Process " + app.info.processName
11894                    + " has crashed too many times: killing!");
11895            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11896                    app.userId, app.info.processName, app.uid);
11897            mStackSupervisor.handleAppCrashLocked(app);
11898            if (!app.persistent) {
11899                // We don't want to start this process again until the user
11900                // explicitly does so...  but for persistent process, we really
11901                // need to keep it running.  If a persistent process is actually
11902                // repeatedly crashing, then badness for everyone.
11903                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11904                        app.info.processName);
11905                if (!app.isolated) {
11906                    // XXX We don't have a way to mark isolated processes
11907                    // as bad, since they don't have a peristent identity.
11908                    mBadProcesses.put(app.info.processName, app.uid,
11909                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11910                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11911                }
11912                app.bad = true;
11913                app.removed = true;
11914                // Don't let services in this process be restarted and potentially
11915                // annoy the user repeatedly.  Unless it is persistent, since those
11916                // processes run critical code.
11917                removeProcessLocked(app, false, false, "crash");
11918                mStackSupervisor.resumeTopActivitiesLocked();
11919                return false;
11920            }
11921            mStackSupervisor.resumeTopActivitiesLocked();
11922        } else {
11923            mStackSupervisor.finishTopRunningActivityLocked(app, reason);
11924        }
11925
11926        // Bump up the crash count of any services currently running in the proc.
11927        for (int i=app.services.size()-1; i>=0; i--) {
11928            // Any services running in the application need to be placed
11929            // back in the pending list.
11930            ServiceRecord sr = app.services.valueAt(i);
11931            sr.crashCount++;
11932        }
11933
11934        // If the crashing process is what we consider to be the "home process" and it has been
11935        // replaced by a third-party app, clear the package preferred activities from packages
11936        // with a home activity running in the process to prevent a repeatedly crashing app
11937        // from blocking the user to manually clear the list.
11938        final ArrayList<ActivityRecord> activities = app.activities;
11939        if (app == mHomeProcess && activities.size() > 0
11940                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11941            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11942                final ActivityRecord r = activities.get(activityNdx);
11943                if (r.isHomeActivity()) {
11944                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11945                    try {
11946                        ActivityThread.getPackageManager()
11947                                .clearPackagePreferredActivities(r.packageName);
11948                    } catch (RemoteException c) {
11949                        // pm is in same process, this will never happen.
11950                    }
11951                }
11952            }
11953        }
11954
11955        if (!app.isolated) {
11956            // XXX Can't keep track of crash times for isolated processes,
11957            // because they don't have a perisistent identity.
11958            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11959        }
11960
11961        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11962        return true;
11963    }
11964
11965    void startAppProblemLocked(ProcessRecord app) {
11966        // If this app is not running under the current user, then we
11967        // can't give it a report button because that would require
11968        // launching the report UI under a different user.
11969        app.errorReportReceiver = null;
11970
11971        for (int userId : mCurrentProfileIds) {
11972            if (app.userId == userId) {
11973                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11974                        mContext, app.info.packageName, app.info.flags);
11975            }
11976        }
11977        skipCurrentReceiverLocked(app);
11978    }
11979
11980    void skipCurrentReceiverLocked(ProcessRecord app) {
11981        for (BroadcastQueue queue : mBroadcastQueues) {
11982            queue.skipCurrentReceiverLocked(app);
11983        }
11984    }
11985
11986    /**
11987     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11988     * The application process will exit immediately after this call returns.
11989     * @param app object of the crashing app, null for the system server
11990     * @param crashInfo describing the exception
11991     */
11992    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11993        ProcessRecord r = findAppProcess(app, "Crash");
11994        final String processName = app == null ? "system_server"
11995                : (r == null ? "unknown" : r.processName);
11996
11997        handleApplicationCrashInner("crash", r, processName, crashInfo);
11998    }
11999
12000    /* Native crash reporting uses this inner version because it needs to be somewhat
12001     * decoupled from the AM-managed cleanup lifecycle
12002     */
12003    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12004            ApplicationErrorReport.CrashInfo crashInfo) {
12005        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12006                UserHandle.getUserId(Binder.getCallingUid()), processName,
12007                r == null ? -1 : r.info.flags,
12008                crashInfo.exceptionClassName,
12009                crashInfo.exceptionMessage,
12010                crashInfo.throwFileName,
12011                crashInfo.throwLineNumber);
12012
12013        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12014
12015        crashApplication(r, crashInfo);
12016    }
12017
12018    public void handleApplicationStrictModeViolation(
12019            IBinder app,
12020            int violationMask,
12021            StrictMode.ViolationInfo info) {
12022        ProcessRecord r = findAppProcess(app, "StrictMode");
12023        if (r == null) {
12024            return;
12025        }
12026
12027        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12028            Integer stackFingerprint = info.hashCode();
12029            boolean logIt = true;
12030            synchronized (mAlreadyLoggedViolatedStacks) {
12031                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12032                    logIt = false;
12033                    // TODO: sub-sample into EventLog for these, with
12034                    // the info.durationMillis?  Then we'd get
12035                    // the relative pain numbers, without logging all
12036                    // the stack traces repeatedly.  We'd want to do
12037                    // likewise in the client code, which also does
12038                    // dup suppression, before the Binder call.
12039                } else {
12040                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12041                        mAlreadyLoggedViolatedStacks.clear();
12042                    }
12043                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12044                }
12045            }
12046            if (logIt) {
12047                logStrictModeViolationToDropBox(r, info);
12048            }
12049        }
12050
12051        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12052            AppErrorResult result = new AppErrorResult();
12053            synchronized (this) {
12054                final long origId = Binder.clearCallingIdentity();
12055
12056                Message msg = Message.obtain();
12057                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
12058                HashMap<String, Object> data = new HashMap<String, Object>();
12059                data.put("result", result);
12060                data.put("app", r);
12061                data.put("violationMask", violationMask);
12062                data.put("info", info);
12063                msg.obj = data;
12064                mUiHandler.sendMessage(msg);
12065
12066                Binder.restoreCallingIdentity(origId);
12067            }
12068            int res = result.get();
12069            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12070        }
12071    }
12072
12073    // Depending on the policy in effect, there could be a bunch of
12074    // these in quick succession so we try to batch these together to
12075    // minimize disk writes, number of dropbox entries, and maximize
12076    // compression, by having more fewer, larger records.
12077    private void logStrictModeViolationToDropBox(
12078            ProcessRecord process,
12079            StrictMode.ViolationInfo info) {
12080        if (info == null) {
12081            return;
12082        }
12083        final boolean isSystemApp = process == null ||
12084                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12085                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12086        final String processName = process == null ? "unknown" : process.processName;
12087        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12088        final DropBoxManager dbox = (DropBoxManager)
12089                mContext.getSystemService(Context.DROPBOX_SERVICE);
12090
12091        // Exit early if the dropbox isn't configured to accept this report type.
12092        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12093
12094        boolean bufferWasEmpty;
12095        boolean needsFlush;
12096        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12097        synchronized (sb) {
12098            bufferWasEmpty = sb.length() == 0;
12099            appendDropBoxProcessHeaders(process, processName, sb);
12100            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12101            sb.append("System-App: ").append(isSystemApp).append("\n");
12102            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12103            if (info.violationNumThisLoop != 0) {
12104                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12105            }
12106            if (info.numAnimationsRunning != 0) {
12107                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12108            }
12109            if (info.broadcastIntentAction != null) {
12110                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12111            }
12112            if (info.durationMillis != -1) {
12113                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12114            }
12115            if (info.numInstances != -1) {
12116                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12117            }
12118            if (info.tags != null) {
12119                for (String tag : info.tags) {
12120                    sb.append("Span-Tag: ").append(tag).append("\n");
12121                }
12122            }
12123            sb.append("\n");
12124            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
12125                sb.append(info.crashInfo.stackTrace);
12126                sb.append("\n");
12127            }
12128            if (info.message != null) {
12129                sb.append(info.message);
12130                sb.append("\n");
12131            }
12132
12133            // Only buffer up to ~64k.  Various logging bits truncate
12134            // things at 128k.
12135            needsFlush = (sb.length() > 64 * 1024);
12136        }
12137
12138        // Flush immediately if the buffer's grown too large, or this
12139        // is a non-system app.  Non-system apps are isolated with a
12140        // different tag & policy and not batched.
12141        //
12142        // Batching is useful during internal testing with
12143        // StrictMode settings turned up high.  Without batching,
12144        // thousands of separate files could be created on boot.
12145        if (!isSystemApp || needsFlush) {
12146            new Thread("Error dump: " + dropboxTag) {
12147                @Override
12148                public void run() {
12149                    String report;
12150                    synchronized (sb) {
12151                        report = sb.toString();
12152                        sb.delete(0, sb.length());
12153                        sb.trimToSize();
12154                    }
12155                    if (report.length() != 0) {
12156                        dbox.addText(dropboxTag, report);
12157                    }
12158                }
12159            }.start();
12160            return;
12161        }
12162
12163        // System app batching:
12164        if (!bufferWasEmpty) {
12165            // An existing dropbox-writing thread is outstanding, so
12166            // we don't need to start it up.  The existing thread will
12167            // catch the buffer appends we just did.
12168            return;
12169        }
12170
12171        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
12172        // (After this point, we shouldn't access AMS internal data structures.)
12173        new Thread("Error dump: " + dropboxTag) {
12174            @Override
12175            public void run() {
12176                // 5 second sleep to let stacks arrive and be batched together
12177                try {
12178                    Thread.sleep(5000);  // 5 seconds
12179                } catch (InterruptedException e) {}
12180
12181                String errorReport;
12182                synchronized (mStrictModeBuffer) {
12183                    errorReport = mStrictModeBuffer.toString();
12184                    if (errorReport.length() == 0) {
12185                        return;
12186                    }
12187                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
12188                    mStrictModeBuffer.trimToSize();
12189                }
12190                dbox.addText(dropboxTag, errorReport);
12191            }
12192        }.start();
12193    }
12194
12195    /**
12196     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
12197     * @param app object of the crashing app, null for the system server
12198     * @param tag reported by the caller
12199     * @param system whether this wtf is coming from the system
12200     * @param crashInfo describing the context of the error
12201     * @return true if the process should exit immediately (WTF is fatal)
12202     */
12203    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
12204            final ApplicationErrorReport.CrashInfo crashInfo) {
12205        final int callingUid = Binder.getCallingUid();
12206        final int callingPid = Binder.getCallingPid();
12207
12208        if (system) {
12209            // If this is coming from the system, we could very well have low-level
12210            // system locks held, so we want to do this all asynchronously.  And we
12211            // never want this to become fatal, so there is that too.
12212            mHandler.post(new Runnable() {
12213                @Override public void run() {
12214                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
12215                }
12216            });
12217            return false;
12218        }
12219
12220        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
12221                crashInfo);
12222
12223        if (r != null && r.pid != Process.myPid() &&
12224                Settings.Global.getInt(mContext.getContentResolver(),
12225                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
12226            crashApplication(r, crashInfo);
12227            return true;
12228        } else {
12229            return false;
12230        }
12231    }
12232
12233    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
12234            final ApplicationErrorReport.CrashInfo crashInfo) {
12235        final ProcessRecord r = findAppProcess(app, "WTF");
12236        final String processName = app == null ? "system_server"
12237                : (r == null ? "unknown" : r.processName);
12238
12239        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
12240                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
12241
12242        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
12243
12244        return r;
12245    }
12246
12247    /**
12248     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
12249     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
12250     */
12251    private ProcessRecord findAppProcess(IBinder app, String reason) {
12252        if (app == null) {
12253            return null;
12254        }
12255
12256        synchronized (this) {
12257            final int NP = mProcessNames.getMap().size();
12258            for (int ip=0; ip<NP; ip++) {
12259                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12260                final int NA = apps.size();
12261                for (int ia=0; ia<NA; ia++) {
12262                    ProcessRecord p = apps.valueAt(ia);
12263                    if (p.thread != null && p.thread.asBinder() == app) {
12264                        return p;
12265                    }
12266                }
12267            }
12268
12269            Slog.w(TAG, "Can't find mystery application for " + reason
12270                    + " from pid=" + Binder.getCallingPid()
12271                    + " uid=" + Binder.getCallingUid() + ": " + app);
12272            return null;
12273        }
12274    }
12275
12276    /**
12277     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
12278     * to append various headers to the dropbox log text.
12279     */
12280    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
12281            StringBuilder sb) {
12282        // Watchdog thread ends up invoking this function (with
12283        // a null ProcessRecord) to add the stack file to dropbox.
12284        // Do not acquire a lock on this (am) in such cases, as it
12285        // could cause a potential deadlock, if and when watchdog
12286        // is invoked due to unavailability of lock on am and it
12287        // would prevent watchdog from killing system_server.
12288        if (process == null) {
12289            sb.append("Process: ").append(processName).append("\n");
12290            return;
12291        }
12292        // Note: ProcessRecord 'process' is guarded by the service
12293        // instance.  (notably process.pkgList, which could otherwise change
12294        // concurrently during execution of this method)
12295        synchronized (this) {
12296            sb.append("Process: ").append(processName).append("\n");
12297            int flags = process.info.flags;
12298            IPackageManager pm = AppGlobals.getPackageManager();
12299            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
12300            for (int ip=0; ip<process.pkgList.size(); ip++) {
12301                String pkg = process.pkgList.keyAt(ip);
12302                sb.append("Package: ").append(pkg);
12303                try {
12304                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
12305                    if (pi != null) {
12306                        sb.append(" v").append(pi.versionCode);
12307                        if (pi.versionName != null) {
12308                            sb.append(" (").append(pi.versionName).append(")");
12309                        }
12310                    }
12311                } catch (RemoteException e) {
12312                    Slog.e(TAG, "Error getting package info: " + pkg, e);
12313                }
12314                sb.append("\n");
12315            }
12316        }
12317    }
12318
12319    private static String processClass(ProcessRecord process) {
12320        if (process == null || process.pid == MY_PID) {
12321            return "system_server";
12322        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
12323            return "system_app";
12324        } else {
12325            return "data_app";
12326        }
12327    }
12328
12329    /**
12330     * Write a description of an error (crash, WTF, ANR) to the drop box.
12331     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
12332     * @param process which caused the error, null means the system server
12333     * @param activity which triggered the error, null if unknown
12334     * @param parent activity related to the error, null if unknown
12335     * @param subject line related to the error, null if absent
12336     * @param report in long form describing the error, null if absent
12337     * @param logFile to include in the report, null if none
12338     * @param crashInfo giving an application stack trace, null if absent
12339     */
12340    public void addErrorToDropBox(String eventType,
12341            ProcessRecord process, String processName, ActivityRecord activity,
12342            ActivityRecord parent, String subject,
12343            final String report, final File logFile,
12344            final ApplicationErrorReport.CrashInfo crashInfo) {
12345        // NOTE -- this must never acquire the ActivityManagerService lock,
12346        // otherwise the watchdog may be prevented from resetting the system.
12347
12348        final String dropboxTag = processClass(process) + "_" + eventType;
12349        final DropBoxManager dbox = (DropBoxManager)
12350                mContext.getSystemService(Context.DROPBOX_SERVICE);
12351
12352        // Exit early if the dropbox isn't configured to accept this report type.
12353        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12354
12355        final StringBuilder sb = new StringBuilder(1024);
12356        appendDropBoxProcessHeaders(process, processName, sb);
12357        if (activity != null) {
12358            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
12359        }
12360        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
12361            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
12362        }
12363        if (parent != null && parent != activity) {
12364            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
12365        }
12366        if (subject != null) {
12367            sb.append("Subject: ").append(subject).append("\n");
12368        }
12369        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12370        if (Debug.isDebuggerConnected()) {
12371            sb.append("Debugger: Connected\n");
12372        }
12373        sb.append("\n");
12374
12375        // Do the rest in a worker thread to avoid blocking the caller on I/O
12376        // (After this point, we shouldn't access AMS internal data structures.)
12377        Thread worker = new Thread("Error dump: " + dropboxTag) {
12378            @Override
12379            public void run() {
12380                if (report != null) {
12381                    sb.append(report);
12382                }
12383                if (logFile != null) {
12384                    try {
12385                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
12386                                    "\n\n[[TRUNCATED]]"));
12387                    } catch (IOException e) {
12388                        Slog.e(TAG, "Error reading " + logFile, e);
12389                    }
12390                }
12391                if (crashInfo != null && crashInfo.stackTrace != null) {
12392                    sb.append(crashInfo.stackTrace);
12393                }
12394
12395                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
12396                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
12397                if (lines > 0) {
12398                    sb.append("\n");
12399
12400                    // Merge several logcat streams, and take the last N lines
12401                    InputStreamReader input = null;
12402                    try {
12403                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
12404                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
12405                                "-b", "crash",
12406                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
12407
12408                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
12409                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
12410                        input = new InputStreamReader(logcat.getInputStream());
12411
12412                        int num;
12413                        char[] buf = new char[8192];
12414                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
12415                    } catch (IOException e) {
12416                        Slog.e(TAG, "Error running logcat", e);
12417                    } finally {
12418                        if (input != null) try { input.close(); } catch (IOException e) {}
12419                    }
12420                }
12421
12422                dbox.addText(dropboxTag, sb.toString());
12423            }
12424        };
12425
12426        if (process == null) {
12427            // If process is null, we are being called from some internal code
12428            // and may be about to die -- run this synchronously.
12429            worker.run();
12430        } else {
12431            worker.start();
12432        }
12433    }
12434
12435    /**
12436     * Bring up the "unexpected error" dialog box for a crashing app.
12437     * Deal with edge cases (intercepts from instrumented applications,
12438     * ActivityController, error intent receivers, that sort of thing).
12439     * @param r the application crashing
12440     * @param crashInfo describing the failure
12441     */
12442    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12443        long timeMillis = System.currentTimeMillis();
12444        String shortMsg = crashInfo.exceptionClassName;
12445        String longMsg = crashInfo.exceptionMessage;
12446        String stackTrace = crashInfo.stackTrace;
12447        if (shortMsg != null && longMsg != null) {
12448            longMsg = shortMsg + ": " + longMsg;
12449        } else if (shortMsg != null) {
12450            longMsg = shortMsg;
12451        }
12452
12453        AppErrorResult result = new AppErrorResult();
12454        synchronized (this) {
12455            if (mController != null) {
12456                try {
12457                    String name = r != null ? r.processName : null;
12458                    int pid = r != null ? r.pid : Binder.getCallingPid();
12459                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
12460                    if (!mController.appCrashed(name, pid,
12461                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12462                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12463                                && "Native crash".equals(crashInfo.exceptionClassName)) {
12464                            Slog.w(TAG, "Skip killing native crashed app " + name
12465                                    + "(" + pid + ") during testing");
12466                        } else {
12467                            Slog.w(TAG, "Force-killing crashed app " + name
12468                                    + " at watcher's request");
12469                            if (r != null) {
12470                                r.kill("crash", true);
12471                            } else {
12472                                // Huh.
12473                                Process.killProcess(pid);
12474                                killProcessGroup(uid, pid);
12475                            }
12476                        }
12477                        return;
12478                    }
12479                } catch (RemoteException e) {
12480                    mController = null;
12481                    Watchdog.getInstance().setActivityController(null);
12482                }
12483            }
12484
12485            final long origId = Binder.clearCallingIdentity();
12486
12487            // If this process is running instrumentation, finish it.
12488            if (r != null && r.instrumentationClass != null) {
12489                Slog.w(TAG, "Error in app " + r.processName
12490                      + " running instrumentation " + r.instrumentationClass + ":");
12491                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12492                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12493                Bundle info = new Bundle();
12494                info.putString("shortMsg", shortMsg);
12495                info.putString("longMsg", longMsg);
12496                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12497                Binder.restoreCallingIdentity(origId);
12498                return;
12499            }
12500
12501            // Log crash in battery stats.
12502            if (r != null) {
12503                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12504            }
12505
12506            // If we can't identify the process or it's already exceeded its crash quota,
12507            // quit right away without showing a crash dialog.
12508            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12509                Binder.restoreCallingIdentity(origId);
12510                return;
12511            }
12512
12513            Message msg = Message.obtain();
12514            msg.what = SHOW_ERROR_MSG;
12515            HashMap data = new HashMap();
12516            data.put("result", result);
12517            data.put("app", r);
12518            msg.obj = data;
12519            mUiHandler.sendMessage(msg);
12520
12521            Binder.restoreCallingIdentity(origId);
12522        }
12523
12524        int res = result.get();
12525
12526        Intent appErrorIntent = null;
12527        synchronized (this) {
12528            if (r != null && !r.isolated) {
12529                // XXX Can't keep track of crash time for isolated processes,
12530                // since they don't have a persistent identity.
12531                mProcessCrashTimes.put(r.info.processName, r.uid,
12532                        SystemClock.uptimeMillis());
12533            }
12534            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12535                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12536            }
12537        }
12538
12539        if (appErrorIntent != null) {
12540            try {
12541                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12542            } catch (ActivityNotFoundException e) {
12543                Slog.w(TAG, "bug report receiver dissappeared", e);
12544            }
12545        }
12546    }
12547
12548    Intent createAppErrorIntentLocked(ProcessRecord r,
12549            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12550        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12551        if (report == null) {
12552            return null;
12553        }
12554        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12555        result.setComponent(r.errorReportReceiver);
12556        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12557        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12558        return result;
12559    }
12560
12561    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12562            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12563        if (r.errorReportReceiver == null) {
12564            return null;
12565        }
12566
12567        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12568            return null;
12569        }
12570
12571        ApplicationErrorReport report = new ApplicationErrorReport();
12572        report.packageName = r.info.packageName;
12573        report.installerPackageName = r.errorReportReceiver.getPackageName();
12574        report.processName = r.processName;
12575        report.time = timeMillis;
12576        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12577
12578        if (r.crashing || r.forceCrashReport) {
12579            report.type = ApplicationErrorReport.TYPE_CRASH;
12580            report.crashInfo = crashInfo;
12581        } else if (r.notResponding) {
12582            report.type = ApplicationErrorReport.TYPE_ANR;
12583            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12584
12585            report.anrInfo.activity = r.notRespondingReport.tag;
12586            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12587            report.anrInfo.info = r.notRespondingReport.longMsg;
12588        }
12589
12590        return report;
12591    }
12592
12593    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12594        enforceNotIsolatedCaller("getProcessesInErrorState");
12595        // assume our apps are happy - lazy create the list
12596        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12597
12598        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12599                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12600        int userId = UserHandle.getUserId(Binder.getCallingUid());
12601
12602        synchronized (this) {
12603
12604            // iterate across all processes
12605            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12606                ProcessRecord app = mLruProcesses.get(i);
12607                if (!allUsers && app.userId != userId) {
12608                    continue;
12609                }
12610                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12611                    // This one's in trouble, so we'll generate a report for it
12612                    // crashes are higher priority (in case there's a crash *and* an anr)
12613                    ActivityManager.ProcessErrorStateInfo report = null;
12614                    if (app.crashing) {
12615                        report = app.crashingReport;
12616                    } else if (app.notResponding) {
12617                        report = app.notRespondingReport;
12618                    }
12619
12620                    if (report != null) {
12621                        if (errList == null) {
12622                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12623                        }
12624                        errList.add(report);
12625                    } else {
12626                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12627                                " crashing = " + app.crashing +
12628                                " notResponding = " + app.notResponding);
12629                    }
12630                }
12631            }
12632        }
12633
12634        return errList;
12635    }
12636
12637    static int procStateToImportance(int procState, int memAdj,
12638            ActivityManager.RunningAppProcessInfo currApp) {
12639        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12640        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12641            currApp.lru = memAdj;
12642        } else {
12643            currApp.lru = 0;
12644        }
12645        return imp;
12646    }
12647
12648    private void fillInProcMemInfo(ProcessRecord app,
12649            ActivityManager.RunningAppProcessInfo outInfo) {
12650        outInfo.pid = app.pid;
12651        outInfo.uid = app.info.uid;
12652        if (mHeavyWeightProcess == app) {
12653            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12654        }
12655        if (app.persistent) {
12656            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12657        }
12658        if (app.activities.size() > 0) {
12659            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12660        }
12661        outInfo.lastTrimLevel = app.trimMemoryLevel;
12662        int adj = app.curAdj;
12663        int procState = app.curProcState;
12664        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12665        outInfo.importanceReasonCode = app.adjTypeCode;
12666        outInfo.processState = app.curProcState;
12667    }
12668
12669    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12670        enforceNotIsolatedCaller("getRunningAppProcesses");
12671
12672        final int callingUid = Binder.getCallingUid();
12673
12674        // Lazy instantiation of list
12675        List<ActivityManager.RunningAppProcessInfo> runList = null;
12676        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12677                callingUid) == PackageManager.PERMISSION_GRANTED;
12678        final int userId = UserHandle.getUserId(callingUid);
12679        final boolean allUids = isGetTasksAllowed(
12680                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
12681
12682        synchronized (this) {
12683            // Iterate across all processes
12684            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
12685                ProcessRecord app = mLruProcesses.get(i);
12686                if ((!allUsers && app.userId != userId)
12687                        || (!allUids && app.uid != callingUid)) {
12688                    continue;
12689                }
12690                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12691                    // Generate process state info for running application
12692                    ActivityManager.RunningAppProcessInfo currApp =
12693                        new ActivityManager.RunningAppProcessInfo(app.processName,
12694                                app.pid, app.getPackageList());
12695                    fillInProcMemInfo(app, currApp);
12696                    if (app.adjSource instanceof ProcessRecord) {
12697                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12698                        currApp.importanceReasonImportance =
12699                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12700                                        app.adjSourceProcState);
12701                    } else if (app.adjSource instanceof ActivityRecord) {
12702                        ActivityRecord r = (ActivityRecord)app.adjSource;
12703                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12704                    }
12705                    if (app.adjTarget instanceof ComponentName) {
12706                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12707                    }
12708                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12709                    //        + " lru=" + currApp.lru);
12710                    if (runList == null) {
12711                        runList = new ArrayList<>();
12712                    }
12713                    runList.add(currApp);
12714                }
12715            }
12716        }
12717        return runList;
12718    }
12719
12720    public List<ApplicationInfo> getRunningExternalApplications() {
12721        enforceNotIsolatedCaller("getRunningExternalApplications");
12722        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12723        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12724        if (runningApps != null && runningApps.size() > 0) {
12725            Set<String> extList = new HashSet<String>();
12726            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12727                if (app.pkgList != null) {
12728                    for (String pkg : app.pkgList) {
12729                        extList.add(pkg);
12730                    }
12731                }
12732            }
12733            IPackageManager pm = AppGlobals.getPackageManager();
12734            for (String pkg : extList) {
12735                try {
12736                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12737                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12738                        retList.add(info);
12739                    }
12740                } catch (RemoteException e) {
12741                }
12742            }
12743        }
12744        return retList;
12745    }
12746
12747    @Override
12748    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12749        enforceNotIsolatedCaller("getMyMemoryState");
12750        synchronized (this) {
12751            ProcessRecord proc;
12752            synchronized (mPidsSelfLocked) {
12753                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12754            }
12755            fillInProcMemInfo(proc, outInfo);
12756        }
12757    }
12758
12759    @Override
12760    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12761        if (checkCallingPermission(android.Manifest.permission.DUMP)
12762                != PackageManager.PERMISSION_GRANTED) {
12763            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12764                    + Binder.getCallingPid()
12765                    + ", uid=" + Binder.getCallingUid()
12766                    + " without permission "
12767                    + android.Manifest.permission.DUMP);
12768            return;
12769        }
12770
12771        boolean dumpAll = false;
12772        boolean dumpClient = false;
12773        String dumpPackage = null;
12774
12775        int opti = 0;
12776        while (opti < args.length) {
12777            String opt = args[opti];
12778            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12779                break;
12780            }
12781            opti++;
12782            if ("-a".equals(opt)) {
12783                dumpAll = true;
12784            } else if ("-c".equals(opt)) {
12785                dumpClient = true;
12786            } else if ("-p".equals(opt)) {
12787                if (opti < args.length) {
12788                    dumpPackage = args[opti];
12789                    opti++;
12790                } else {
12791                    pw.println("Error: -p option requires package argument");
12792                    return;
12793                }
12794                dumpClient = true;
12795            } else if ("-h".equals(opt)) {
12796                pw.println("Activity manager dump options:");
12797                pw.println("  [-a] [-c] [-p package] [-h] [cmd] ...");
12798                pw.println("  cmd may be one of:");
12799                pw.println("    a[ctivities]: activity stack state");
12800                pw.println("    r[recents]: recent activities state");
12801                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12802                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12803                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12804                pw.println("    o[om]: out of memory management");
12805                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12806                pw.println("    provider [COMP_SPEC]: provider client-side state");
12807                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12808                pw.println("    as[sociations]: tracked app associations");
12809                pw.println("    service [COMP_SPEC]: service client-side state");
12810                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12811                pw.println("    all: dump all activities");
12812                pw.println("    top: dump the top activity");
12813                pw.println("    write: write all pending state to storage");
12814                pw.println("    track-associations: enable association tracking");
12815                pw.println("    untrack-associations: disable and clear association tracking");
12816                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12817                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12818                pw.println("    a partial substring in a component name, a");
12819                pw.println("    hex object identifier.");
12820                pw.println("  -a: include all available server state.");
12821                pw.println("  -c: include client state.");
12822                pw.println("  -p: limit output to given package.");
12823                return;
12824            } else {
12825                pw.println("Unknown argument: " + opt + "; use -h for help");
12826            }
12827        }
12828
12829        long origId = Binder.clearCallingIdentity();
12830        boolean more = false;
12831        // Is the caller requesting to dump a particular piece of data?
12832        if (opti < args.length) {
12833            String cmd = args[opti];
12834            opti++;
12835            if ("activities".equals(cmd) || "a".equals(cmd)) {
12836                synchronized (this) {
12837                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12838                }
12839            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12840                synchronized (this) {
12841                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
12842                }
12843            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12844                String[] newArgs;
12845                String name;
12846                if (opti >= args.length) {
12847                    name = null;
12848                    newArgs = EMPTY_STRING_ARRAY;
12849                } else {
12850                    dumpPackage = args[opti];
12851                    opti++;
12852                    newArgs = new String[args.length - opti];
12853                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12854                            args.length - opti);
12855                }
12856                synchronized (this) {
12857                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
12858                }
12859            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12860                String[] newArgs;
12861                String name;
12862                if (opti >= args.length) {
12863                    name = null;
12864                    newArgs = EMPTY_STRING_ARRAY;
12865                } else {
12866                    dumpPackage = args[opti];
12867                    opti++;
12868                    newArgs = new String[args.length - opti];
12869                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12870                            args.length - opti);
12871                }
12872                synchronized (this) {
12873                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
12874                }
12875            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12876                String[] newArgs;
12877                String name;
12878                if (opti >= args.length) {
12879                    name = null;
12880                    newArgs = EMPTY_STRING_ARRAY;
12881                } else {
12882                    dumpPackage = args[opti];
12883                    opti++;
12884                    newArgs = new String[args.length - opti];
12885                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12886                            args.length - opti);
12887                }
12888                synchronized (this) {
12889                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
12890                }
12891            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12892                synchronized (this) {
12893                    dumpOomLocked(fd, pw, args, opti, true);
12894                }
12895            } else if ("provider".equals(cmd)) {
12896                String[] newArgs;
12897                String name;
12898                if (opti >= args.length) {
12899                    name = null;
12900                    newArgs = EMPTY_STRING_ARRAY;
12901                } else {
12902                    name = args[opti];
12903                    opti++;
12904                    newArgs = new String[args.length - opti];
12905                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12906                }
12907                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12908                    pw.println("No providers match: " + name);
12909                    pw.println("Use -h for help.");
12910                }
12911            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12912                synchronized (this) {
12913                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12914                }
12915            } else if ("service".equals(cmd)) {
12916                String[] newArgs;
12917                String name;
12918                if (opti >= args.length) {
12919                    name = null;
12920                    newArgs = EMPTY_STRING_ARRAY;
12921                } else {
12922                    name = args[opti];
12923                    opti++;
12924                    newArgs = new String[args.length - opti];
12925                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12926                            args.length - opti);
12927                }
12928                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12929                    pw.println("No services match: " + name);
12930                    pw.println("Use -h for help.");
12931                }
12932            } else if ("package".equals(cmd)) {
12933                String[] newArgs;
12934                if (opti >= args.length) {
12935                    pw.println("package: no package name specified");
12936                    pw.println("Use -h for help.");
12937                } else {
12938                    dumpPackage = args[opti];
12939                    opti++;
12940                    newArgs = new String[args.length - opti];
12941                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12942                            args.length - opti);
12943                    args = newArgs;
12944                    opti = 0;
12945                    more = true;
12946                }
12947            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
12948                synchronized (this) {
12949                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12950                }
12951            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12952                synchronized (this) {
12953                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12954                }
12955            } else if ("write".equals(cmd)) {
12956                mTaskPersister.flush();
12957                pw.println("All tasks persisted.");
12958                return;
12959            } else if ("track-associations".equals(cmd)) {
12960                synchronized (this) {
12961                    if (!mTrackingAssociations) {
12962                        mTrackingAssociations = true;
12963                        pw.println("Association tracking started.");
12964                    } else {
12965                        pw.println("Association tracking already enabled.");
12966                    }
12967                }
12968                return;
12969            } else if ("untrack-associations".equals(cmd)) {
12970                synchronized (this) {
12971                    if (mTrackingAssociations) {
12972                        mTrackingAssociations = false;
12973                        mAssociations.clear();
12974                        pw.println("Association tracking stopped.");
12975                    } else {
12976                        pw.println("Association tracking not running.");
12977                    }
12978                }
12979                return;
12980            } else {
12981                // Dumping a single activity?
12982                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12983                    pw.println("Bad activity command, or no activities match: " + cmd);
12984                    pw.println("Use -h for help.");
12985                }
12986            }
12987            if (!more) {
12988                Binder.restoreCallingIdentity(origId);
12989                return;
12990            }
12991        }
12992
12993        // No piece of data specified, dump everything.
12994        synchronized (this) {
12995            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12996            pw.println();
12997            if (dumpAll) {
12998                pw.println("-------------------------------------------------------------------------------");
12999            }
13000            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13001            pw.println();
13002            if (dumpAll) {
13003                pw.println("-------------------------------------------------------------------------------");
13004            }
13005            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13006            pw.println();
13007            if (dumpAll) {
13008                pw.println("-------------------------------------------------------------------------------");
13009            }
13010            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13011            pw.println();
13012            if (dumpAll) {
13013                pw.println("-------------------------------------------------------------------------------");
13014            }
13015            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13016            pw.println();
13017            if (dumpAll) {
13018                pw.println("-------------------------------------------------------------------------------");
13019            }
13020            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13021            if (mAssociations.size() > 0) {
13022                pw.println();
13023                if (dumpAll) {
13024                    pw.println("-------------------------------------------------------------------------------");
13025                }
13026                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13027            }
13028            pw.println();
13029            if (dumpAll) {
13030                pw.println("-------------------------------------------------------------------------------");
13031            }
13032            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13033        }
13034        Binder.restoreCallingIdentity(origId);
13035    }
13036
13037    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13038            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13039        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13040
13041        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13042                dumpPackage);
13043        boolean needSep = printedAnything;
13044
13045        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13046                dumpPackage, needSep, "  mFocusedActivity: ");
13047        if (printed) {
13048            printedAnything = true;
13049            needSep = false;
13050        }
13051
13052        if (dumpPackage == null) {
13053            if (needSep) {
13054                pw.println();
13055            }
13056            needSep = true;
13057            printedAnything = true;
13058            mStackSupervisor.dump(pw, "  ");
13059        }
13060
13061        if (!printedAnything) {
13062            pw.println("  (nothing)");
13063        }
13064    }
13065
13066    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13067            int opti, boolean dumpAll, String dumpPackage) {
13068        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13069
13070        boolean printedAnything = false;
13071
13072        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13073            boolean printedHeader = false;
13074
13075            final int N = mRecentTasks.size();
13076            for (int i=0; i<N; i++) {
13077                TaskRecord tr = mRecentTasks.get(i);
13078                if (dumpPackage != null) {
13079                    if (tr.realActivity == null ||
13080                            !dumpPackage.equals(tr.realActivity)) {
13081                        continue;
13082                    }
13083                }
13084                if (!printedHeader) {
13085                    pw.println("  Recent tasks:");
13086                    printedHeader = true;
13087                    printedAnything = true;
13088                }
13089                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13090                        pw.println(tr);
13091                if (dumpAll) {
13092                    mRecentTasks.get(i).dump(pw, "    ");
13093                }
13094            }
13095        }
13096
13097        if (!printedAnything) {
13098            pw.println("  (nothing)");
13099        }
13100    }
13101
13102    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13103            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13104        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13105
13106        int dumpUid = 0;
13107        if (dumpPackage != null) {
13108            IPackageManager pm = AppGlobals.getPackageManager();
13109            try {
13110                dumpUid = pm.getPackageUid(dumpPackage, 0);
13111            } catch (RemoteException e) {
13112            }
13113        }
13114
13115        boolean printedAnything = false;
13116
13117        final long now = SystemClock.uptimeMillis();
13118
13119        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13120            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13121                    = mAssociations.valueAt(i1);
13122            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13123                SparseArray<ArrayMap<String, Association>> sourceUids
13124                        = targetComponents.valueAt(i2);
13125                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13126                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13127                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13128                        Association ass = sourceProcesses.valueAt(i4);
13129                        if (dumpPackage != null) {
13130                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13131                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13132                                continue;
13133                            }
13134                        }
13135                        printedAnything = true;
13136                        pw.print("  ");
13137                        pw.print(ass.mTargetProcess);
13138                        pw.print("/");
13139                        UserHandle.formatUid(pw, ass.mTargetUid);
13140                        pw.print(" <- ");
13141                        pw.print(ass.mSourceProcess);
13142                        pw.print("/");
13143                        UserHandle.formatUid(pw, ass.mSourceUid);
13144                        pw.println();
13145                        pw.print("    via ");
13146                        pw.print(ass.mTargetComponent.flattenToShortString());
13147                        pw.println();
13148                        pw.print("    ");
13149                        long dur = ass.mTime;
13150                        if (ass.mNesting > 0) {
13151                            dur += now - ass.mStartTime;
13152                        }
13153                        TimeUtils.formatDuration(dur, pw);
13154                        pw.print(" (");
13155                        pw.print(ass.mCount);
13156                        pw.println(" times)");
13157                        if (ass.mNesting > 0) {
13158                            pw.print("    ");
13159                            pw.print(" Currently active: ");
13160                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13161                            pw.println();
13162                        }
13163                    }
13164                }
13165            }
13166
13167        }
13168
13169        if (!printedAnything) {
13170            pw.println("  (nothing)");
13171        }
13172    }
13173
13174    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13175            int opti, boolean dumpAll, String dumpPackage) {
13176        boolean needSep = false;
13177        boolean printedAnything = false;
13178        int numPers = 0;
13179
13180        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13181
13182        if (dumpAll) {
13183            final int NP = mProcessNames.getMap().size();
13184            for (int ip=0; ip<NP; ip++) {
13185                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13186                final int NA = procs.size();
13187                for (int ia=0; ia<NA; ia++) {
13188                    ProcessRecord r = procs.valueAt(ia);
13189                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13190                        continue;
13191                    }
13192                    if (!needSep) {
13193                        pw.println("  All known processes:");
13194                        needSep = true;
13195                        printedAnything = true;
13196                    }
13197                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13198                        pw.print(" UID "); pw.print(procs.keyAt(ia));
13199                        pw.print(" "); pw.println(r);
13200                    r.dump(pw, "    ");
13201                    if (r.persistent) {
13202                        numPers++;
13203                    }
13204                }
13205            }
13206        }
13207
13208        if (mIsolatedProcesses.size() > 0) {
13209            boolean printed = false;
13210            for (int i=0; i<mIsolatedProcesses.size(); i++) {
13211                ProcessRecord r = mIsolatedProcesses.valueAt(i);
13212                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13213                    continue;
13214                }
13215                if (!printed) {
13216                    if (needSep) {
13217                        pw.println();
13218                    }
13219                    pw.println("  Isolated process list (sorted by uid):");
13220                    printedAnything = true;
13221                    printed = true;
13222                    needSep = true;
13223                }
13224                pw.println(String.format("%sIsolated #%2d: %s",
13225                        "    ", i, r.toString()));
13226            }
13227        }
13228
13229        if (mActiveUids.size() > 0) {
13230            if (needSep) {
13231                pw.println();
13232            }
13233            pw.println("  UID states:");
13234            for (int i=0; i<mActiveUids.size(); i++) {
13235                UidRecord uidRec = mActiveUids.valueAt(i);
13236                pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13237                pw.print(": "); pw.println(uidRec);
13238            }
13239            needSep = true;
13240            printedAnything = true;
13241        }
13242
13243        if (mLruProcesses.size() > 0) {
13244            if (needSep) {
13245                pw.println();
13246            }
13247            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
13248                    pw.print(" total, non-act at ");
13249                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13250                    pw.print(", non-svc at ");
13251                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13252                    pw.println("):");
13253            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
13254            needSep = true;
13255            printedAnything = true;
13256        }
13257
13258        if (dumpAll || dumpPackage != null) {
13259            synchronized (mPidsSelfLocked) {
13260                boolean printed = false;
13261                for (int i=0; i<mPidsSelfLocked.size(); i++) {
13262                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
13263                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13264                        continue;
13265                    }
13266                    if (!printed) {
13267                        if (needSep) pw.println();
13268                        needSep = true;
13269                        pw.println("  PID mappings:");
13270                        printed = true;
13271                        printedAnything = true;
13272                    }
13273                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
13274                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
13275                }
13276            }
13277        }
13278
13279        if (mForegroundProcesses.size() > 0) {
13280            synchronized (mPidsSelfLocked) {
13281                boolean printed = false;
13282                for (int i=0; i<mForegroundProcesses.size(); i++) {
13283                    ProcessRecord r = mPidsSelfLocked.get(
13284                            mForegroundProcesses.valueAt(i).pid);
13285                    if (dumpPackage != null && (r == null
13286                            || !r.pkgList.containsKey(dumpPackage))) {
13287                        continue;
13288                    }
13289                    if (!printed) {
13290                        if (needSep) pw.println();
13291                        needSep = true;
13292                        pw.println("  Foreground Processes:");
13293                        printed = true;
13294                        printedAnything = true;
13295                    }
13296                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
13297                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
13298                }
13299            }
13300        }
13301
13302        if (mPersistentStartingProcesses.size() > 0) {
13303            if (needSep) pw.println();
13304            needSep = true;
13305            printedAnything = true;
13306            pw.println("  Persisent processes that are starting:");
13307            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
13308                    "Starting Norm", "Restarting PERS", dumpPackage);
13309        }
13310
13311        if (mRemovedProcesses.size() > 0) {
13312            if (needSep) pw.println();
13313            needSep = true;
13314            printedAnything = true;
13315            pw.println("  Processes that are being removed:");
13316            dumpProcessList(pw, this, mRemovedProcesses, "    ",
13317                    "Removed Norm", "Removed PERS", dumpPackage);
13318        }
13319
13320        if (mProcessesOnHold.size() > 0) {
13321            if (needSep) pw.println();
13322            needSep = true;
13323            printedAnything = true;
13324            pw.println("  Processes that are on old until the system is ready:");
13325            dumpProcessList(pw, this, mProcessesOnHold, "    ",
13326                    "OnHold Norm", "OnHold PERS", dumpPackage);
13327        }
13328
13329        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
13330
13331        if (mProcessCrashTimes.getMap().size() > 0) {
13332            boolean printed = false;
13333            long now = SystemClock.uptimeMillis();
13334            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
13335            final int NP = pmap.size();
13336            for (int ip=0; ip<NP; ip++) {
13337                String pname = pmap.keyAt(ip);
13338                SparseArray<Long> uids = pmap.valueAt(ip);
13339                final int N = uids.size();
13340                for (int i=0; i<N; i++) {
13341                    int puid = uids.keyAt(i);
13342                    ProcessRecord r = mProcessNames.get(pname, puid);
13343                    if (dumpPackage != null && (r == null
13344                            || !r.pkgList.containsKey(dumpPackage))) {
13345                        continue;
13346                    }
13347                    if (!printed) {
13348                        if (needSep) pw.println();
13349                        needSep = true;
13350                        pw.println("  Time since processes crashed:");
13351                        printed = true;
13352                        printedAnything = true;
13353                    }
13354                    pw.print("    Process "); pw.print(pname);
13355                            pw.print(" uid "); pw.print(puid);
13356                            pw.print(": last crashed ");
13357                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
13358                            pw.println(" ago");
13359                }
13360            }
13361        }
13362
13363        if (mBadProcesses.getMap().size() > 0) {
13364            boolean printed = false;
13365            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
13366            final int NP = pmap.size();
13367            for (int ip=0; ip<NP; ip++) {
13368                String pname = pmap.keyAt(ip);
13369                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
13370                final int N = uids.size();
13371                for (int i=0; i<N; i++) {
13372                    int puid = uids.keyAt(i);
13373                    ProcessRecord r = mProcessNames.get(pname, puid);
13374                    if (dumpPackage != null && (r == null
13375                            || !r.pkgList.containsKey(dumpPackage))) {
13376                        continue;
13377                    }
13378                    if (!printed) {
13379                        if (needSep) pw.println();
13380                        needSep = true;
13381                        pw.println("  Bad processes:");
13382                        printedAnything = true;
13383                    }
13384                    BadProcessInfo info = uids.valueAt(i);
13385                    pw.print("    Bad process "); pw.print(pname);
13386                            pw.print(" uid "); pw.print(puid);
13387                            pw.print(": crashed at time "); pw.println(info.time);
13388                    if (info.shortMsg != null) {
13389                        pw.print("      Short msg: "); pw.println(info.shortMsg);
13390                    }
13391                    if (info.longMsg != null) {
13392                        pw.print("      Long msg: "); pw.println(info.longMsg);
13393                    }
13394                    if (info.stack != null) {
13395                        pw.println("      Stack:");
13396                        int lastPos = 0;
13397                        for (int pos=0; pos<info.stack.length(); pos++) {
13398                            if (info.stack.charAt(pos) == '\n') {
13399                                pw.print("        ");
13400                                pw.write(info.stack, lastPos, pos-lastPos);
13401                                pw.println();
13402                                lastPos = pos+1;
13403                            }
13404                        }
13405                        if (lastPos < info.stack.length()) {
13406                            pw.print("        ");
13407                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
13408                            pw.println();
13409                        }
13410                    }
13411                }
13412            }
13413        }
13414
13415        if (dumpPackage == null) {
13416            pw.println();
13417            needSep = false;
13418            pw.println("  mStartedUsers:");
13419            for (int i=0; i<mStartedUsers.size(); i++) {
13420                UserState uss = mStartedUsers.valueAt(i);
13421                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
13422                        pw.print(": "); uss.dump("", pw);
13423            }
13424            pw.print("  mStartedUserArray: [");
13425            for (int i=0; i<mStartedUserArray.length; i++) {
13426                if (i > 0) pw.print(", ");
13427                pw.print(mStartedUserArray[i]);
13428            }
13429            pw.println("]");
13430            pw.print("  mUserLru: [");
13431            for (int i=0; i<mUserLru.size(); i++) {
13432                if (i > 0) pw.print(", ");
13433                pw.print(mUserLru.get(i));
13434            }
13435            pw.println("]");
13436            if (dumpAll) {
13437                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
13438            }
13439            synchronized (mUserProfileGroupIdsSelfLocked) {
13440                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
13441                    pw.println("  mUserProfileGroupIds:");
13442                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
13443                        pw.print("    User #");
13444                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
13445                        pw.print(" -> profile #");
13446                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
13447                    }
13448                }
13449            }
13450        }
13451        if (mHomeProcess != null && (dumpPackage == null
13452                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13453            if (needSep) {
13454                pw.println();
13455                needSep = false;
13456            }
13457            pw.println("  mHomeProcess: " + mHomeProcess);
13458        }
13459        if (mPreviousProcess != null && (dumpPackage == null
13460                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13461            if (needSep) {
13462                pw.println();
13463                needSep = false;
13464            }
13465            pw.println("  mPreviousProcess: " + mPreviousProcess);
13466        }
13467        if (dumpAll) {
13468            StringBuilder sb = new StringBuilder(128);
13469            sb.append("  mPreviousProcessVisibleTime: ");
13470            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13471            pw.println(sb);
13472        }
13473        if (mHeavyWeightProcess != null && (dumpPackage == null
13474                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13475            if (needSep) {
13476                pw.println();
13477                needSep = false;
13478            }
13479            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13480        }
13481        if (dumpPackage == null) {
13482            pw.println("  mConfiguration: " + mConfiguration);
13483        }
13484        if (dumpAll) {
13485            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13486            if (mCompatModePackages.getPackages().size() > 0) {
13487                boolean printed = false;
13488                for (Map.Entry<String, Integer> entry
13489                        : mCompatModePackages.getPackages().entrySet()) {
13490                    String pkg = entry.getKey();
13491                    int mode = entry.getValue();
13492                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
13493                        continue;
13494                    }
13495                    if (!printed) {
13496                        pw.println("  mScreenCompatPackages:");
13497                        printed = true;
13498                    }
13499                    pw.print("    "); pw.print(pkg); pw.print(": ");
13500                            pw.print(mode); pw.println();
13501                }
13502            }
13503        }
13504        if (dumpPackage == null) {
13505            pw.println("  mWakefulness="
13506                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
13507            pw.println("  mSleepTokens=" + mSleepTokens);
13508            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
13509                    + lockScreenShownToString());
13510            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
13511            if (mRunningVoice != null) {
13512                pw.println("  mRunningVoice=" + mRunningVoice);
13513                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
13514            }
13515        }
13516        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
13517                || mOrigWaitForDebugger) {
13518            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
13519                    || dumpPackage.equals(mOrigDebugApp)) {
13520                if (needSep) {
13521                    pw.println();
13522                    needSep = false;
13523                }
13524                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
13525                        + " mDebugTransient=" + mDebugTransient
13526                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
13527            }
13528        }
13529        if (mCurAppTimeTracker != null) {
13530            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
13531        }
13532        if (mMemWatchProcesses.getMap().size() > 0) {
13533            pw.println("  Mem watch processes:");
13534            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
13535                    = mMemWatchProcesses.getMap();
13536            for (int i=0; i<procs.size(); i++) {
13537                final String proc = procs.keyAt(i);
13538                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
13539                for (int j=0; j<uids.size(); j++) {
13540                    if (needSep) {
13541                        pw.println();
13542                        needSep = false;
13543                    }
13544                    StringBuilder sb = new StringBuilder();
13545                    sb.append("    ").append(proc).append('/');
13546                    UserHandle.formatUid(sb, uids.keyAt(j));
13547                    Pair<Long, String> val = uids.valueAt(j);
13548                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
13549                    if (val.second != null) {
13550                        sb.append(", report to ").append(val.second);
13551                    }
13552                    pw.println(sb.toString());
13553                }
13554            }
13555            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
13556            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
13557            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
13558                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
13559        }
13560        if (mOpenGlTraceApp != null) {
13561            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
13562                if (needSep) {
13563                    pw.println();
13564                    needSep = false;
13565                }
13566                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
13567            }
13568        }
13569        if (mTrackAllocationApp != null) {
13570            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
13571                if (needSep) {
13572                    pw.println();
13573                    needSep = false;
13574                }
13575                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
13576            }
13577        }
13578        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
13579                || mProfileFd != null) {
13580            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13581                if (needSep) {
13582                    pw.println();
13583                    needSep = false;
13584                }
13585                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13586                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13587                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13588                        + mAutoStopProfiler);
13589                pw.println("  mProfileType=" + mProfileType);
13590            }
13591        }
13592        if (dumpPackage == null) {
13593            if (mAlwaysFinishActivities || mController != null) {
13594                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
13595                        + " mController=" + mController);
13596            }
13597            if (dumpAll) {
13598                pw.println("  Total persistent processes: " + numPers);
13599                pw.println("  mProcessesReady=" + mProcessesReady
13600                        + " mSystemReady=" + mSystemReady
13601                        + " mBooted=" + mBooted
13602                        + " mFactoryTest=" + mFactoryTest);
13603                pw.println("  mBooting=" + mBooting
13604                        + " mCallFinishBooting=" + mCallFinishBooting
13605                        + " mBootAnimationComplete=" + mBootAnimationComplete);
13606                pw.print("  mLastPowerCheckRealtime=");
13607                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13608                        pw.println("");
13609                pw.print("  mLastPowerCheckUptime=");
13610                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13611                        pw.println("");
13612                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13613                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13614                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13615                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
13616                        + " (" + mLruProcesses.size() + " total)"
13617                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13618                        + " mNumServiceProcs=" + mNumServiceProcs
13619                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13620                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
13621                        + " mLastMemoryLevel" + mLastMemoryLevel
13622                        + " mLastNumProcesses" + mLastNumProcesses);
13623                long now = SystemClock.uptimeMillis();
13624                pw.print("  mLastIdleTime=");
13625                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
13626                        pw.print(" mLowRamSinceLastIdle=");
13627                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13628                        pw.println();
13629            }
13630        }
13631
13632        if (!printedAnything) {
13633            pw.println("  (nothing)");
13634        }
13635    }
13636
13637    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13638            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13639        if (mProcessesToGc.size() > 0) {
13640            boolean printed = false;
13641            long now = SystemClock.uptimeMillis();
13642            for (int i=0; i<mProcessesToGc.size(); i++) {
13643                ProcessRecord proc = mProcessesToGc.get(i);
13644                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13645                    continue;
13646                }
13647                if (!printed) {
13648                    if (needSep) pw.println();
13649                    needSep = true;
13650                    pw.println("  Processes that are waiting to GC:");
13651                    printed = true;
13652                }
13653                pw.print("    Process "); pw.println(proc);
13654                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13655                        pw.print(", last gced=");
13656                        pw.print(now-proc.lastRequestedGc);
13657                        pw.print(" ms ago, last lowMem=");
13658                        pw.print(now-proc.lastLowMemory);
13659                        pw.println(" ms ago");
13660
13661            }
13662        }
13663        return needSep;
13664    }
13665
13666    void printOomLevel(PrintWriter pw, String name, int adj) {
13667        pw.print("    ");
13668        if (adj >= 0) {
13669            pw.print(' ');
13670            if (adj < 10) pw.print(' ');
13671        } else {
13672            if (adj > -10) pw.print(' ');
13673        }
13674        pw.print(adj);
13675        pw.print(": ");
13676        pw.print(name);
13677        pw.print(" (");
13678        pw.print(mProcessList.getMemLevel(adj)/1024);
13679        pw.println(" kB)");
13680    }
13681
13682    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13683            int opti, boolean dumpAll) {
13684        boolean needSep = false;
13685
13686        if (mLruProcesses.size() > 0) {
13687            if (needSep) pw.println();
13688            needSep = true;
13689            pw.println("  OOM levels:");
13690            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13691            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13692            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13693            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13694            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13695            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13696            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13697            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13698            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13699            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13700            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13701            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13702            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13703            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13704
13705            if (needSep) pw.println();
13706            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13707                    pw.print(" total, non-act at ");
13708                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13709                    pw.print(", non-svc at ");
13710                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13711                    pw.println("):");
13712            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13713            needSep = true;
13714        }
13715
13716        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13717
13718        pw.println();
13719        pw.println("  mHomeProcess: " + mHomeProcess);
13720        pw.println("  mPreviousProcess: " + mPreviousProcess);
13721        if (mHeavyWeightProcess != null) {
13722            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13723        }
13724
13725        return true;
13726    }
13727
13728    /**
13729     * There are three ways to call this:
13730     *  - no provider specified: dump all the providers
13731     *  - a flattened component name that matched an existing provider was specified as the
13732     *    first arg: dump that one provider
13733     *  - the first arg isn't the flattened component name of an existing provider:
13734     *    dump all providers whose component contains the first arg as a substring
13735     */
13736    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13737            int opti, boolean dumpAll) {
13738        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13739    }
13740
13741    static class ItemMatcher {
13742        ArrayList<ComponentName> components;
13743        ArrayList<String> strings;
13744        ArrayList<Integer> objects;
13745        boolean all;
13746
13747        ItemMatcher() {
13748            all = true;
13749        }
13750
13751        void build(String name) {
13752            ComponentName componentName = ComponentName.unflattenFromString(name);
13753            if (componentName != null) {
13754                if (components == null) {
13755                    components = new ArrayList<ComponentName>();
13756                }
13757                components.add(componentName);
13758                all = false;
13759            } else {
13760                int objectId = 0;
13761                // Not a '/' separated full component name; maybe an object ID?
13762                try {
13763                    objectId = Integer.parseInt(name, 16);
13764                    if (objects == null) {
13765                        objects = new ArrayList<Integer>();
13766                    }
13767                    objects.add(objectId);
13768                    all = false;
13769                } catch (RuntimeException e) {
13770                    // Not an integer; just do string match.
13771                    if (strings == null) {
13772                        strings = new ArrayList<String>();
13773                    }
13774                    strings.add(name);
13775                    all = false;
13776                }
13777            }
13778        }
13779
13780        int build(String[] args, int opti) {
13781            for (; opti<args.length; opti++) {
13782                String name = args[opti];
13783                if ("--".equals(name)) {
13784                    return opti+1;
13785                }
13786                build(name);
13787            }
13788            return opti;
13789        }
13790
13791        boolean match(Object object, ComponentName comp) {
13792            if (all) {
13793                return true;
13794            }
13795            if (components != null) {
13796                for (int i=0; i<components.size(); i++) {
13797                    if (components.get(i).equals(comp)) {
13798                        return true;
13799                    }
13800                }
13801            }
13802            if (objects != null) {
13803                for (int i=0; i<objects.size(); i++) {
13804                    if (System.identityHashCode(object) == objects.get(i)) {
13805                        return true;
13806                    }
13807                }
13808            }
13809            if (strings != null) {
13810                String flat = comp.flattenToString();
13811                for (int i=0; i<strings.size(); i++) {
13812                    if (flat.contains(strings.get(i))) {
13813                        return true;
13814                    }
13815                }
13816            }
13817            return false;
13818        }
13819    }
13820
13821    /**
13822     * There are three things that cmd can be:
13823     *  - a flattened component name that matches an existing activity
13824     *  - the cmd arg isn't the flattened component name of an existing activity:
13825     *    dump all activity whose component contains the cmd as a substring
13826     *  - A hex number of the ActivityRecord object instance.
13827     */
13828    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13829            int opti, boolean dumpAll) {
13830        ArrayList<ActivityRecord> activities;
13831
13832        synchronized (this) {
13833            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13834        }
13835
13836        if (activities.size() <= 0) {
13837            return false;
13838        }
13839
13840        String[] newArgs = new String[args.length - opti];
13841        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13842
13843        TaskRecord lastTask = null;
13844        boolean needSep = false;
13845        for (int i=activities.size()-1; i>=0; i--) {
13846            ActivityRecord r = activities.get(i);
13847            if (needSep) {
13848                pw.println();
13849            }
13850            needSep = true;
13851            synchronized (this) {
13852                if (lastTask != r.task) {
13853                    lastTask = r.task;
13854                    pw.print("TASK "); pw.print(lastTask.affinity);
13855                            pw.print(" id="); pw.println(lastTask.taskId);
13856                    if (dumpAll) {
13857                        lastTask.dump(pw, "  ");
13858                    }
13859                }
13860            }
13861            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13862        }
13863        return true;
13864    }
13865
13866    /**
13867     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13868     * there is a thread associated with the activity.
13869     */
13870    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13871            final ActivityRecord r, String[] args, boolean dumpAll) {
13872        String innerPrefix = prefix + "  ";
13873        synchronized (this) {
13874            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13875                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13876                    pw.print(" pid=");
13877                    if (r.app != null) pw.println(r.app.pid);
13878                    else pw.println("(not running)");
13879            if (dumpAll) {
13880                r.dump(pw, innerPrefix);
13881            }
13882        }
13883        if (r.app != null && r.app.thread != null) {
13884            // flush anything that is already in the PrintWriter since the thread is going
13885            // to write to the file descriptor directly
13886            pw.flush();
13887            try {
13888                TransferPipe tp = new TransferPipe();
13889                try {
13890                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13891                            r.appToken, innerPrefix, args);
13892                    tp.go(fd);
13893                } finally {
13894                    tp.kill();
13895                }
13896            } catch (IOException e) {
13897                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13898            } catch (RemoteException e) {
13899                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13900            }
13901        }
13902    }
13903
13904    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13905            int opti, boolean dumpAll, String dumpPackage) {
13906        boolean needSep = false;
13907        boolean onlyHistory = false;
13908        boolean printedAnything = false;
13909
13910        if ("history".equals(dumpPackage)) {
13911            if (opti < args.length && "-s".equals(args[opti])) {
13912                dumpAll = false;
13913            }
13914            onlyHistory = true;
13915            dumpPackage = null;
13916        }
13917
13918        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13919        if (!onlyHistory && dumpAll) {
13920            if (mRegisteredReceivers.size() > 0) {
13921                boolean printed = false;
13922                Iterator it = mRegisteredReceivers.values().iterator();
13923                while (it.hasNext()) {
13924                    ReceiverList r = (ReceiverList)it.next();
13925                    if (dumpPackage != null && (r.app == null ||
13926                            !dumpPackage.equals(r.app.info.packageName))) {
13927                        continue;
13928                    }
13929                    if (!printed) {
13930                        pw.println("  Registered Receivers:");
13931                        needSep = true;
13932                        printed = true;
13933                        printedAnything = true;
13934                    }
13935                    pw.print("  * "); pw.println(r);
13936                    r.dump(pw, "    ");
13937                }
13938            }
13939
13940            if (mReceiverResolver.dump(pw, needSep ?
13941                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13942                    "    ", dumpPackage, false, false)) {
13943                needSep = true;
13944                printedAnything = true;
13945            }
13946        }
13947
13948        for (BroadcastQueue q : mBroadcastQueues) {
13949            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13950            printedAnything |= needSep;
13951        }
13952
13953        needSep = true;
13954
13955        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13956            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13957                if (needSep) {
13958                    pw.println();
13959                }
13960                needSep = true;
13961                printedAnything = true;
13962                pw.print("  Sticky broadcasts for user ");
13963                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13964                StringBuilder sb = new StringBuilder(128);
13965                for (Map.Entry<String, ArrayList<Intent>> ent
13966                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13967                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13968                    if (dumpAll) {
13969                        pw.println(":");
13970                        ArrayList<Intent> intents = ent.getValue();
13971                        final int N = intents.size();
13972                        for (int i=0; i<N; i++) {
13973                            sb.setLength(0);
13974                            sb.append("    Intent: ");
13975                            intents.get(i).toShortString(sb, false, true, false, false);
13976                            pw.println(sb.toString());
13977                            Bundle bundle = intents.get(i).getExtras();
13978                            if (bundle != null) {
13979                                pw.print("      ");
13980                                pw.println(bundle.toString());
13981                            }
13982                        }
13983                    } else {
13984                        pw.println("");
13985                    }
13986                }
13987            }
13988        }
13989
13990        if (!onlyHistory && dumpAll) {
13991            pw.println();
13992            for (BroadcastQueue queue : mBroadcastQueues) {
13993                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13994                        + queue.mBroadcastsScheduled);
13995            }
13996            pw.println("  mHandler:");
13997            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13998            needSep = true;
13999            printedAnything = true;
14000        }
14001
14002        if (!printedAnything) {
14003            pw.println("  (nothing)");
14004        }
14005    }
14006
14007    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14008            int opti, boolean dumpAll, String dumpPackage) {
14009        boolean needSep;
14010        boolean printedAnything = false;
14011
14012        ItemMatcher matcher = new ItemMatcher();
14013        matcher.build(args, opti);
14014
14015        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14016
14017        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14018        printedAnything |= needSep;
14019
14020        if (mLaunchingProviders.size() > 0) {
14021            boolean printed = false;
14022            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14023                ContentProviderRecord r = mLaunchingProviders.get(i);
14024                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14025                    continue;
14026                }
14027                if (!printed) {
14028                    if (needSep) pw.println();
14029                    needSep = true;
14030                    pw.println("  Launching content providers:");
14031                    printed = true;
14032                    printedAnything = true;
14033                }
14034                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14035                        pw.println(r);
14036            }
14037        }
14038
14039        if (mGrantedUriPermissions.size() > 0) {
14040            boolean printed = false;
14041            int dumpUid = -2;
14042            if (dumpPackage != null) {
14043                try {
14044                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
14045                } catch (NameNotFoundException e) {
14046                    dumpUid = -1;
14047                }
14048            }
14049            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14050                int uid = mGrantedUriPermissions.keyAt(i);
14051                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14052                    continue;
14053                }
14054                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14055                if (!printed) {
14056                    if (needSep) pw.println();
14057                    needSep = true;
14058                    pw.println("  Granted Uri Permissions:");
14059                    printed = true;
14060                    printedAnything = true;
14061                }
14062                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14063                for (UriPermission perm : perms.values()) {
14064                    pw.print("    "); pw.println(perm);
14065                    if (dumpAll) {
14066                        perm.dump(pw, "      ");
14067                    }
14068                }
14069            }
14070        }
14071
14072        if (!printedAnything) {
14073            pw.println("  (nothing)");
14074        }
14075    }
14076
14077    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14078            int opti, boolean dumpAll, String dumpPackage) {
14079        boolean printed = false;
14080
14081        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14082
14083        if (mIntentSenderRecords.size() > 0) {
14084            Iterator<WeakReference<PendingIntentRecord>> it
14085                    = mIntentSenderRecords.values().iterator();
14086            while (it.hasNext()) {
14087                WeakReference<PendingIntentRecord> ref = it.next();
14088                PendingIntentRecord rec = ref != null ? ref.get(): null;
14089                if (dumpPackage != null && (rec == null
14090                        || !dumpPackage.equals(rec.key.packageName))) {
14091                    continue;
14092                }
14093                printed = true;
14094                if (rec != null) {
14095                    pw.print("  * "); pw.println(rec);
14096                    if (dumpAll) {
14097                        rec.dump(pw, "    ");
14098                    }
14099                } else {
14100                    pw.print("  * "); pw.println(ref);
14101                }
14102            }
14103        }
14104
14105        if (!printed) {
14106            pw.println("  (nothing)");
14107        }
14108    }
14109
14110    private static final int dumpProcessList(PrintWriter pw,
14111            ActivityManagerService service, List list,
14112            String prefix, String normalLabel, String persistentLabel,
14113            String dumpPackage) {
14114        int numPers = 0;
14115        final int N = list.size()-1;
14116        for (int i=N; i>=0; i--) {
14117            ProcessRecord r = (ProcessRecord)list.get(i);
14118            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14119                continue;
14120            }
14121            pw.println(String.format("%s%s #%2d: %s",
14122                    prefix, (r.persistent ? persistentLabel : normalLabel),
14123                    i, r.toString()));
14124            if (r.persistent) {
14125                numPers++;
14126            }
14127        }
14128        return numPers;
14129    }
14130
14131    private static final boolean dumpProcessOomList(PrintWriter pw,
14132            ActivityManagerService service, List<ProcessRecord> origList,
14133            String prefix, String normalLabel, String persistentLabel,
14134            boolean inclDetails, String dumpPackage) {
14135
14136        ArrayList<Pair<ProcessRecord, Integer>> list
14137                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14138        for (int i=0; i<origList.size(); i++) {
14139            ProcessRecord r = origList.get(i);
14140            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14141                continue;
14142            }
14143            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14144        }
14145
14146        if (list.size() <= 0) {
14147            return false;
14148        }
14149
14150        Comparator<Pair<ProcessRecord, Integer>> comparator
14151                = new Comparator<Pair<ProcessRecord, Integer>>() {
14152            @Override
14153            public int compare(Pair<ProcessRecord, Integer> object1,
14154                    Pair<ProcessRecord, Integer> object2) {
14155                if (object1.first.setAdj != object2.first.setAdj) {
14156                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14157                }
14158                if (object1.second.intValue() != object2.second.intValue()) {
14159                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14160                }
14161                return 0;
14162            }
14163        };
14164
14165        Collections.sort(list, comparator);
14166
14167        final long curRealtime = SystemClock.elapsedRealtime();
14168        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14169        final long curUptime = SystemClock.uptimeMillis();
14170        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14171
14172        for (int i=list.size()-1; i>=0; i--) {
14173            ProcessRecord r = list.get(i).first;
14174            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14175            char schedGroup;
14176            switch (r.setSchedGroup) {
14177                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
14178                    schedGroup = 'B';
14179                    break;
14180                case Process.THREAD_GROUP_DEFAULT:
14181                    schedGroup = 'F';
14182                    break;
14183                default:
14184                    schedGroup = '?';
14185                    break;
14186            }
14187            char foreground;
14188            if (r.foregroundActivities) {
14189                foreground = 'A';
14190            } else if (r.foregroundServices) {
14191                foreground = 'S';
14192            } else {
14193                foreground = ' ';
14194            }
14195            String procState = ProcessList.makeProcStateString(r.curProcState);
14196            pw.print(prefix);
14197            pw.print(r.persistent ? persistentLabel : normalLabel);
14198            pw.print(" #");
14199            int num = (origList.size()-1)-list.get(i).second;
14200            if (num < 10) pw.print(' ');
14201            pw.print(num);
14202            pw.print(": ");
14203            pw.print(oomAdj);
14204            pw.print(' ');
14205            pw.print(schedGroup);
14206            pw.print('/');
14207            pw.print(foreground);
14208            pw.print('/');
14209            pw.print(procState);
14210            pw.print(" trm:");
14211            if (r.trimMemoryLevel < 10) pw.print(' ');
14212            pw.print(r.trimMemoryLevel);
14213            pw.print(' ');
14214            pw.print(r.toShortString());
14215            pw.print(" (");
14216            pw.print(r.adjType);
14217            pw.println(')');
14218            if (r.adjSource != null || r.adjTarget != null) {
14219                pw.print(prefix);
14220                pw.print("    ");
14221                if (r.adjTarget instanceof ComponentName) {
14222                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14223                } else if (r.adjTarget != null) {
14224                    pw.print(r.adjTarget.toString());
14225                } else {
14226                    pw.print("{null}");
14227                }
14228                pw.print("<=");
14229                if (r.adjSource instanceof ProcessRecord) {
14230                    pw.print("Proc{");
14231                    pw.print(((ProcessRecord)r.adjSource).toShortString());
14232                    pw.println("}");
14233                } else if (r.adjSource != null) {
14234                    pw.println(r.adjSource.toString());
14235                } else {
14236                    pw.println("{null}");
14237                }
14238            }
14239            if (inclDetails) {
14240                pw.print(prefix);
14241                pw.print("    ");
14242                pw.print("oom: max="); pw.print(r.maxAdj);
14243                pw.print(" curRaw="); pw.print(r.curRawAdj);
14244                pw.print(" setRaw="); pw.print(r.setRawAdj);
14245                pw.print(" cur="); pw.print(r.curAdj);
14246                pw.print(" set="); pw.println(r.setAdj);
14247                pw.print(prefix);
14248                pw.print("    ");
14249                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14250                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14251                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14252                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14253                pw.println();
14254                pw.print(prefix);
14255                pw.print("    ");
14256                pw.print("cached="); pw.print(r.cached);
14257                pw.print(" empty="); pw.print(r.empty);
14258                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14259
14260                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14261                    if (r.lastWakeTime != 0) {
14262                        long wtime;
14263                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14264                        synchronized (stats) {
14265                            wtime = stats.getProcessWakeTime(r.info.uid,
14266                                    r.pid, curRealtime);
14267                        }
14268                        long timeUsed = wtime - r.lastWakeTime;
14269                        pw.print(prefix);
14270                        pw.print("    ");
14271                        pw.print("keep awake over ");
14272                        TimeUtils.formatDuration(realtimeSince, pw);
14273                        pw.print(" used ");
14274                        TimeUtils.formatDuration(timeUsed, pw);
14275                        pw.print(" (");
14276                        pw.print((timeUsed*100)/realtimeSince);
14277                        pw.println("%)");
14278                    }
14279                    if (r.lastCpuTime != 0) {
14280                        long timeUsed = r.curCpuTime - r.lastCpuTime;
14281                        pw.print(prefix);
14282                        pw.print("    ");
14283                        pw.print("run cpu over ");
14284                        TimeUtils.formatDuration(uptimeSince, pw);
14285                        pw.print(" used ");
14286                        TimeUtils.formatDuration(timeUsed, pw);
14287                        pw.print(" (");
14288                        pw.print((timeUsed*100)/uptimeSince);
14289                        pw.println("%)");
14290                    }
14291                }
14292            }
14293        }
14294        return true;
14295    }
14296
14297    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14298            String[] args) {
14299        ArrayList<ProcessRecord> procs;
14300        synchronized (this) {
14301            if (args != null && args.length > start
14302                    && args[start].charAt(0) != '-') {
14303                procs = new ArrayList<ProcessRecord>();
14304                int pid = -1;
14305                try {
14306                    pid = Integer.parseInt(args[start]);
14307                } catch (NumberFormatException e) {
14308                }
14309                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14310                    ProcessRecord proc = mLruProcesses.get(i);
14311                    if (proc.pid == pid) {
14312                        procs.add(proc);
14313                    } else if (allPkgs && proc.pkgList != null
14314                            && proc.pkgList.containsKey(args[start])) {
14315                        procs.add(proc);
14316                    } else if (proc.processName.equals(args[start])) {
14317                        procs.add(proc);
14318                    }
14319                }
14320                if (procs.size() <= 0) {
14321                    return null;
14322                }
14323            } else {
14324                procs = new ArrayList<ProcessRecord>(mLruProcesses);
14325            }
14326        }
14327        return procs;
14328    }
14329
14330    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
14331            PrintWriter pw, String[] args) {
14332        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14333        if (procs == null) {
14334            pw.println("No process found for: " + args[0]);
14335            return;
14336        }
14337
14338        long uptime = SystemClock.uptimeMillis();
14339        long realtime = SystemClock.elapsedRealtime();
14340        pw.println("Applications Graphics Acceleration Info:");
14341        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14342
14343        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14344            ProcessRecord r = procs.get(i);
14345            if (r.thread != null) {
14346                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
14347                pw.flush();
14348                try {
14349                    TransferPipe tp = new TransferPipe();
14350                    try {
14351                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
14352                        tp.go(fd);
14353                    } finally {
14354                        tp.kill();
14355                    }
14356                } catch (IOException e) {
14357                    pw.println("Failure while dumping the app: " + r);
14358                    pw.flush();
14359                } catch (RemoteException e) {
14360                    pw.println("Got a RemoteException while dumping the app " + r);
14361                    pw.flush();
14362                }
14363            }
14364        }
14365    }
14366
14367    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
14368        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14369        if (procs == null) {
14370            pw.println("No process found for: " + args[0]);
14371            return;
14372        }
14373
14374        pw.println("Applications Database Info:");
14375
14376        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14377            ProcessRecord r = procs.get(i);
14378            if (r.thread != null) {
14379                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
14380                pw.flush();
14381                try {
14382                    TransferPipe tp = new TransferPipe();
14383                    try {
14384                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
14385                        tp.go(fd);
14386                    } finally {
14387                        tp.kill();
14388                    }
14389                } catch (IOException e) {
14390                    pw.println("Failure while dumping the app: " + r);
14391                    pw.flush();
14392                } catch (RemoteException e) {
14393                    pw.println("Got a RemoteException while dumping the app " + r);
14394                    pw.flush();
14395                }
14396            }
14397        }
14398    }
14399
14400    final static class MemItem {
14401        final boolean isProc;
14402        final String label;
14403        final String shortLabel;
14404        final long pss;
14405        final int id;
14406        final boolean hasActivities;
14407        ArrayList<MemItem> subitems;
14408
14409        public MemItem(String _label, String _shortLabel, long _pss, int _id,
14410                boolean _hasActivities) {
14411            isProc = true;
14412            label = _label;
14413            shortLabel = _shortLabel;
14414            pss = _pss;
14415            id = _id;
14416            hasActivities = _hasActivities;
14417        }
14418
14419        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
14420            isProc = false;
14421            label = _label;
14422            shortLabel = _shortLabel;
14423            pss = _pss;
14424            id = _id;
14425            hasActivities = false;
14426        }
14427    }
14428
14429    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
14430            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
14431        if (sort && !isCompact) {
14432            Collections.sort(items, new Comparator<MemItem>() {
14433                @Override
14434                public int compare(MemItem lhs, MemItem rhs) {
14435                    if (lhs.pss < rhs.pss) {
14436                        return 1;
14437                    } else if (lhs.pss > rhs.pss) {
14438                        return -1;
14439                    }
14440                    return 0;
14441                }
14442            });
14443        }
14444
14445        for (int i=0; i<items.size(); i++) {
14446            MemItem mi = items.get(i);
14447            if (!isCompact) {
14448                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
14449            } else if (mi.isProc) {
14450                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
14451                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
14452                pw.println(mi.hasActivities ? ",a" : ",e");
14453            } else {
14454                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
14455                pw.println(mi.pss);
14456            }
14457            if (mi.subitems != null) {
14458                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
14459                        true, isCompact);
14460            }
14461        }
14462    }
14463
14464    // These are in KB.
14465    static final long[] DUMP_MEM_BUCKETS = new long[] {
14466        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
14467        120*1024, 160*1024, 200*1024,
14468        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
14469        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
14470    };
14471
14472    static final void appendMemBucket(StringBuilder out, long memKB, String label,
14473            boolean stackLike) {
14474        int start = label.lastIndexOf('.');
14475        if (start >= 0) start++;
14476        else start = 0;
14477        int end = label.length();
14478        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
14479            if (DUMP_MEM_BUCKETS[i] >= memKB) {
14480                long bucket = DUMP_MEM_BUCKETS[i]/1024;
14481                out.append(bucket);
14482                out.append(stackLike ? "MB." : "MB ");
14483                out.append(label, start, end);
14484                return;
14485            }
14486        }
14487        out.append(memKB/1024);
14488        out.append(stackLike ? "MB." : "MB ");
14489        out.append(label, start, end);
14490    }
14491
14492    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
14493            ProcessList.NATIVE_ADJ,
14494            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
14495            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
14496            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
14497            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
14498            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
14499            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
14500    };
14501    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
14502            "Native",
14503            "System", "Persistent", "Persistent Service", "Foreground",
14504            "Visible", "Perceptible",
14505            "Heavy Weight", "Backup",
14506            "A Services", "Home",
14507            "Previous", "B Services", "Cached"
14508    };
14509    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
14510            "native",
14511            "sys", "pers", "persvc", "fore",
14512            "vis", "percept",
14513            "heavy", "backup",
14514            "servicea", "home",
14515            "prev", "serviceb", "cached"
14516    };
14517
14518    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
14519            long realtime, boolean isCheckinRequest, boolean isCompact) {
14520        if (isCheckinRequest || isCompact) {
14521            // short checkin version
14522            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
14523        } else {
14524            pw.println("Applications Memory Usage (kB):");
14525            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14526        }
14527    }
14528
14529    private static final int KSM_SHARED = 0;
14530    private static final int KSM_SHARING = 1;
14531    private static final int KSM_UNSHARED = 2;
14532    private static final int KSM_VOLATILE = 3;
14533
14534    private final long[] getKsmInfo() {
14535        long[] longOut = new long[4];
14536        final int[] SINGLE_LONG_FORMAT = new int[] {
14537            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14538        };
14539        long[] longTmp = new long[1];
14540        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14541                SINGLE_LONG_FORMAT, null, longTmp, null);
14542        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14543        longTmp[0] = 0;
14544        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14545                SINGLE_LONG_FORMAT, null, longTmp, null);
14546        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14547        longTmp[0] = 0;
14548        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14549                SINGLE_LONG_FORMAT, null, longTmp, null);
14550        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14551        longTmp[0] = 0;
14552        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14553                SINGLE_LONG_FORMAT, null, longTmp, null);
14554        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14555        return longOut;
14556    }
14557
14558    final void dumpApplicationMemoryUsage(FileDescriptor fd,
14559            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
14560        boolean dumpDetails = false;
14561        boolean dumpFullDetails = false;
14562        boolean dumpDalvik = false;
14563        boolean dumpSummaryOnly = false;
14564        boolean oomOnly = false;
14565        boolean isCompact = false;
14566        boolean localOnly = false;
14567        boolean packages = false;
14568
14569        int opti = 0;
14570        while (opti < args.length) {
14571            String opt = args[opti];
14572            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14573                break;
14574            }
14575            opti++;
14576            if ("-a".equals(opt)) {
14577                dumpDetails = true;
14578                dumpFullDetails = true;
14579                dumpDalvik = true;
14580            } else if ("-d".equals(opt)) {
14581                dumpDalvik = true;
14582            } else if ("-c".equals(opt)) {
14583                isCompact = true;
14584            } else if ("-s".equals(opt)) {
14585                dumpDetails = true;
14586                dumpSummaryOnly = true;
14587            } else if ("--oom".equals(opt)) {
14588                oomOnly = true;
14589            } else if ("--local".equals(opt)) {
14590                localOnly = true;
14591            } else if ("--package".equals(opt)) {
14592                packages = true;
14593            } else if ("-h".equals(opt)) {
14594                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
14595                pw.println("  -a: include all available information for each process.");
14596                pw.println("  -d: include dalvik details.");
14597                pw.println("  -c: dump in a compact machine-parseable representation.");
14598                pw.println("  -s: dump only summary of application memory usage.");
14599                pw.println("  --oom: only show processes organized by oom adj.");
14600                pw.println("  --local: only collect details locally, don't call process.");
14601                pw.println("  --package: interpret process arg as package, dumping all");
14602                pw.println("             processes that have loaded that package.");
14603                pw.println("If [process] is specified it can be the name or ");
14604                pw.println("pid of a specific process to dump.");
14605                return;
14606            } else {
14607                pw.println("Unknown argument: " + opt + "; use -h for help");
14608            }
14609        }
14610
14611        final boolean isCheckinRequest = scanArgs(args, "--checkin");
14612        long uptime = SystemClock.uptimeMillis();
14613        long realtime = SystemClock.elapsedRealtime();
14614        final long[] tmpLong = new long[1];
14615
14616        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
14617        if (procs == null) {
14618            // No Java processes.  Maybe they want to print a native process.
14619            if (args != null && args.length > opti
14620                    && args[opti].charAt(0) != '-') {
14621                ArrayList<ProcessCpuTracker.Stats> nativeProcs
14622                        = new ArrayList<ProcessCpuTracker.Stats>();
14623                updateCpuStatsNow();
14624                int findPid = -1;
14625                try {
14626                    findPid = Integer.parseInt(args[opti]);
14627                } catch (NumberFormatException e) {
14628                }
14629                synchronized (mProcessCpuTracker) {
14630                    final int N = mProcessCpuTracker.countStats();
14631                    for (int i=0; i<N; i++) {
14632                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14633                        if (st.pid == findPid || (st.baseName != null
14634                                && st.baseName.equals(args[opti]))) {
14635                            nativeProcs.add(st);
14636                        }
14637                    }
14638                }
14639                if (nativeProcs.size() > 0) {
14640                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14641                            isCompact);
14642                    Debug.MemoryInfo mi = null;
14643                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14644                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14645                        final int pid = r.pid;
14646                        if (!isCheckinRequest && dumpDetails) {
14647                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14648                        }
14649                        if (mi == null) {
14650                            mi = new Debug.MemoryInfo();
14651                        }
14652                        if (dumpDetails || (!brief && !oomOnly)) {
14653                            Debug.getMemoryInfo(pid, mi);
14654                        } else {
14655                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14656                            mi.dalvikPrivateDirty = (int)tmpLong[0];
14657                        }
14658                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14659                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14660                        if (isCheckinRequest) {
14661                            pw.println();
14662                        }
14663                    }
14664                    return;
14665                }
14666            }
14667            pw.println("No process found for: " + args[opti]);
14668            return;
14669        }
14670
14671        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14672            dumpDetails = true;
14673        }
14674
14675        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14676
14677        String[] innerArgs = new String[args.length-opti];
14678        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14679
14680        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14681        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14682        long nativePss = 0;
14683        long dalvikPss = 0;
14684        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
14685                EmptyArray.LONG;
14686        long otherPss = 0;
14687        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14688
14689        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14690        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14691                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14692
14693        long totalPss = 0;
14694        long cachedPss = 0;
14695
14696        Debug.MemoryInfo mi = null;
14697        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14698            final ProcessRecord r = procs.get(i);
14699            final IApplicationThread thread;
14700            final int pid;
14701            final int oomAdj;
14702            final boolean hasActivities;
14703            synchronized (this) {
14704                thread = r.thread;
14705                pid = r.pid;
14706                oomAdj = r.getSetAdjWithServices();
14707                hasActivities = r.activities.size() > 0;
14708            }
14709            if (thread != null) {
14710                if (!isCheckinRequest && dumpDetails) {
14711                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14712                }
14713                if (mi == null) {
14714                    mi = new Debug.MemoryInfo();
14715                }
14716                if (dumpDetails || (!brief && !oomOnly)) {
14717                    Debug.getMemoryInfo(pid, mi);
14718                } else {
14719                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14720                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14721                }
14722                if (dumpDetails) {
14723                    if (localOnly) {
14724                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14725                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
14726                        if (isCheckinRequest) {
14727                            pw.println();
14728                        }
14729                    } else {
14730                        try {
14731                            pw.flush();
14732                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14733                                    dumpDalvik, dumpSummaryOnly, innerArgs);
14734                        } catch (RemoteException e) {
14735                            if (!isCheckinRequest) {
14736                                pw.println("Got RemoteException!");
14737                                pw.flush();
14738                            }
14739                        }
14740                    }
14741                }
14742
14743                final long myTotalPss = mi.getTotalPss();
14744                final long myTotalUss = mi.getTotalUss();
14745
14746                synchronized (this) {
14747                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14748                        // Record this for posterity if the process has been stable.
14749                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14750                    }
14751                }
14752
14753                if (!isCheckinRequest && mi != null) {
14754                    totalPss += myTotalPss;
14755                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14756                            (hasActivities ? " / activities)" : ")"),
14757                            r.processName, myTotalPss, pid, hasActivities);
14758                    procMems.add(pssItem);
14759                    procMemsMap.put(pid, pssItem);
14760
14761                    nativePss += mi.nativePss;
14762                    dalvikPss += mi.dalvikPss;
14763                    for (int j=0; j<dalvikSubitemPss.length; j++) {
14764                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
14765                    }
14766                    otherPss += mi.otherPss;
14767                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14768                        long mem = mi.getOtherPss(j);
14769                        miscPss[j] += mem;
14770                        otherPss -= mem;
14771                    }
14772
14773                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14774                        cachedPss += myTotalPss;
14775                    }
14776
14777                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14778                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14779                                || oomIndex == (oomPss.length-1)) {
14780                            oomPss[oomIndex] += myTotalPss;
14781                            if (oomProcs[oomIndex] == null) {
14782                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14783                            }
14784                            oomProcs[oomIndex].add(pssItem);
14785                            break;
14786                        }
14787                    }
14788                }
14789            }
14790        }
14791
14792        long nativeProcTotalPss = 0;
14793
14794        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14795            // If we are showing aggregations, also look for native processes to
14796            // include so that our aggregations are more accurate.
14797            updateCpuStatsNow();
14798            mi = null;
14799            synchronized (mProcessCpuTracker) {
14800                final int N = mProcessCpuTracker.countStats();
14801                for (int i=0; i<N; i++) {
14802                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14803                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14804                        if (mi == null) {
14805                            mi = new Debug.MemoryInfo();
14806                        }
14807                        if (!brief && !oomOnly) {
14808                            Debug.getMemoryInfo(st.pid, mi);
14809                        } else {
14810                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14811                            mi.nativePrivateDirty = (int)tmpLong[0];
14812                        }
14813
14814                        final long myTotalPss = mi.getTotalPss();
14815                        totalPss += myTotalPss;
14816                        nativeProcTotalPss += myTotalPss;
14817
14818                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14819                                st.name, myTotalPss, st.pid, false);
14820                        procMems.add(pssItem);
14821
14822                        nativePss += mi.nativePss;
14823                        dalvikPss += mi.dalvikPss;
14824                        for (int j=0; j<dalvikSubitemPss.length; j++) {
14825                            dalvikSubitemPss[j] += mi.getOtherPss(
14826                                    Debug.MemoryInfo.NUM_OTHER_STATS + j);
14827                        }
14828                        otherPss += mi.otherPss;
14829                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14830                            long mem = mi.getOtherPss(j);
14831                            miscPss[j] += mem;
14832                            otherPss -= mem;
14833                        }
14834                        oomPss[0] += myTotalPss;
14835                        if (oomProcs[0] == null) {
14836                            oomProcs[0] = new ArrayList<MemItem>();
14837                        }
14838                        oomProcs[0].add(pssItem);
14839                    }
14840                }
14841            }
14842
14843            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14844
14845            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14846            final MemItem dalvikItem = new MemItem("Dalvik", "Dalvik", dalvikPss, -2);
14847            if (dalvikSubitemPss.length > 0) {
14848                dalvikItem.subitems = new ArrayList<MemItem>();
14849                for (int j=0; j<dalvikSubitemPss.length; j++) {
14850                    final String name = Debug.MemoryInfo.getOtherLabel(
14851                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
14852                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j], j));
14853                }
14854            }
14855            catMems.add(dalvikItem);
14856            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14857            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14858                String label = Debug.MemoryInfo.getOtherLabel(j);
14859                catMems.add(new MemItem(label, label, miscPss[j], j));
14860            }
14861
14862            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14863            for (int j=0; j<oomPss.length; j++) {
14864                if (oomPss[j] != 0) {
14865                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14866                            : DUMP_MEM_OOM_LABEL[j];
14867                    MemItem item = new MemItem(label, label, oomPss[j],
14868                            DUMP_MEM_OOM_ADJ[j]);
14869                    item.subitems = oomProcs[j];
14870                    oomMems.add(item);
14871                }
14872            }
14873
14874            if (!brief && !oomOnly && !isCompact) {
14875                pw.println();
14876                pw.println("Total PSS by process:");
14877                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14878                pw.println();
14879            }
14880            if (!isCompact) {
14881                pw.println("Total PSS by OOM adjustment:");
14882            }
14883            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14884            if (!brief && !oomOnly) {
14885                PrintWriter out = categoryPw != null ? categoryPw : pw;
14886                if (!isCompact) {
14887                    out.println();
14888                    out.println("Total PSS by category:");
14889                }
14890                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14891            }
14892            if (!isCompact) {
14893                pw.println();
14894            }
14895            MemInfoReader memInfo = new MemInfoReader();
14896            memInfo.readMemInfo();
14897            if (nativeProcTotalPss > 0) {
14898                synchronized (this) {
14899                    final long cachedKb = memInfo.getCachedSizeKb();
14900                    final long freeKb = memInfo.getFreeSizeKb();
14901                    final long zramKb = memInfo.getZramTotalSizeKb();
14902                    final long kernelKb = memInfo.getKernelUsedSizeKb();
14903                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
14904                            kernelKb*1024, nativeProcTotalPss*1024);
14905                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
14906                            nativeProcTotalPss);
14907                }
14908            }
14909            if (!brief) {
14910                if (!isCompact) {
14911                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14912                    pw.print(" kB (status ");
14913                    switch (mLastMemoryLevel) {
14914                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14915                            pw.println("normal)");
14916                            break;
14917                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14918                            pw.println("moderate)");
14919                            break;
14920                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14921                            pw.println("low)");
14922                            break;
14923                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14924                            pw.println("critical)");
14925                            break;
14926                        default:
14927                            pw.print(mLastMemoryLevel);
14928                            pw.println(")");
14929                            break;
14930                    }
14931                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14932                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14933                            pw.print(cachedPss); pw.print(" cached pss + ");
14934                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14935                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14936                } else {
14937                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14938                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14939                            + memInfo.getFreeSizeKb()); pw.print(",");
14940                    pw.println(totalPss - cachedPss);
14941                }
14942            }
14943            if (!isCompact) {
14944                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14945                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14946                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14947                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14948                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14949                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14950                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14951            }
14952            if (!brief) {
14953                if (memInfo.getZramTotalSizeKb() != 0) {
14954                    if (!isCompact) {
14955                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14956                                pw.print(" kB physical used for ");
14957                                pw.print(memInfo.getSwapTotalSizeKb()
14958                                        - memInfo.getSwapFreeSizeKb());
14959                                pw.print(" kB in swap (");
14960                                pw.print(memInfo.getSwapTotalSizeKb());
14961                                pw.println(" kB total swap)");
14962                    } else {
14963                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14964                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14965                                pw.println(memInfo.getSwapFreeSizeKb());
14966                    }
14967                }
14968                final long[] ksm = getKsmInfo();
14969                if (!isCompact) {
14970                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14971                            || ksm[KSM_VOLATILE] != 0) {
14972                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14973                                pw.print(" kB saved from shared ");
14974                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14975                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14976                                pw.print(" kB unshared; ");
14977                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14978                    }
14979                    pw.print("   Tuning: ");
14980                    pw.print(ActivityManager.staticGetMemoryClass());
14981                    pw.print(" (large ");
14982                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14983                    pw.print("), oom ");
14984                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14985                    pw.print(" kB");
14986                    pw.print(", restore limit ");
14987                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14988                    pw.print(" kB");
14989                    if (ActivityManager.isLowRamDeviceStatic()) {
14990                        pw.print(" (low-ram)");
14991                    }
14992                    if (ActivityManager.isHighEndGfx()) {
14993                        pw.print(" (high-end-gfx)");
14994                    }
14995                    pw.println();
14996                } else {
14997                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14998                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14999                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15000                    pw.print("tuning,");
15001                    pw.print(ActivityManager.staticGetMemoryClass());
15002                    pw.print(',');
15003                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15004                    pw.print(',');
15005                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15006                    if (ActivityManager.isLowRamDeviceStatic()) {
15007                        pw.print(",low-ram");
15008                    }
15009                    if (ActivityManager.isHighEndGfx()) {
15010                        pw.print(",high-end-gfx");
15011                    }
15012                    pw.println();
15013                }
15014            }
15015        }
15016    }
15017
15018    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15019            long memtrack, String name) {
15020        sb.append("  ");
15021        sb.append(ProcessList.makeOomAdjString(oomAdj));
15022        sb.append(' ');
15023        sb.append(ProcessList.makeProcStateString(procState));
15024        sb.append(' ');
15025        ProcessList.appendRamKb(sb, pss);
15026        sb.append(" kB: ");
15027        sb.append(name);
15028        if (memtrack > 0) {
15029            sb.append(" (");
15030            sb.append(memtrack);
15031            sb.append(" kB memtrack)");
15032        }
15033    }
15034
15035    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15036        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15037        sb.append(" (pid ");
15038        sb.append(mi.pid);
15039        sb.append(") ");
15040        sb.append(mi.adjType);
15041        sb.append('\n');
15042        if (mi.adjReason != null) {
15043            sb.append("                      ");
15044            sb.append(mi.adjReason);
15045            sb.append('\n');
15046        }
15047    }
15048
15049    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15050        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15051        for (int i=0, N=memInfos.size(); i<N; i++) {
15052            ProcessMemInfo mi = memInfos.get(i);
15053            infoMap.put(mi.pid, mi);
15054        }
15055        updateCpuStatsNow();
15056        long[] memtrackTmp = new long[1];
15057        synchronized (mProcessCpuTracker) {
15058            final int N = mProcessCpuTracker.countStats();
15059            for (int i=0; i<N; i++) {
15060                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15061                if (st.vsize > 0) {
15062                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
15063                    if (pss > 0) {
15064                        if (infoMap.indexOfKey(st.pid) < 0) {
15065                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15066                                    ProcessList.NATIVE_ADJ, -1, "native", null);
15067                            mi.pss = pss;
15068                            mi.memtrack = memtrackTmp[0];
15069                            memInfos.add(mi);
15070                        }
15071                    }
15072                }
15073            }
15074        }
15075
15076        long totalPss = 0;
15077        long totalMemtrack = 0;
15078        for (int i=0, N=memInfos.size(); i<N; i++) {
15079            ProcessMemInfo mi = memInfos.get(i);
15080            if (mi.pss == 0) {
15081                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15082                mi.memtrack = memtrackTmp[0];
15083            }
15084            totalPss += mi.pss;
15085            totalMemtrack += mi.memtrack;
15086        }
15087        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15088            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15089                if (lhs.oomAdj != rhs.oomAdj) {
15090                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15091                }
15092                if (lhs.pss != rhs.pss) {
15093                    return lhs.pss < rhs.pss ? 1 : -1;
15094                }
15095                return 0;
15096            }
15097        });
15098
15099        StringBuilder tag = new StringBuilder(128);
15100        StringBuilder stack = new StringBuilder(128);
15101        tag.append("Low on memory -- ");
15102        appendMemBucket(tag, totalPss, "total", false);
15103        appendMemBucket(stack, totalPss, "total", true);
15104
15105        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15106        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15107        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15108
15109        boolean firstLine = true;
15110        int lastOomAdj = Integer.MIN_VALUE;
15111        long extraNativeRam = 0;
15112        long extraNativeMemtrack = 0;
15113        long cachedPss = 0;
15114        for (int i=0, N=memInfos.size(); i<N; i++) {
15115            ProcessMemInfo mi = memInfos.get(i);
15116
15117            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15118                cachedPss += mi.pss;
15119            }
15120
15121            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15122                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15123                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15124                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15125                if (lastOomAdj != mi.oomAdj) {
15126                    lastOomAdj = mi.oomAdj;
15127                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15128                        tag.append(" / ");
15129                    }
15130                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15131                        if (firstLine) {
15132                            stack.append(":");
15133                            firstLine = false;
15134                        }
15135                        stack.append("\n\t at ");
15136                    } else {
15137                        stack.append("$");
15138                    }
15139                } else {
15140                    tag.append(" ");
15141                    stack.append("$");
15142                }
15143                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15144                    appendMemBucket(tag, mi.pss, mi.name, false);
15145                }
15146                appendMemBucket(stack, mi.pss, mi.name, true);
15147                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15148                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15149                    stack.append("(");
15150                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15151                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15152                            stack.append(DUMP_MEM_OOM_LABEL[k]);
15153                            stack.append(":");
15154                            stack.append(DUMP_MEM_OOM_ADJ[k]);
15155                        }
15156                    }
15157                    stack.append(")");
15158                }
15159            }
15160
15161            appendMemInfo(fullNativeBuilder, mi);
15162            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15163                // The short form only has native processes that are >= 512K.
15164                if (mi.pss >= 512) {
15165                    appendMemInfo(shortNativeBuilder, mi);
15166                } else {
15167                    extraNativeRam += mi.pss;
15168                    extraNativeMemtrack += mi.memtrack;
15169                }
15170            } else {
15171                // Short form has all other details, but if we have collected RAM
15172                // from smaller native processes let's dump a summary of that.
15173                if (extraNativeRam > 0) {
15174                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15175                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15176                    shortNativeBuilder.append('\n');
15177                    extraNativeRam = 0;
15178                }
15179                appendMemInfo(fullJavaBuilder, mi);
15180            }
15181        }
15182
15183        fullJavaBuilder.append("           ");
15184        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15185        fullJavaBuilder.append(" kB: TOTAL");
15186        if (totalMemtrack > 0) {
15187            fullJavaBuilder.append(" (");
15188            fullJavaBuilder.append(totalMemtrack);
15189            fullJavaBuilder.append(" kB memtrack)");
15190        } else {
15191        }
15192        fullJavaBuilder.append("\n");
15193
15194        MemInfoReader memInfo = new MemInfoReader();
15195        memInfo.readMemInfo();
15196        final long[] infos = memInfo.getRawInfo();
15197
15198        StringBuilder memInfoBuilder = new StringBuilder(1024);
15199        Debug.getMemInfo(infos);
15200        memInfoBuilder.append("  MemInfo: ");
15201        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
15202        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
15203        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
15204        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
15205        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
15206        memInfoBuilder.append("           ");
15207        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
15208        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
15209        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
15210        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
15211        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15212            memInfoBuilder.append("  ZRAM: ");
15213            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
15214            memInfoBuilder.append(" kB RAM, ");
15215            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
15216            memInfoBuilder.append(" kB swap total, ");
15217            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
15218            memInfoBuilder.append(" kB swap free\n");
15219        }
15220        final long[] ksm = getKsmInfo();
15221        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15222                || ksm[KSM_VOLATILE] != 0) {
15223            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
15224            memInfoBuilder.append(" kB saved from shared ");
15225            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
15226            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
15227            memInfoBuilder.append(" kB unshared; ");
15228            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
15229        }
15230        memInfoBuilder.append("  Free RAM: ");
15231        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
15232                + memInfo.getFreeSizeKb());
15233        memInfoBuilder.append(" kB\n");
15234        memInfoBuilder.append("  Used RAM: ");
15235        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
15236        memInfoBuilder.append(" kB\n");
15237        memInfoBuilder.append("  Lost RAM: ");
15238        memInfoBuilder.append(memInfo.getTotalSizeKb()
15239                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15240                - memInfo.getKernelUsedSizeKb());
15241        memInfoBuilder.append(" kB\n");
15242        Slog.i(TAG, "Low on memory:");
15243        Slog.i(TAG, shortNativeBuilder.toString());
15244        Slog.i(TAG, fullJavaBuilder.toString());
15245        Slog.i(TAG, memInfoBuilder.toString());
15246
15247        StringBuilder dropBuilder = new StringBuilder(1024);
15248        /*
15249        StringWriter oomSw = new StringWriter();
15250        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
15251        StringWriter catSw = new StringWriter();
15252        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15253        String[] emptyArgs = new String[] { };
15254        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
15255        oomPw.flush();
15256        String oomString = oomSw.toString();
15257        */
15258        dropBuilder.append("Low on memory:");
15259        dropBuilder.append(stack);
15260        dropBuilder.append('\n');
15261        dropBuilder.append(fullNativeBuilder);
15262        dropBuilder.append(fullJavaBuilder);
15263        dropBuilder.append('\n');
15264        dropBuilder.append(memInfoBuilder);
15265        dropBuilder.append('\n');
15266        /*
15267        dropBuilder.append(oomString);
15268        dropBuilder.append('\n');
15269        */
15270        StringWriter catSw = new StringWriter();
15271        synchronized (ActivityManagerService.this) {
15272            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15273            String[] emptyArgs = new String[] { };
15274            catPw.println();
15275            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
15276            catPw.println();
15277            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
15278                    false, false, null);
15279            catPw.println();
15280            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
15281            catPw.flush();
15282        }
15283        dropBuilder.append(catSw.toString());
15284        addErrorToDropBox("lowmem", null, "system_server", null,
15285                null, tag.toString(), dropBuilder.toString(), null, null);
15286        //Slog.i(TAG, "Sent to dropbox:");
15287        //Slog.i(TAG, dropBuilder.toString());
15288        synchronized (ActivityManagerService.this) {
15289            long now = SystemClock.uptimeMillis();
15290            if (mLastMemUsageReportTime < now) {
15291                mLastMemUsageReportTime = now;
15292            }
15293        }
15294    }
15295
15296    /**
15297     * Searches array of arguments for the specified string
15298     * @param args array of argument strings
15299     * @param value value to search for
15300     * @return true if the value is contained in the array
15301     */
15302    private static boolean scanArgs(String[] args, String value) {
15303        if (args != null) {
15304            for (String arg : args) {
15305                if (value.equals(arg)) {
15306                    return true;
15307                }
15308            }
15309        }
15310        return false;
15311    }
15312
15313    private final boolean removeDyingProviderLocked(ProcessRecord proc,
15314            ContentProviderRecord cpr, boolean always) {
15315        final boolean inLaunching = mLaunchingProviders.contains(cpr);
15316
15317        if (!inLaunching || always) {
15318            synchronized (cpr) {
15319                cpr.launchingApp = null;
15320                cpr.notifyAll();
15321            }
15322            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
15323            String names[] = cpr.info.authority.split(";");
15324            for (int j = 0; j < names.length; j++) {
15325                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
15326            }
15327        }
15328
15329        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
15330            ContentProviderConnection conn = cpr.connections.get(i);
15331            if (conn.waiting) {
15332                // If this connection is waiting for the provider, then we don't
15333                // need to mess with its process unless we are always removing
15334                // or for some reason the provider is not currently launching.
15335                if (inLaunching && !always) {
15336                    continue;
15337                }
15338            }
15339            ProcessRecord capp = conn.client;
15340            conn.dead = true;
15341            if (conn.stableCount > 0) {
15342                if (!capp.persistent && capp.thread != null
15343                        && capp.pid != 0
15344                        && capp.pid != MY_PID) {
15345                    capp.kill("depends on provider "
15346                            + cpr.name.flattenToShortString()
15347                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
15348                }
15349            } else if (capp.thread != null && conn.provider.provider != null) {
15350                try {
15351                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
15352                } catch (RemoteException e) {
15353                }
15354                // In the protocol here, we don't expect the client to correctly
15355                // clean up this connection, we'll just remove it.
15356                cpr.connections.remove(i);
15357                if (conn.client.conProviders.remove(conn)) {
15358                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
15359                }
15360            }
15361        }
15362
15363        if (inLaunching && always) {
15364            mLaunchingProviders.remove(cpr);
15365        }
15366        return inLaunching;
15367    }
15368
15369    /**
15370     * Main code for cleaning up a process when it has gone away.  This is
15371     * called both as a result of the process dying, or directly when stopping
15372     * a process when running in single process mode.
15373     *
15374     * @return Returns true if the given process has been restarted, so the
15375     * app that was passed in must remain on the process lists.
15376     */
15377    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
15378            boolean restarting, boolean allowRestart, int index) {
15379        if (index >= 0) {
15380            removeLruProcessLocked(app);
15381            ProcessList.remove(app.pid);
15382        }
15383
15384        mProcessesToGc.remove(app);
15385        mPendingPssProcesses.remove(app);
15386
15387        // Dismiss any open dialogs.
15388        if (app.crashDialog != null && !app.forceCrashReport) {
15389            app.crashDialog.dismiss();
15390            app.crashDialog = null;
15391        }
15392        if (app.anrDialog != null) {
15393            app.anrDialog.dismiss();
15394            app.anrDialog = null;
15395        }
15396        if (app.waitDialog != null) {
15397            app.waitDialog.dismiss();
15398            app.waitDialog = null;
15399        }
15400
15401        app.crashing = false;
15402        app.notResponding = false;
15403
15404        app.resetPackageList(mProcessStats);
15405        app.unlinkDeathRecipient();
15406        app.makeInactive(mProcessStats);
15407        app.waitingToKill = null;
15408        app.forcingToForeground = null;
15409        updateProcessForegroundLocked(app, false, false);
15410        app.foregroundActivities = false;
15411        app.hasShownUi = false;
15412        app.treatLikeActivity = false;
15413        app.hasAboveClient = false;
15414        app.hasClientActivities = false;
15415
15416        mServices.killServicesLocked(app, allowRestart);
15417
15418        boolean restart = false;
15419
15420        // Remove published content providers.
15421        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
15422            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
15423            final boolean always = app.bad || !allowRestart;
15424            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
15425            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
15426                // We left the provider in the launching list, need to
15427                // restart it.
15428                restart = true;
15429            }
15430
15431            cpr.provider = null;
15432            cpr.proc = null;
15433        }
15434        app.pubProviders.clear();
15435
15436        // Take care of any launching providers waiting for this process.
15437        if (checkAppInLaunchingProvidersLocked(app, false)) {
15438            restart = true;
15439        }
15440
15441        // Unregister from connected content providers.
15442        if (!app.conProviders.isEmpty()) {
15443            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
15444                ContentProviderConnection conn = app.conProviders.get(i);
15445                conn.provider.connections.remove(conn);
15446                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
15447                        conn.provider.name);
15448            }
15449            app.conProviders.clear();
15450        }
15451
15452        // At this point there may be remaining entries in mLaunchingProviders
15453        // where we were the only one waiting, so they are no longer of use.
15454        // Look for these and clean up if found.
15455        // XXX Commented out for now.  Trying to figure out a way to reproduce
15456        // the actual situation to identify what is actually going on.
15457        if (false) {
15458            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15459                ContentProviderRecord cpr = mLaunchingProviders.get(i);
15460                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
15461                    synchronized (cpr) {
15462                        cpr.launchingApp = null;
15463                        cpr.notifyAll();
15464                    }
15465                }
15466            }
15467        }
15468
15469        skipCurrentReceiverLocked(app);
15470
15471        // Unregister any receivers.
15472        for (int i = app.receivers.size() - 1; i >= 0; i--) {
15473            removeReceiverLocked(app.receivers.valueAt(i));
15474        }
15475        app.receivers.clear();
15476
15477        // If the app is undergoing backup, tell the backup manager about it
15478        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
15479            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
15480                    + mBackupTarget.appInfo + " died during backup");
15481            try {
15482                IBackupManager bm = IBackupManager.Stub.asInterface(
15483                        ServiceManager.getService(Context.BACKUP_SERVICE));
15484                bm.agentDisconnected(app.info.packageName);
15485            } catch (RemoteException e) {
15486                // can't happen; backup manager is local
15487            }
15488        }
15489
15490        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
15491            ProcessChangeItem item = mPendingProcessChanges.get(i);
15492            if (item.pid == app.pid) {
15493                mPendingProcessChanges.remove(i);
15494                mAvailProcessChanges.add(item);
15495            }
15496        }
15497        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
15498
15499        // If the caller is restarting this app, then leave it in its
15500        // current lists and let the caller take care of it.
15501        if (restarting) {
15502            return false;
15503        }
15504
15505        if (!app.persistent || app.isolated) {
15506            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
15507                    "Removing non-persistent process during cleanup: " + app);
15508            removeProcessNameLocked(app.processName, app.uid);
15509            if (mHeavyWeightProcess == app) {
15510                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
15511                        mHeavyWeightProcess.userId, 0));
15512                mHeavyWeightProcess = null;
15513            }
15514        } else if (!app.removed) {
15515            // This app is persistent, so we need to keep its record around.
15516            // If it is not already on the pending app list, add it there
15517            // and start a new process for it.
15518            if (mPersistentStartingProcesses.indexOf(app) < 0) {
15519                mPersistentStartingProcesses.add(app);
15520                restart = true;
15521            }
15522        }
15523        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
15524                TAG_CLEANUP, "Clean-up removing on hold: " + app);
15525        mProcessesOnHold.remove(app);
15526
15527        if (app == mHomeProcess) {
15528            mHomeProcess = null;
15529        }
15530        if (app == mPreviousProcess) {
15531            mPreviousProcess = null;
15532        }
15533
15534        if (restart && !app.isolated) {
15535            // We have components that still need to be running in the
15536            // process, so re-launch it.
15537            if (index < 0) {
15538                ProcessList.remove(app.pid);
15539            }
15540            addProcessNameLocked(app);
15541            startProcessLocked(app, "restart", app.processName);
15542            return true;
15543        } else if (app.pid > 0 && app.pid != MY_PID) {
15544            // Goodbye!
15545            boolean removed;
15546            synchronized (mPidsSelfLocked) {
15547                mPidsSelfLocked.remove(app.pid);
15548                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
15549            }
15550            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
15551            if (app.isolated) {
15552                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
15553            }
15554            app.setPid(0);
15555        }
15556        return false;
15557    }
15558
15559    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
15560        // Look through the content providers we are waiting to have launched,
15561        // and if any run in this process then either schedule a restart of
15562        // the process or kill the client waiting for it if this process has
15563        // gone bad.
15564        boolean restart = false;
15565        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15566            ContentProviderRecord cpr = mLaunchingProviders.get(i);
15567            if (cpr.launchingApp == app) {
15568                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
15569                    restart = true;
15570                } else {
15571                    removeDyingProviderLocked(app, cpr, true);
15572                }
15573            }
15574        }
15575        return restart;
15576    }
15577
15578    // =========================================================
15579    // SERVICES
15580    // =========================================================
15581
15582    @Override
15583    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
15584            int flags) {
15585        enforceNotIsolatedCaller("getServices");
15586        synchronized (this) {
15587            return mServices.getRunningServiceInfoLocked(maxNum, flags);
15588        }
15589    }
15590
15591    @Override
15592    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
15593        enforceNotIsolatedCaller("getRunningServiceControlPanel");
15594        synchronized (this) {
15595            return mServices.getRunningServiceControlPanelLocked(name);
15596        }
15597    }
15598
15599    @Override
15600    public ComponentName startService(IApplicationThread caller, Intent service,
15601            String resolvedType, String callingPackage, int userId)
15602            throws TransactionTooLargeException {
15603        enforceNotIsolatedCaller("startService");
15604        // Refuse possible leaked file descriptors
15605        if (service != null && service.hasFileDescriptors() == true) {
15606            throw new IllegalArgumentException("File descriptors passed in Intent");
15607        }
15608
15609        if (callingPackage == null) {
15610            throw new IllegalArgumentException("callingPackage cannot be null");
15611        }
15612
15613        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15614                "startService: " + service + " type=" + resolvedType);
15615        synchronized(this) {
15616            final int callingPid = Binder.getCallingPid();
15617            final int callingUid = Binder.getCallingUid();
15618            final long origId = Binder.clearCallingIdentity();
15619            ComponentName res = mServices.startServiceLocked(caller, service,
15620                    resolvedType, callingPid, callingUid, callingPackage, userId);
15621            Binder.restoreCallingIdentity(origId);
15622            return res;
15623        }
15624    }
15625
15626    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
15627            String callingPackage, int userId)
15628            throws TransactionTooLargeException {
15629        synchronized(this) {
15630            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15631                    "startServiceInPackage: " + service + " type=" + resolvedType);
15632            final long origId = Binder.clearCallingIdentity();
15633            ComponentName res = mServices.startServiceLocked(null, service,
15634                    resolvedType, -1, uid, callingPackage, userId);
15635            Binder.restoreCallingIdentity(origId);
15636            return res;
15637        }
15638    }
15639
15640    @Override
15641    public int stopService(IApplicationThread caller, Intent service,
15642            String resolvedType, int userId) {
15643        enforceNotIsolatedCaller("stopService");
15644        // Refuse possible leaked file descriptors
15645        if (service != null && service.hasFileDescriptors() == true) {
15646            throw new IllegalArgumentException("File descriptors passed in Intent");
15647        }
15648
15649        synchronized(this) {
15650            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
15651        }
15652    }
15653
15654    @Override
15655    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
15656        enforceNotIsolatedCaller("peekService");
15657        // Refuse possible leaked file descriptors
15658        if (service != null && service.hasFileDescriptors() == true) {
15659            throw new IllegalArgumentException("File descriptors passed in Intent");
15660        }
15661
15662        if (callingPackage == null) {
15663            throw new IllegalArgumentException("callingPackage cannot be null");
15664        }
15665
15666        synchronized(this) {
15667            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
15668        }
15669    }
15670
15671    @Override
15672    public boolean stopServiceToken(ComponentName className, IBinder token,
15673            int startId) {
15674        synchronized(this) {
15675            return mServices.stopServiceTokenLocked(className, token, startId);
15676        }
15677    }
15678
15679    @Override
15680    public void setServiceForeground(ComponentName className, IBinder token,
15681            int id, Notification notification, boolean removeNotification) {
15682        synchronized(this) {
15683            mServices.setServiceForegroundLocked(className, token, id, notification,
15684                    removeNotification);
15685        }
15686    }
15687
15688    @Override
15689    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15690            boolean requireFull, String name, String callerPackage) {
15691        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15692                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15693    }
15694
15695    int unsafeConvertIncomingUser(int userId) {
15696        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15697                ? mCurrentUserId : userId;
15698    }
15699
15700    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15701            int allowMode, String name, String callerPackage) {
15702        final int callingUserId = UserHandle.getUserId(callingUid);
15703        if (callingUserId == userId) {
15704            return userId;
15705        }
15706
15707        // Note that we may be accessing mCurrentUserId outside of a lock...
15708        // shouldn't be a big deal, if this is being called outside
15709        // of a locked context there is intrinsically a race with
15710        // the value the caller will receive and someone else changing it.
15711        // We assume that USER_CURRENT_OR_SELF will use the current user; later
15712        // we will switch to the calling user if access to the current user fails.
15713        int targetUserId = unsafeConvertIncomingUser(userId);
15714
15715        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15716            final boolean allow;
15717            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15718                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15719                // If the caller has this permission, they always pass go.  And collect $200.
15720                allow = true;
15721            } else if (allowMode == ALLOW_FULL_ONLY) {
15722                // We require full access, sucks to be you.
15723                allow = false;
15724            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15725                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15726                // If the caller does not have either permission, they are always doomed.
15727                allow = false;
15728            } else if (allowMode == ALLOW_NON_FULL) {
15729                // We are blanket allowing non-full access, you lucky caller!
15730                allow = true;
15731            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15732                // We may or may not allow this depending on whether the two users are
15733                // in the same profile.
15734                synchronized (mUserProfileGroupIdsSelfLocked) {
15735                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15736                            UserInfo.NO_PROFILE_GROUP_ID);
15737                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15738                            UserInfo.NO_PROFILE_GROUP_ID);
15739                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15740                            && callingProfile == targetProfile;
15741                }
15742            } else {
15743                throw new IllegalArgumentException("Unknown mode: " + allowMode);
15744            }
15745            if (!allow) {
15746                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15747                    // In this case, they would like to just execute as their
15748                    // owner user instead of failing.
15749                    targetUserId = callingUserId;
15750                } else {
15751                    StringBuilder builder = new StringBuilder(128);
15752                    builder.append("Permission Denial: ");
15753                    builder.append(name);
15754                    if (callerPackage != null) {
15755                        builder.append(" from ");
15756                        builder.append(callerPackage);
15757                    }
15758                    builder.append(" asks to run as user ");
15759                    builder.append(userId);
15760                    builder.append(" but is calling from user ");
15761                    builder.append(UserHandle.getUserId(callingUid));
15762                    builder.append("; this requires ");
15763                    builder.append(INTERACT_ACROSS_USERS_FULL);
15764                    if (allowMode != ALLOW_FULL_ONLY) {
15765                        builder.append(" or ");
15766                        builder.append(INTERACT_ACROSS_USERS);
15767                    }
15768                    String msg = builder.toString();
15769                    Slog.w(TAG, msg);
15770                    throw new SecurityException(msg);
15771                }
15772            }
15773        }
15774        if (!allowAll && targetUserId < 0) {
15775            throw new IllegalArgumentException(
15776                    "Call does not support special user #" + targetUserId);
15777        }
15778        // Check shell permission
15779        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15780            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15781                    targetUserId)) {
15782                throw new SecurityException("Shell does not have permission to access user "
15783                        + targetUserId + "\n " + Debug.getCallers(3));
15784            }
15785        }
15786        return targetUserId;
15787    }
15788
15789    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15790            String className, int flags) {
15791        boolean result = false;
15792        // For apps that don't have pre-defined UIDs, check for permission
15793        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15794            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15795                if (ActivityManager.checkUidPermission(
15796                        INTERACT_ACROSS_USERS,
15797                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15798                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15799                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15800                            + " requests FLAG_SINGLE_USER, but app does not hold "
15801                            + INTERACT_ACROSS_USERS;
15802                    Slog.w(TAG, msg);
15803                    throw new SecurityException(msg);
15804                }
15805                // Permission passed
15806                result = true;
15807            }
15808        } else if ("system".equals(componentProcessName)) {
15809            result = true;
15810        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15811            // Phone app and persistent apps are allowed to export singleuser providers.
15812            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15813                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15814        }
15815        if (DEBUG_MU) Slog.v(TAG_MU,
15816                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
15817                + Integer.toHexString(flags) + ") = " + result);
15818        return result;
15819    }
15820
15821    /**
15822     * Checks to see if the caller is in the same app as the singleton
15823     * component, or the component is in a special app. It allows special apps
15824     * to export singleton components but prevents exporting singleton
15825     * components for regular apps.
15826     */
15827    boolean isValidSingletonCall(int callingUid, int componentUid) {
15828        int componentAppId = UserHandle.getAppId(componentUid);
15829        return UserHandle.isSameApp(callingUid, componentUid)
15830                || componentAppId == Process.SYSTEM_UID
15831                || componentAppId == Process.PHONE_UID
15832                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15833                        == PackageManager.PERMISSION_GRANTED;
15834    }
15835
15836    public int bindService(IApplicationThread caller, IBinder token, Intent service,
15837            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
15838            int userId) throws TransactionTooLargeException {
15839        enforceNotIsolatedCaller("bindService");
15840
15841        // Refuse possible leaked file descriptors
15842        if (service != null && service.hasFileDescriptors() == true) {
15843            throw new IllegalArgumentException("File descriptors passed in Intent");
15844        }
15845
15846        if (callingPackage == null) {
15847            throw new IllegalArgumentException("callingPackage cannot be null");
15848        }
15849
15850        synchronized(this) {
15851            return mServices.bindServiceLocked(caller, token, service,
15852                    resolvedType, connection, flags, callingPackage, userId);
15853        }
15854    }
15855
15856    public boolean unbindService(IServiceConnection connection) {
15857        synchronized (this) {
15858            return mServices.unbindServiceLocked(connection);
15859        }
15860    }
15861
15862    public void publishService(IBinder token, Intent intent, IBinder service) {
15863        // Refuse possible leaked file descriptors
15864        if (intent != null && intent.hasFileDescriptors() == true) {
15865            throw new IllegalArgumentException("File descriptors passed in Intent");
15866        }
15867
15868        synchronized(this) {
15869            if (!(token instanceof ServiceRecord)) {
15870                throw new IllegalArgumentException("Invalid service token");
15871            }
15872            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15873        }
15874    }
15875
15876    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15877        // Refuse possible leaked file descriptors
15878        if (intent != null && intent.hasFileDescriptors() == true) {
15879            throw new IllegalArgumentException("File descriptors passed in Intent");
15880        }
15881
15882        synchronized(this) {
15883            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15884        }
15885    }
15886
15887    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15888        synchronized(this) {
15889            if (!(token instanceof ServiceRecord)) {
15890                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
15891                throw new IllegalArgumentException("Invalid service token");
15892            }
15893            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15894        }
15895    }
15896
15897    // =========================================================
15898    // BACKUP AND RESTORE
15899    // =========================================================
15900
15901    // Cause the target app to be launched if necessary and its backup agent
15902    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15903    // activity manager to announce its creation.
15904    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15905        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
15906                "bindBackupAgent: app=" + app + " mode=" + backupMode);
15907        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15908
15909        synchronized(this) {
15910            // !!! TODO: currently no check here that we're already bound
15911            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15912            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15913            synchronized (stats) {
15914                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15915            }
15916
15917            // Backup agent is now in use, its package can't be stopped.
15918            try {
15919                AppGlobals.getPackageManager().setPackageStoppedState(
15920                        app.packageName, false, UserHandle.getUserId(app.uid));
15921            } catch (RemoteException e) {
15922            } catch (IllegalArgumentException e) {
15923                Slog.w(TAG, "Failed trying to unstop package "
15924                        + app.packageName + ": " + e);
15925            }
15926
15927            BackupRecord r = new BackupRecord(ss, app, backupMode);
15928            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15929                    ? new ComponentName(app.packageName, app.backupAgentName)
15930                    : new ComponentName("android", "FullBackupAgent");
15931            // startProcessLocked() returns existing proc's record if it's already running
15932            ProcessRecord proc = startProcessLocked(app.processName, app,
15933                    false, 0, "backup", hostingName, false, false, false);
15934            if (proc == null) {
15935                Slog.e(TAG, "Unable to start backup agent process " + r);
15936                return false;
15937            }
15938
15939            r.app = proc;
15940            mBackupTarget = r;
15941            mBackupAppName = app.packageName;
15942
15943            // Try not to kill the process during backup
15944            updateOomAdjLocked(proc);
15945
15946            // If the process is already attached, schedule the creation of the backup agent now.
15947            // If it is not yet live, this will be done when it attaches to the framework.
15948            if (proc.thread != null) {
15949                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
15950                try {
15951                    proc.thread.scheduleCreateBackupAgent(app,
15952                            compatibilityInfoForPackageLocked(app), backupMode);
15953                } catch (RemoteException e) {
15954                    // Will time out on the backup manager side
15955                }
15956            } else {
15957                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
15958            }
15959            // Invariants: at this point, the target app process exists and the application
15960            // is either already running or in the process of coming up.  mBackupTarget and
15961            // mBackupAppName describe the app, so that when it binds back to the AM we
15962            // know that it's scheduled for a backup-agent operation.
15963        }
15964
15965        return true;
15966    }
15967
15968    @Override
15969    public void clearPendingBackup() {
15970        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
15971        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15972
15973        synchronized (this) {
15974            mBackupTarget = null;
15975            mBackupAppName = null;
15976        }
15977    }
15978
15979    // A backup agent has just come up
15980    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15981        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
15982                + " = " + agent);
15983
15984        synchronized(this) {
15985            if (!agentPackageName.equals(mBackupAppName)) {
15986                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15987                return;
15988            }
15989        }
15990
15991        long oldIdent = Binder.clearCallingIdentity();
15992        try {
15993            IBackupManager bm = IBackupManager.Stub.asInterface(
15994                    ServiceManager.getService(Context.BACKUP_SERVICE));
15995            bm.agentConnected(agentPackageName, agent);
15996        } catch (RemoteException e) {
15997            // can't happen; the backup manager service is local
15998        } catch (Exception e) {
15999            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16000            e.printStackTrace();
16001        } finally {
16002            Binder.restoreCallingIdentity(oldIdent);
16003        }
16004    }
16005
16006    // done with this agent
16007    public void unbindBackupAgent(ApplicationInfo appInfo) {
16008        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16009        if (appInfo == null) {
16010            Slog.w(TAG, "unbind backup agent for null app");
16011            return;
16012        }
16013
16014        synchronized(this) {
16015            try {
16016                if (mBackupAppName == null) {
16017                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16018                    return;
16019                }
16020
16021                if (!mBackupAppName.equals(appInfo.packageName)) {
16022                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16023                    return;
16024                }
16025
16026                // Not backing this app up any more; reset its OOM adjustment
16027                final ProcessRecord proc = mBackupTarget.app;
16028                updateOomAdjLocked(proc);
16029
16030                // If the app crashed during backup, 'thread' will be null here
16031                if (proc.thread != null) {
16032                    try {
16033                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16034                                compatibilityInfoForPackageLocked(appInfo));
16035                    } catch (Exception e) {
16036                        Slog.e(TAG, "Exception when unbinding backup agent:");
16037                        e.printStackTrace();
16038                    }
16039                }
16040            } finally {
16041                mBackupTarget = null;
16042                mBackupAppName = null;
16043            }
16044        }
16045    }
16046    // =========================================================
16047    // BROADCASTS
16048    // =========================================================
16049
16050    boolean isPendingBroadcastProcessLocked(int pid) {
16051        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16052                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16053    }
16054
16055    void skipPendingBroadcastLocked(int pid) {
16056            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16057            for (BroadcastQueue queue : mBroadcastQueues) {
16058                queue.skipPendingBroadcastLocked(pid);
16059            }
16060    }
16061
16062    // The app just attached; send any pending broadcasts that it should receive
16063    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16064        boolean didSomething = false;
16065        for (BroadcastQueue queue : mBroadcastQueues) {
16066            didSomething |= queue.sendPendingBroadcastsLocked(app);
16067        }
16068        return didSomething;
16069    }
16070
16071    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16072            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16073        enforceNotIsolatedCaller("registerReceiver");
16074        ArrayList<Intent> stickyIntents = null;
16075        ProcessRecord callerApp = null;
16076        int callingUid;
16077        int callingPid;
16078        synchronized(this) {
16079            if (caller != null) {
16080                callerApp = getRecordForAppLocked(caller);
16081                if (callerApp == null) {
16082                    throw new SecurityException(
16083                            "Unable to find app for caller " + caller
16084                            + " (pid=" + Binder.getCallingPid()
16085                            + ") when registering receiver " + receiver);
16086                }
16087                if (callerApp.info.uid != Process.SYSTEM_UID &&
16088                        !callerApp.pkgList.containsKey(callerPackage) &&
16089                        !"android".equals(callerPackage)) {
16090                    throw new SecurityException("Given caller package " + callerPackage
16091                            + " is not running in process " + callerApp);
16092                }
16093                callingUid = callerApp.info.uid;
16094                callingPid = callerApp.pid;
16095            } else {
16096                callerPackage = null;
16097                callingUid = Binder.getCallingUid();
16098                callingPid = Binder.getCallingPid();
16099            }
16100
16101            userId = handleIncomingUser(callingPid, callingUid, userId,
16102                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16103
16104            Iterator<String> actions = filter.actionsIterator();
16105            if (actions == null) {
16106                ArrayList<String> noAction = new ArrayList<String>(1);
16107                noAction.add(null);
16108                actions = noAction.iterator();
16109            }
16110
16111            // Collect stickies of users
16112            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16113            while (actions.hasNext()) {
16114                String action = actions.next();
16115                for (int id : userIds) {
16116                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16117                    if (stickies != null) {
16118                        ArrayList<Intent> intents = stickies.get(action);
16119                        if (intents != null) {
16120                            if (stickyIntents == null) {
16121                                stickyIntents = new ArrayList<Intent>();
16122                            }
16123                            stickyIntents.addAll(intents);
16124                        }
16125                    }
16126                }
16127            }
16128        }
16129
16130        ArrayList<Intent> allSticky = null;
16131        if (stickyIntents != null) {
16132            final ContentResolver resolver = mContext.getContentResolver();
16133            // Look for any matching sticky broadcasts...
16134            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16135                Intent intent = stickyIntents.get(i);
16136                // If intent has scheme "content", it will need to acccess
16137                // provider that needs to lock mProviderMap in ActivityThread
16138                // and also it may need to wait application response, so we
16139                // cannot lock ActivityManagerService here.
16140                if (filter.match(resolver, intent, true, TAG) >= 0) {
16141                    if (allSticky == null) {
16142                        allSticky = new ArrayList<Intent>();
16143                    }
16144                    allSticky.add(intent);
16145                }
16146            }
16147        }
16148
16149        // The first sticky in the list is returned directly back to the client.
16150        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16151        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16152        if (receiver == null) {
16153            return sticky;
16154        }
16155
16156        synchronized (this) {
16157            if (callerApp != null && (callerApp.thread == null
16158                    || callerApp.thread.asBinder() != caller.asBinder())) {
16159                // Original caller already died
16160                return null;
16161            }
16162            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16163            if (rl == null) {
16164                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16165                        userId, receiver);
16166                if (rl.app != null) {
16167                    rl.app.receivers.add(rl);
16168                } else {
16169                    try {
16170                        receiver.asBinder().linkToDeath(rl, 0);
16171                    } catch (RemoteException e) {
16172                        return sticky;
16173                    }
16174                    rl.linkedToDeath = true;
16175                }
16176                mRegisteredReceivers.put(receiver.asBinder(), rl);
16177            } else if (rl.uid != callingUid) {
16178                throw new IllegalArgumentException(
16179                        "Receiver requested to register for uid " + callingUid
16180                        + " was previously registered for uid " + rl.uid);
16181            } else if (rl.pid != callingPid) {
16182                throw new IllegalArgumentException(
16183                        "Receiver requested to register for pid " + callingPid
16184                        + " was previously registered for pid " + rl.pid);
16185            } else if (rl.userId != userId) {
16186                throw new IllegalArgumentException(
16187                        "Receiver requested to register for user " + userId
16188                        + " was previously registered for user " + rl.userId);
16189            }
16190            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16191                    permission, callingUid, userId);
16192            rl.add(bf);
16193            if (!bf.debugCheck()) {
16194                Slog.w(TAG, "==> For Dynamic broadcast");
16195            }
16196            mReceiverResolver.addFilter(bf);
16197
16198            // Enqueue broadcasts for all existing stickies that match
16199            // this filter.
16200            if (allSticky != null) {
16201                ArrayList receivers = new ArrayList();
16202                receivers.add(bf);
16203
16204                final int stickyCount = allSticky.size();
16205                for (int i = 0; i < stickyCount; i++) {
16206                    Intent intent = allSticky.get(i);
16207                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16208                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16209                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16210                            null, 0, null, null, false, true, true, -1);
16211                    queue.enqueueParallelBroadcastLocked(r);
16212                    queue.scheduleBroadcastsLocked();
16213                }
16214            }
16215
16216            return sticky;
16217        }
16218    }
16219
16220    public void unregisterReceiver(IIntentReceiver receiver) {
16221        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16222
16223        final long origId = Binder.clearCallingIdentity();
16224        try {
16225            boolean doTrim = false;
16226
16227            synchronized(this) {
16228                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16229                if (rl != null) {
16230                    final BroadcastRecord r = rl.curBroadcast;
16231                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16232                        final boolean doNext = r.queue.finishReceiverLocked(
16233                                r, r.resultCode, r.resultData, r.resultExtras,
16234                                r.resultAbort, false);
16235                        if (doNext) {
16236                            doTrim = true;
16237                            r.queue.processNextBroadcast(false);
16238                        }
16239                    }
16240
16241                    if (rl.app != null) {
16242                        rl.app.receivers.remove(rl);
16243                    }
16244                    removeReceiverLocked(rl);
16245                    if (rl.linkedToDeath) {
16246                        rl.linkedToDeath = false;
16247                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
16248                    }
16249                }
16250            }
16251
16252            // If we actually concluded any broadcasts, we might now be able
16253            // to trim the recipients' apps from our working set
16254            if (doTrim) {
16255                trimApplications();
16256                return;
16257            }
16258
16259        } finally {
16260            Binder.restoreCallingIdentity(origId);
16261        }
16262    }
16263
16264    void removeReceiverLocked(ReceiverList rl) {
16265        mRegisteredReceivers.remove(rl.receiver.asBinder());
16266        for (int i = rl.size() - 1; i >= 0; i--) {
16267            mReceiverResolver.removeFilter(rl.get(i));
16268        }
16269    }
16270
16271    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16272        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16273            ProcessRecord r = mLruProcesses.get(i);
16274            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16275                try {
16276                    r.thread.dispatchPackageBroadcast(cmd, packages);
16277                } catch (RemoteException ex) {
16278                }
16279            }
16280        }
16281    }
16282
16283    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16284            int callingUid, int[] users) {
16285        List<ResolveInfo> receivers = null;
16286        try {
16287            HashSet<ComponentName> singleUserReceivers = null;
16288            boolean scannedFirstReceivers = false;
16289            for (int user : users) {
16290                // Skip users that have Shell restrictions
16291                if (callingUid == Process.SHELL_UID
16292                        && getUserManagerLocked().hasUserRestriction(
16293                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
16294                    continue;
16295                }
16296                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16297                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
16298                if (user != UserHandle.USER_OWNER && newReceivers != null) {
16299                    // If this is not the primary user, we need to check for
16300                    // any receivers that should be filtered out.
16301                    for (int i=0; i<newReceivers.size(); i++) {
16302                        ResolveInfo ri = newReceivers.get(i);
16303                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
16304                            newReceivers.remove(i);
16305                            i--;
16306                        }
16307                    }
16308                }
16309                if (newReceivers != null && newReceivers.size() == 0) {
16310                    newReceivers = null;
16311                }
16312                if (receivers == null) {
16313                    receivers = newReceivers;
16314                } else if (newReceivers != null) {
16315                    // We need to concatenate the additional receivers
16316                    // found with what we have do far.  This would be easy,
16317                    // but we also need to de-dup any receivers that are
16318                    // singleUser.
16319                    if (!scannedFirstReceivers) {
16320                        // Collect any single user receivers we had already retrieved.
16321                        scannedFirstReceivers = true;
16322                        for (int i=0; i<receivers.size(); i++) {
16323                            ResolveInfo ri = receivers.get(i);
16324                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16325                                ComponentName cn = new ComponentName(
16326                                        ri.activityInfo.packageName, ri.activityInfo.name);
16327                                if (singleUserReceivers == null) {
16328                                    singleUserReceivers = new HashSet<ComponentName>();
16329                                }
16330                                singleUserReceivers.add(cn);
16331                            }
16332                        }
16333                    }
16334                    // Add the new results to the existing results, tracking
16335                    // and de-dupping single user receivers.
16336                    for (int i=0; i<newReceivers.size(); i++) {
16337                        ResolveInfo ri = newReceivers.get(i);
16338                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16339                            ComponentName cn = new ComponentName(
16340                                    ri.activityInfo.packageName, ri.activityInfo.name);
16341                            if (singleUserReceivers == null) {
16342                                singleUserReceivers = new HashSet<ComponentName>();
16343                            }
16344                            if (!singleUserReceivers.contains(cn)) {
16345                                singleUserReceivers.add(cn);
16346                                receivers.add(ri);
16347                            }
16348                        } else {
16349                            receivers.add(ri);
16350                        }
16351                    }
16352                }
16353            }
16354        } catch (RemoteException ex) {
16355            // pm is in same process, this will never happen.
16356        }
16357        return receivers;
16358    }
16359
16360    private final int broadcastIntentLocked(ProcessRecord callerApp,
16361            String callerPackage, Intent intent, String resolvedType,
16362            IIntentReceiver resultTo, int resultCode, String resultData,
16363            Bundle resultExtras, String requiredPermission, int appOp, Bundle options,
16364            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
16365        intent = new Intent(intent);
16366
16367        // By default broadcasts do not go to stopped apps.
16368        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
16369
16370        // If we have not finished booting, don't allow this to launch new processes.
16371        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
16372            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16373        }
16374
16375        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
16376                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
16377                + " ordered=" + ordered + " userid=" + userId);
16378        if ((resultTo != null) && !ordered) {
16379            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
16380        }
16381
16382        userId = handleIncomingUser(callingPid, callingUid, userId,
16383                true, ALLOW_NON_FULL, "broadcast", callerPackage);
16384
16385        // Make sure that the user who is receiving this broadcast is running.
16386        // If not, we will just skip it. Make an exception for shutdown broadcasts
16387        // and upgrade steps.
16388
16389        if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
16390            if ((callingUid != Process.SYSTEM_UID
16391                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
16392                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
16393                Slog.w(TAG, "Skipping broadcast of " + intent
16394                        + ": user " + userId + " is stopped");
16395                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
16396            }
16397        }
16398
16399        BroadcastOptions brOptions = null;
16400        if (options != null) {
16401            brOptions = new BroadcastOptions(options);
16402            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
16403                // See if the caller is allowed to do this.  Note we are checking against
16404                // the actual real caller (not whoever provided the operation as say a
16405                // PendingIntent), because that who is actually supplied the arguments.
16406                if (checkComponentPermission(
16407                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
16408                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
16409                        != PackageManager.PERMISSION_GRANTED) {
16410                    String msg = "Permission Denial: " + intent.getAction()
16411                            + " broadcast from " + callerPackage + " (pid=" + callingPid
16412                            + ", uid=" + callingUid + ")"
16413                            + " requires "
16414                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
16415                    Slog.w(TAG, msg);
16416                    throw new SecurityException(msg);
16417                }
16418            }
16419        }
16420
16421        /*
16422         * Prevent non-system code (defined here to be non-persistent
16423         * processes) from sending protected broadcasts.
16424         */
16425        int callingAppId = UserHandle.getAppId(callingUid);
16426        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
16427            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
16428            || callingAppId == Process.NFC_UID || callingUid == 0) {
16429            // Always okay.
16430        } else if (callerApp == null || !callerApp.persistent) {
16431            try {
16432                if (AppGlobals.getPackageManager().isProtectedBroadcast(
16433                        intent.getAction())) {
16434                    String msg = "Permission Denial: not allowed to send broadcast "
16435                            + intent.getAction() + " from pid="
16436                            + callingPid + ", uid=" + callingUid;
16437                    Slog.w(TAG, msg);
16438                    throw new SecurityException(msg);
16439                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
16440                    // Special case for compatibility: we don't want apps to send this,
16441                    // but historically it has not been protected and apps may be using it
16442                    // to poke their own app widget.  So, instead of making it protected,
16443                    // just limit it to the caller.
16444                    if (callerApp == null) {
16445                        String msg = "Permission Denial: not allowed to send broadcast "
16446                                + intent.getAction() + " from unknown caller.";
16447                        Slog.w(TAG, msg);
16448                        throw new SecurityException(msg);
16449                    } else if (intent.getComponent() != null) {
16450                        // They are good enough to send to an explicit component...  verify
16451                        // it is being sent to the calling app.
16452                        if (!intent.getComponent().getPackageName().equals(
16453                                callerApp.info.packageName)) {
16454                            String msg = "Permission Denial: not allowed to send broadcast "
16455                                    + intent.getAction() + " to "
16456                                    + intent.getComponent().getPackageName() + " from "
16457                                    + callerApp.info.packageName;
16458                            Slog.w(TAG, msg);
16459                            throw new SecurityException(msg);
16460                        }
16461                    } else {
16462                        // Limit broadcast to their own package.
16463                        intent.setPackage(callerApp.info.packageName);
16464                    }
16465                }
16466            } catch (RemoteException e) {
16467                Slog.w(TAG, "Remote exception", e);
16468                return ActivityManager.BROADCAST_SUCCESS;
16469            }
16470        }
16471
16472        final String action = intent.getAction();
16473        if (action != null) {
16474            switch (action) {
16475                case Intent.ACTION_UID_REMOVED:
16476                case Intent.ACTION_PACKAGE_REMOVED:
16477                case Intent.ACTION_PACKAGE_CHANGED:
16478                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16479                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16480                    // Handle special intents: if this broadcast is from the package
16481                    // manager about a package being removed, we need to remove all of
16482                    // its activities from the history stack.
16483                    if (checkComponentPermission(
16484                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
16485                            callingPid, callingUid, -1, true)
16486                            != PackageManager.PERMISSION_GRANTED) {
16487                        String msg = "Permission Denial: " + intent.getAction()
16488                                + " broadcast from " + callerPackage + " (pid=" + callingPid
16489                                + ", uid=" + callingUid + ")"
16490                                + " requires "
16491                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
16492                        Slog.w(TAG, msg);
16493                        throw new SecurityException(msg);
16494                    }
16495                    switch (action) {
16496                        case Intent.ACTION_UID_REMOVED:
16497                            final Bundle intentExtras = intent.getExtras();
16498                            final int uid = intentExtras != null
16499                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
16500                            if (uid >= 0) {
16501                                mBatteryStatsService.removeUid(uid);
16502                                mAppOpsService.uidRemoved(uid);
16503                            }
16504                            break;
16505                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16506                            // If resources are unavailable just force stop all those packages
16507                            // and flush the attribute cache as well.
16508                            String list[] =
16509                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16510                            if (list != null && list.length > 0) {
16511                                for (int i = 0; i < list.length; i++) {
16512                                    forceStopPackageLocked(list[i], -1, false, true, true,
16513                                            false, false, userId, "storage unmount");
16514                                }
16515                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16516                                sendPackageBroadcastLocked(
16517                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
16518                                        userId);
16519                            }
16520                            break;
16521                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16522                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16523                            break;
16524                        case Intent.ACTION_PACKAGE_REMOVED:
16525                        case Intent.ACTION_PACKAGE_CHANGED:
16526                            Uri data = intent.getData();
16527                            String ssp;
16528                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
16529                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
16530                                boolean fullUninstall = removed &&
16531                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16532                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
16533                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
16534                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
16535                                            false, true, true, false, fullUninstall, userId,
16536                                            removed ? "pkg removed" : "pkg changed");
16537                                }
16538                                if (removed) {
16539                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
16540                                            new String[] {ssp}, userId);
16541                                    if (fullUninstall) {
16542                                        mAppOpsService.packageRemoved(
16543                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
16544
16545                                        // Remove all permissions granted from/to this package
16546                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
16547
16548                                        removeTasksByPackageNameLocked(ssp, userId);
16549                                        mBatteryStatsService.notePackageUninstalled(ssp);
16550                                    }
16551                                } else {
16552                                    cleanupDisabledPackageComponentsLocked(ssp, userId,
16553                                            intent.getStringArrayExtra(
16554                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
16555                                }
16556                            }
16557                            break;
16558                    }
16559                    break;
16560                case Intent.ACTION_PACKAGE_ADDED:
16561                    // Special case for adding a package: by default turn on compatibility mode.
16562                    Uri data = intent.getData();
16563                    String ssp;
16564                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
16565                        final boolean replacing =
16566                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16567                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
16568
16569                        try {
16570                            ApplicationInfo ai = AppGlobals.getPackageManager().
16571                                    getApplicationInfo(ssp, 0, 0);
16572                            mBatteryStatsService.notePackageInstalled(ssp,
16573                                    ai != null ? ai.versionCode : 0);
16574                        } catch (RemoteException e) {
16575                        }
16576                    }
16577                    break;
16578                case Intent.ACTION_TIMEZONE_CHANGED:
16579                    // If this is the time zone changed action, queue up a message that will reset
16580                    // the timezone of all currently running processes. This message will get
16581                    // queued up before the broadcast happens.
16582                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
16583                    break;
16584                case Intent.ACTION_TIME_CHANGED:
16585                    // If the user set the time, let all running processes know.
16586                    final int is24Hour =
16587                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
16588                                    : 0;
16589                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
16590                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16591                    synchronized (stats) {
16592                        stats.noteCurrentTimeChangedLocked();
16593                    }
16594                    break;
16595                case Intent.ACTION_CLEAR_DNS_CACHE:
16596                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
16597                    break;
16598                case Proxy.PROXY_CHANGE_ACTION:
16599                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
16600                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
16601                    break;
16602            }
16603        }
16604
16605        // Add to the sticky list if requested.
16606        if (sticky) {
16607            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
16608                    callingPid, callingUid)
16609                    != PackageManager.PERMISSION_GRANTED) {
16610                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
16611                        + callingPid + ", uid=" + callingUid
16612                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16613                Slog.w(TAG, msg);
16614                throw new SecurityException(msg);
16615            }
16616            if (requiredPermission != null) {
16617                Slog.w(TAG, "Can't broadcast sticky intent " + intent
16618                        + " and enforce permission " + requiredPermission);
16619                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
16620            }
16621            if (intent.getComponent() != null) {
16622                throw new SecurityException(
16623                        "Sticky broadcasts can't target a specific component");
16624            }
16625            // We use userId directly here, since the "all" target is maintained
16626            // as a separate set of sticky broadcasts.
16627            if (userId != UserHandle.USER_ALL) {
16628                // But first, if this is not a broadcast to all users, then
16629                // make sure it doesn't conflict with an existing broadcast to
16630                // all users.
16631                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
16632                        UserHandle.USER_ALL);
16633                if (stickies != null) {
16634                    ArrayList<Intent> list = stickies.get(intent.getAction());
16635                    if (list != null) {
16636                        int N = list.size();
16637                        int i;
16638                        for (i=0; i<N; i++) {
16639                            if (intent.filterEquals(list.get(i))) {
16640                                throw new IllegalArgumentException(
16641                                        "Sticky broadcast " + intent + " for user "
16642                                        + userId + " conflicts with existing global broadcast");
16643                            }
16644                        }
16645                    }
16646                }
16647            }
16648            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16649            if (stickies == null) {
16650                stickies = new ArrayMap<>();
16651                mStickyBroadcasts.put(userId, stickies);
16652            }
16653            ArrayList<Intent> list = stickies.get(intent.getAction());
16654            if (list == null) {
16655                list = new ArrayList<>();
16656                stickies.put(intent.getAction(), list);
16657            }
16658            final int stickiesCount = list.size();
16659            int i;
16660            for (i = 0; i < stickiesCount; i++) {
16661                if (intent.filterEquals(list.get(i))) {
16662                    // This sticky already exists, replace it.
16663                    list.set(i, new Intent(intent));
16664                    break;
16665                }
16666            }
16667            if (i >= stickiesCount) {
16668                list.add(new Intent(intent));
16669            }
16670        }
16671
16672        int[] users;
16673        if (userId == UserHandle.USER_ALL) {
16674            // Caller wants broadcast to go to all started users.
16675            users = mStartedUserArray;
16676        } else {
16677            // Caller wants broadcast to go to one specific user.
16678            users = new int[] {userId};
16679        }
16680
16681        // Figure out who all will receive this broadcast.
16682        List receivers = null;
16683        List<BroadcastFilter> registeredReceivers = null;
16684        // Need to resolve the intent to interested receivers...
16685        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
16686                 == 0) {
16687            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
16688        }
16689        if (intent.getComponent() == null) {
16690            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
16691                // Query one target user at a time, excluding shell-restricted users
16692                UserManagerService ums = getUserManagerLocked();
16693                for (int i = 0; i < users.length; i++) {
16694                    if (ums.hasUserRestriction(
16695                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
16696                        continue;
16697                    }
16698                    List<BroadcastFilter> registeredReceiversForUser =
16699                            mReceiverResolver.queryIntent(intent,
16700                                    resolvedType, false, users[i]);
16701                    if (registeredReceivers == null) {
16702                        registeredReceivers = registeredReceiversForUser;
16703                    } else if (registeredReceiversForUser != null) {
16704                        registeredReceivers.addAll(registeredReceiversForUser);
16705                    }
16706                }
16707            } else {
16708                registeredReceivers = mReceiverResolver.queryIntent(intent,
16709                        resolvedType, false, userId);
16710            }
16711        }
16712
16713        final boolean replacePending =
16714                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16715
16716        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
16717                + " replacePending=" + replacePending);
16718
16719        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16720        if (!ordered && NR > 0) {
16721            // If we are not serializing this broadcast, then send the
16722            // registered receivers separately so they don't wait for the
16723            // components to be launched.
16724            final BroadcastQueue queue = broadcastQueueForIntent(intent);
16725            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16726                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
16727                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
16728                    resultExtras, ordered, sticky, false, userId);
16729            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
16730            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16731            if (!replaced) {
16732                queue.enqueueParallelBroadcastLocked(r);
16733                queue.scheduleBroadcastsLocked();
16734            }
16735            registeredReceivers = null;
16736            NR = 0;
16737        }
16738
16739        // Merge into one list.
16740        int ir = 0;
16741        if (receivers != null) {
16742            // A special case for PACKAGE_ADDED: do not allow the package
16743            // being added to see this broadcast.  This prevents them from
16744            // using this as a back door to get run as soon as they are
16745            // installed.  Maybe in the future we want to have a special install
16746            // broadcast or such for apps, but we'd like to deliberately make
16747            // this decision.
16748            String skipPackages[] = null;
16749            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16750                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16751                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16752                Uri data = intent.getData();
16753                if (data != null) {
16754                    String pkgName = data.getSchemeSpecificPart();
16755                    if (pkgName != null) {
16756                        skipPackages = new String[] { pkgName };
16757                    }
16758                }
16759            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16760                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16761            }
16762            if (skipPackages != null && (skipPackages.length > 0)) {
16763                for (String skipPackage : skipPackages) {
16764                    if (skipPackage != null) {
16765                        int NT = receivers.size();
16766                        for (int it=0; it<NT; it++) {
16767                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
16768                            if (curt.activityInfo.packageName.equals(skipPackage)) {
16769                                receivers.remove(it);
16770                                it--;
16771                                NT--;
16772                            }
16773                        }
16774                    }
16775                }
16776            }
16777
16778            int NT = receivers != null ? receivers.size() : 0;
16779            int it = 0;
16780            ResolveInfo curt = null;
16781            BroadcastFilter curr = null;
16782            while (it < NT && ir < NR) {
16783                if (curt == null) {
16784                    curt = (ResolveInfo)receivers.get(it);
16785                }
16786                if (curr == null) {
16787                    curr = registeredReceivers.get(ir);
16788                }
16789                if (curr.getPriority() >= curt.priority) {
16790                    // Insert this broadcast record into the final list.
16791                    receivers.add(it, curr);
16792                    ir++;
16793                    curr = null;
16794                    it++;
16795                    NT++;
16796                } else {
16797                    // Skip to the next ResolveInfo in the final list.
16798                    it++;
16799                    curt = null;
16800                }
16801            }
16802        }
16803        while (ir < NR) {
16804            if (receivers == null) {
16805                receivers = new ArrayList();
16806            }
16807            receivers.add(registeredReceivers.get(ir));
16808            ir++;
16809        }
16810
16811        if ((receivers != null && receivers.size() > 0)
16812                || resultTo != null) {
16813            BroadcastQueue queue = broadcastQueueForIntent(intent);
16814            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16815                    callerPackage, callingPid, callingUid, resolvedType,
16816                    requiredPermission, appOp, brOptions, receivers, resultTo, resultCode,
16817                    resultData, resultExtras, ordered, sticky, false, userId);
16818
16819            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
16820                    + ": prev had " + queue.mOrderedBroadcasts.size());
16821            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
16822                    "Enqueueing broadcast " + r.intent.getAction());
16823
16824            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16825            if (!replaced) {
16826                queue.enqueueOrderedBroadcastLocked(r);
16827                queue.scheduleBroadcastsLocked();
16828            }
16829        }
16830
16831        return ActivityManager.BROADCAST_SUCCESS;
16832    }
16833
16834    final Intent verifyBroadcastLocked(Intent intent) {
16835        // Refuse possible leaked file descriptors
16836        if (intent != null && intent.hasFileDescriptors() == true) {
16837            throw new IllegalArgumentException("File descriptors passed in Intent");
16838        }
16839
16840        int flags = intent.getFlags();
16841
16842        if (!mProcessesReady) {
16843            // if the caller really truly claims to know what they're doing, go
16844            // ahead and allow the broadcast without launching any receivers
16845            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16846                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
16847            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16848                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16849                        + " before boot completion");
16850                throw new IllegalStateException("Cannot broadcast before boot completed");
16851            }
16852        }
16853
16854        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16855            throw new IllegalArgumentException(
16856                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16857        }
16858
16859        return intent;
16860    }
16861
16862    public final int broadcastIntent(IApplicationThread caller,
16863            Intent intent, String resolvedType, IIntentReceiver resultTo,
16864            int resultCode, String resultData, Bundle resultExtras,
16865            String requiredPermission, int appOp, Bundle options,
16866            boolean serialized, boolean sticky, int userId) {
16867        enforceNotIsolatedCaller("broadcastIntent");
16868        synchronized(this) {
16869            intent = verifyBroadcastLocked(intent);
16870
16871            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16872            final int callingPid = Binder.getCallingPid();
16873            final int callingUid = Binder.getCallingUid();
16874            final long origId = Binder.clearCallingIdentity();
16875            int res = broadcastIntentLocked(callerApp,
16876                    callerApp != null ? callerApp.info.packageName : null,
16877                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
16878                    requiredPermission, appOp, null, serialized, sticky,
16879                    callingPid, callingUid, userId);
16880            Binder.restoreCallingIdentity(origId);
16881            return res;
16882        }
16883    }
16884
16885    int broadcastIntentInPackage(String packageName, int uid,
16886            Intent intent, String resolvedType, IIntentReceiver resultTo,
16887            int resultCode, String resultData, Bundle resultExtras,
16888            String requiredPermission, Bundle options, boolean serialized, boolean sticky,
16889            int userId) {
16890        synchronized(this) {
16891            intent = verifyBroadcastLocked(intent);
16892
16893            final long origId = Binder.clearCallingIdentity();
16894            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16895                    resultTo, resultCode, resultData, resultExtras, requiredPermission,
16896                    AppOpsManager.OP_NONE, options, serialized, sticky, -1, uid, userId);
16897            Binder.restoreCallingIdentity(origId);
16898            return res;
16899        }
16900    }
16901
16902    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16903        // Refuse possible leaked file descriptors
16904        if (intent != null && intent.hasFileDescriptors() == true) {
16905            throw new IllegalArgumentException("File descriptors passed in Intent");
16906        }
16907
16908        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16909                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16910
16911        synchronized(this) {
16912            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16913                    != PackageManager.PERMISSION_GRANTED) {
16914                String msg = "Permission Denial: unbroadcastIntent() from pid="
16915                        + Binder.getCallingPid()
16916                        + ", uid=" + Binder.getCallingUid()
16917                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16918                Slog.w(TAG, msg);
16919                throw new SecurityException(msg);
16920            }
16921            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16922            if (stickies != null) {
16923                ArrayList<Intent> list = stickies.get(intent.getAction());
16924                if (list != null) {
16925                    int N = list.size();
16926                    int i;
16927                    for (i=0; i<N; i++) {
16928                        if (intent.filterEquals(list.get(i))) {
16929                            list.remove(i);
16930                            break;
16931                        }
16932                    }
16933                    if (list.size() <= 0) {
16934                        stickies.remove(intent.getAction());
16935                    }
16936                }
16937                if (stickies.size() <= 0) {
16938                    mStickyBroadcasts.remove(userId);
16939                }
16940            }
16941        }
16942    }
16943
16944    void backgroundServicesFinishedLocked(int userId) {
16945        for (BroadcastQueue queue : mBroadcastQueues) {
16946            queue.backgroundServicesFinishedLocked(userId);
16947        }
16948    }
16949
16950    public void finishReceiver(IBinder who, int resultCode, String resultData,
16951            Bundle resultExtras, boolean resultAbort, int flags) {
16952        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
16953
16954        // Refuse possible leaked file descriptors
16955        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16956            throw new IllegalArgumentException("File descriptors passed in Bundle");
16957        }
16958
16959        final long origId = Binder.clearCallingIdentity();
16960        try {
16961            boolean doNext = false;
16962            BroadcastRecord r;
16963
16964            synchronized(this) {
16965                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
16966                        ? mFgBroadcastQueue : mBgBroadcastQueue;
16967                r = queue.getMatchingOrderedReceiver(who);
16968                if (r != null) {
16969                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16970                        resultData, resultExtras, resultAbort, true);
16971                }
16972            }
16973
16974            if (doNext) {
16975                r.queue.processNextBroadcast(false);
16976            }
16977            trimApplications();
16978        } finally {
16979            Binder.restoreCallingIdentity(origId);
16980        }
16981    }
16982
16983    // =========================================================
16984    // INSTRUMENTATION
16985    // =========================================================
16986
16987    public boolean startInstrumentation(ComponentName className,
16988            String profileFile, int flags, Bundle arguments,
16989            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16990            int userId, String abiOverride) {
16991        enforceNotIsolatedCaller("startInstrumentation");
16992        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16993                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16994        // Refuse possible leaked file descriptors
16995        if (arguments != null && arguments.hasFileDescriptors()) {
16996            throw new IllegalArgumentException("File descriptors passed in Bundle");
16997        }
16998
16999        synchronized(this) {
17000            InstrumentationInfo ii = null;
17001            ApplicationInfo ai = null;
17002            try {
17003                ii = mContext.getPackageManager().getInstrumentationInfo(
17004                    className, STOCK_PM_FLAGS);
17005                ai = AppGlobals.getPackageManager().getApplicationInfo(
17006                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17007            } catch (PackageManager.NameNotFoundException e) {
17008            } catch (RemoteException e) {
17009            }
17010            if (ii == null) {
17011                reportStartInstrumentationFailure(watcher, className,
17012                        "Unable to find instrumentation info for: " + className);
17013                return false;
17014            }
17015            if (ai == null) {
17016                reportStartInstrumentationFailure(watcher, className,
17017                        "Unable to find instrumentation target package: " + ii.targetPackage);
17018                return false;
17019            }
17020
17021            int match = mContext.getPackageManager().checkSignatures(
17022                    ii.targetPackage, ii.packageName);
17023            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17024                String msg = "Permission Denial: starting instrumentation "
17025                        + className + " from pid="
17026                        + Binder.getCallingPid()
17027                        + ", uid=" + Binder.getCallingPid()
17028                        + " not allowed because package " + ii.packageName
17029                        + " does not have a signature matching the target "
17030                        + ii.targetPackage;
17031                reportStartInstrumentationFailure(watcher, className, msg);
17032                throw new SecurityException(msg);
17033            }
17034
17035            final long origId = Binder.clearCallingIdentity();
17036            // Instrumentation can kill and relaunch even persistent processes
17037            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17038                    "start instr");
17039            ProcessRecord app = addAppLocked(ai, false, abiOverride);
17040            app.instrumentationClass = className;
17041            app.instrumentationInfo = ai;
17042            app.instrumentationProfileFile = profileFile;
17043            app.instrumentationArguments = arguments;
17044            app.instrumentationWatcher = watcher;
17045            app.instrumentationUiAutomationConnection = uiAutomationConnection;
17046            app.instrumentationResultClass = className;
17047            Binder.restoreCallingIdentity(origId);
17048        }
17049
17050        return true;
17051    }
17052
17053    /**
17054     * Report errors that occur while attempting to start Instrumentation.  Always writes the
17055     * error to the logs, but if somebody is watching, send the report there too.  This enables
17056     * the "am" command to report errors with more information.
17057     *
17058     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17059     * @param cn The component name of the instrumentation.
17060     * @param report The error report.
17061     */
17062    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
17063            ComponentName cn, String report) {
17064        Slog.w(TAG, report);
17065        try {
17066            if (watcher != null) {
17067                Bundle results = new Bundle();
17068                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17069                results.putString("Error", report);
17070                watcher.instrumentationStatus(cn, -1, results);
17071            }
17072        } catch (RemoteException e) {
17073            Slog.w(TAG, e);
17074        }
17075    }
17076
17077    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17078        if (app.instrumentationWatcher != null) {
17079            try {
17080                // NOTE:  IInstrumentationWatcher *must* be oneway here
17081                app.instrumentationWatcher.instrumentationFinished(
17082                    app.instrumentationClass,
17083                    resultCode,
17084                    results);
17085            } catch (RemoteException e) {
17086            }
17087        }
17088        if (app.instrumentationUiAutomationConnection != null) {
17089            try {
17090                app.instrumentationUiAutomationConnection.shutdown();
17091            } catch (RemoteException re) {
17092                /* ignore */
17093            }
17094            // Only a UiAutomation can set this flag and now that
17095            // it is finished we make sure it is reset to its default.
17096            mUserIsMonkey = false;
17097        }
17098        app.instrumentationWatcher = null;
17099        app.instrumentationUiAutomationConnection = null;
17100        app.instrumentationClass = null;
17101        app.instrumentationInfo = null;
17102        app.instrumentationProfileFile = null;
17103        app.instrumentationArguments = null;
17104
17105        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17106                "finished inst");
17107    }
17108
17109    public void finishInstrumentation(IApplicationThread target,
17110            int resultCode, Bundle results) {
17111        int userId = UserHandle.getCallingUserId();
17112        // Refuse possible leaked file descriptors
17113        if (results != null && results.hasFileDescriptors()) {
17114            throw new IllegalArgumentException("File descriptors passed in Intent");
17115        }
17116
17117        synchronized(this) {
17118            ProcessRecord app = getRecordForAppLocked(target);
17119            if (app == null) {
17120                Slog.w(TAG, "finishInstrumentation: no app for " + target);
17121                return;
17122            }
17123            final long origId = Binder.clearCallingIdentity();
17124            finishInstrumentationLocked(app, resultCode, results);
17125            Binder.restoreCallingIdentity(origId);
17126        }
17127    }
17128
17129    // =========================================================
17130    // CONFIGURATION
17131    // =========================================================
17132
17133    public ConfigurationInfo getDeviceConfigurationInfo() {
17134        ConfigurationInfo config = new ConfigurationInfo();
17135        synchronized (this) {
17136            config.reqTouchScreen = mConfiguration.touchscreen;
17137            config.reqKeyboardType = mConfiguration.keyboard;
17138            config.reqNavigation = mConfiguration.navigation;
17139            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17140                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17141                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17142            }
17143            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17144                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17145                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17146            }
17147            config.reqGlEsVersion = GL_ES_VERSION;
17148        }
17149        return config;
17150    }
17151
17152    ActivityStack getFocusedStack() {
17153        return mStackSupervisor.getFocusedStack();
17154    }
17155
17156    @Override
17157    public int getFocusedStackId() throws RemoteException {
17158        ActivityStack focusedStack = getFocusedStack();
17159        if (focusedStack != null) {
17160            return focusedStack.getStackId();
17161        }
17162        return -1;
17163    }
17164
17165    public Configuration getConfiguration() {
17166        Configuration ci;
17167        synchronized(this) {
17168            ci = new Configuration(mConfiguration);
17169            ci.userSetLocale = false;
17170        }
17171        return ci;
17172    }
17173
17174    @Override
17175    public void updatePersistentConfiguration(Configuration values) {
17176        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17177                "updateConfiguration()");
17178        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
17179                "updateConfiguration()");
17180        if (values == null) {
17181            throw new NullPointerException("Configuration must not be null");
17182        }
17183
17184        int userId = UserHandle.getCallingUserId();
17185
17186        synchronized(this) {
17187            final long origId = Binder.clearCallingIdentity();
17188            updateConfigurationLocked(values, null, false, true, userId);
17189            Binder.restoreCallingIdentity(origId);
17190        }
17191    }
17192
17193    public void updateConfiguration(Configuration values) {
17194        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17195                "updateConfiguration()");
17196
17197        synchronized(this) {
17198            if (values == null && mWindowManager != null) {
17199                // sentinel: fetch the current configuration from the window manager
17200                values = mWindowManager.computeNewConfiguration();
17201            }
17202
17203            if (mWindowManager != null) {
17204                mProcessList.applyDisplaySize(mWindowManager);
17205            }
17206
17207            final long origId = Binder.clearCallingIdentity();
17208            if (values != null) {
17209                Settings.System.clearConfiguration(values);
17210            }
17211            updateConfigurationLocked(values, null, false);
17212            Binder.restoreCallingIdentity(origId);
17213        }
17214    }
17215
17216    boolean updateConfigurationLocked(Configuration values,
17217            ActivityRecord starting, boolean initLocale) {
17218        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
17219        return updateConfigurationLocked(values, starting, initLocale, false,
17220                UserHandle.USER_NULL);
17221    }
17222
17223    /**
17224     * Do either or both things: (1) change the current configuration, and (2)
17225     * make sure the given activity is running with the (now) current
17226     * configuration.  Returns true if the activity has been left running, or
17227     * false if <var>starting</var> is being destroyed to match the new
17228     * configuration.
17229     *
17230     * @param userId is only used when persistent parameter is set to true to persist configuration
17231     *               for that particular user
17232     */
17233    boolean updateConfigurationLocked(Configuration values,
17234            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
17235        int changes = 0;
17236
17237        if (values != null) {
17238            Configuration newConfig = new Configuration(mConfiguration);
17239            changes = newConfig.updateFrom(values);
17240            if (changes != 0) {
17241                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
17242                        "Updating configuration to: " + values);
17243
17244                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
17245
17246                if (!initLocale && values.locale != null && values.userSetLocale) {
17247                    final String languageTag = values.locale.toLanguageTag();
17248                    SystemProperties.set("persist.sys.locale", languageTag);
17249                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
17250                            values.locale));
17251                }
17252
17253                mConfigurationSeq++;
17254                if (mConfigurationSeq <= 0) {
17255                    mConfigurationSeq = 1;
17256                }
17257                newConfig.seq = mConfigurationSeq;
17258                mConfiguration = newConfig;
17259                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
17260                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
17261                //mUsageStatsService.noteStartConfig(newConfig);
17262
17263                final Configuration configCopy = new Configuration(mConfiguration);
17264
17265                // TODO: If our config changes, should we auto dismiss any currently
17266                // showing dialogs?
17267                mShowDialogs = shouldShowDialogs(newConfig);
17268
17269                AttributeCache ac = AttributeCache.instance();
17270                if (ac != null) {
17271                    ac.updateConfiguration(configCopy);
17272                }
17273
17274                // Make sure all resources in our process are updated
17275                // right now, so that anyone who is going to retrieve
17276                // resource values after we return will be sure to get
17277                // the new ones.  This is especially important during
17278                // boot, where the first config change needs to guarantee
17279                // all resources have that config before following boot
17280                // code is executed.
17281                mSystemThread.applyConfigurationToResources(configCopy);
17282
17283                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
17284                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
17285                    msg.obj = new Configuration(configCopy);
17286                    msg.arg1 = userId;
17287                    mHandler.sendMessage(msg);
17288                }
17289
17290                for (int i=mLruProcesses.size()-1; i>=0; i--) {
17291                    ProcessRecord app = mLruProcesses.get(i);
17292                    try {
17293                        if (app.thread != null) {
17294                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
17295                                    + app.processName + " new config " + mConfiguration);
17296                            app.thread.scheduleConfigurationChanged(configCopy);
17297                        }
17298                    } catch (Exception e) {
17299                    }
17300                }
17301                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
17302                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17303                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
17304                        | Intent.FLAG_RECEIVER_FOREGROUND);
17305                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
17306                        null, AppOpsManager.OP_NONE, null, false, false,
17307                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17308                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
17309                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
17310                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17311                    if (!mProcessesReady) {
17312                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17313                    }
17314                    broadcastIntentLocked(null, null, intent,
17315                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17316                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17317                }
17318            }
17319        }
17320
17321        boolean kept = true;
17322        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
17323        // mainStack is null during startup.
17324        if (mainStack != null) {
17325            if (changes != 0 && starting == null) {
17326                // If the configuration changed, and the caller is not already
17327                // in the process of starting an activity, then find the top
17328                // activity to check if its configuration needs to change.
17329                starting = mainStack.topRunningActivityLocked(null);
17330            }
17331
17332            if (starting != null) {
17333                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
17334                // And we need to make sure at this point that all other activities
17335                // are made visible with the correct configuration.
17336                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
17337            }
17338        }
17339
17340        if (values != null && mWindowManager != null) {
17341            mWindowManager.setNewConfiguration(mConfiguration);
17342        }
17343
17344        return kept;
17345    }
17346
17347    /**
17348     * Decide based on the configuration whether we should shouw the ANR,
17349     * crash, etc dialogs.  The idea is that if there is no affordnace to
17350     * press the on-screen buttons, we shouldn't show the dialog.
17351     *
17352     * A thought: SystemUI might also want to get told about this, the Power
17353     * dialog / global actions also might want different behaviors.
17354     */
17355    private static final boolean shouldShowDialogs(Configuration config) {
17356        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
17357                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
17358                && config.navigation == Configuration.NAVIGATION_NONAV);
17359    }
17360
17361    @Override
17362    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
17363        synchronized (this) {
17364            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
17365            if (srec != null) {
17366                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
17367            }
17368        }
17369        return false;
17370    }
17371
17372    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
17373            Intent resultData) {
17374
17375        synchronized (this) {
17376            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
17377            if (r != null) {
17378                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
17379            }
17380            return false;
17381        }
17382    }
17383
17384    public int getLaunchedFromUid(IBinder activityToken) {
17385        ActivityRecord srec;
17386        synchronized (this) {
17387            srec = ActivityRecord.forTokenLocked(activityToken);
17388        }
17389        if (srec == null) {
17390            return -1;
17391        }
17392        return srec.launchedFromUid;
17393    }
17394
17395    public String getLaunchedFromPackage(IBinder activityToken) {
17396        ActivityRecord srec;
17397        synchronized (this) {
17398            srec = ActivityRecord.forTokenLocked(activityToken);
17399        }
17400        if (srec == null) {
17401            return null;
17402        }
17403        return srec.launchedFromPackage;
17404    }
17405
17406    // =========================================================
17407    // LIFETIME MANAGEMENT
17408    // =========================================================
17409
17410    // Returns which broadcast queue the app is the current [or imminent] receiver
17411    // on, or 'null' if the app is not an active broadcast recipient.
17412    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
17413        BroadcastRecord r = app.curReceiver;
17414        if (r != null) {
17415            return r.queue;
17416        }
17417
17418        // It's not the current receiver, but it might be starting up to become one
17419        synchronized (this) {
17420            for (BroadcastQueue queue : mBroadcastQueues) {
17421                r = queue.mPendingBroadcast;
17422                if (r != null && r.curApp == app) {
17423                    // found it; report which queue it's in
17424                    return queue;
17425                }
17426            }
17427        }
17428
17429        return null;
17430    }
17431
17432    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17433            ComponentName targetComponent, String targetProcess) {
17434        if (!mTrackingAssociations) {
17435            return null;
17436        }
17437        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17438                = mAssociations.get(targetUid);
17439        if (components == null) {
17440            components = new ArrayMap<>();
17441            mAssociations.put(targetUid, components);
17442        }
17443        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17444        if (sourceUids == null) {
17445            sourceUids = new SparseArray<>();
17446            components.put(targetComponent, sourceUids);
17447        }
17448        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17449        if (sourceProcesses == null) {
17450            sourceProcesses = new ArrayMap<>();
17451            sourceUids.put(sourceUid, sourceProcesses);
17452        }
17453        Association ass = sourceProcesses.get(sourceProcess);
17454        if (ass == null) {
17455            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
17456                    targetProcess);
17457            sourceProcesses.put(sourceProcess, ass);
17458        }
17459        ass.mCount++;
17460        ass.mNesting++;
17461        if (ass.mNesting == 1) {
17462            ass.mStartTime = SystemClock.uptimeMillis();
17463        }
17464        return ass;
17465    }
17466
17467    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17468            ComponentName targetComponent) {
17469        if (!mTrackingAssociations) {
17470            return;
17471        }
17472        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17473                = mAssociations.get(targetUid);
17474        if (components == null) {
17475            return;
17476        }
17477        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17478        if (sourceUids == null) {
17479            return;
17480        }
17481        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17482        if (sourceProcesses == null) {
17483            return;
17484        }
17485        Association ass = sourceProcesses.get(sourceProcess);
17486        if (ass == null || ass.mNesting <= 0) {
17487            return;
17488        }
17489        ass.mNesting--;
17490        if (ass.mNesting == 0) {
17491            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
17492        }
17493    }
17494
17495    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
17496            boolean doingAll, long now) {
17497        if (mAdjSeq == app.adjSeq) {
17498            // This adjustment has already been computed.
17499            return app.curRawAdj;
17500        }
17501
17502        if (app.thread == null) {
17503            app.adjSeq = mAdjSeq;
17504            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17505            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17506            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
17507        }
17508
17509        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
17510        app.adjSource = null;
17511        app.adjTarget = null;
17512        app.empty = false;
17513        app.cached = false;
17514
17515        final int activitiesSize = app.activities.size();
17516
17517        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17518            // The max adjustment doesn't allow this app to be anything
17519            // below foreground, so it is not worth doing work for it.
17520            app.adjType = "fixed";
17521            app.adjSeq = mAdjSeq;
17522            app.curRawAdj = app.maxAdj;
17523            app.foregroundActivities = false;
17524            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
17525            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
17526            // System processes can do UI, and when they do we want to have
17527            // them trim their memory after the user leaves the UI.  To
17528            // facilitate this, here we need to determine whether or not it
17529            // is currently showing UI.
17530            app.systemNoUi = true;
17531            if (app == TOP_APP) {
17532                app.systemNoUi = false;
17533            } else if (activitiesSize > 0) {
17534                for (int j = 0; j < activitiesSize; j++) {
17535                    final ActivityRecord r = app.activities.get(j);
17536                    if (r.visible) {
17537                        app.systemNoUi = false;
17538                    }
17539                }
17540            }
17541            if (!app.systemNoUi) {
17542                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
17543            }
17544            return (app.curAdj=app.maxAdj);
17545        }
17546
17547        app.systemNoUi = false;
17548
17549        final int PROCESS_STATE_TOP = mTopProcessState;
17550
17551        // Determine the importance of the process, starting with most
17552        // important to least, and assign an appropriate OOM adjustment.
17553        int adj;
17554        int schedGroup;
17555        int procState;
17556        boolean foregroundActivities = false;
17557        BroadcastQueue queue;
17558        if (app == TOP_APP) {
17559            // The last app on the list is the foreground app.
17560            adj = ProcessList.FOREGROUND_APP_ADJ;
17561            schedGroup = Process.THREAD_GROUP_DEFAULT;
17562            app.adjType = "top-activity";
17563            foregroundActivities = true;
17564            procState = PROCESS_STATE_TOP;
17565        } else if (app.instrumentationClass != null) {
17566            // Don't want to kill running instrumentation.
17567            adj = ProcessList.FOREGROUND_APP_ADJ;
17568            schedGroup = Process.THREAD_GROUP_DEFAULT;
17569            app.adjType = "instrumentation";
17570            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17571        } else if ((queue = isReceivingBroadcast(app)) != null) {
17572            // An app that is currently receiving a broadcast also
17573            // counts as being in the foreground for OOM killer purposes.
17574            // It's placed in a sched group based on the nature of the
17575            // broadcast as reflected by which queue it's active in.
17576            adj = ProcessList.FOREGROUND_APP_ADJ;
17577            schedGroup = (queue == mFgBroadcastQueue)
17578                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17579            app.adjType = "broadcast";
17580            procState = ActivityManager.PROCESS_STATE_RECEIVER;
17581        } else if (app.executingServices.size() > 0) {
17582            // An app that is currently executing a service callback also
17583            // counts as being in the foreground.
17584            adj = ProcessList.FOREGROUND_APP_ADJ;
17585            schedGroup = app.execServicesFg ?
17586                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17587            app.adjType = "exec-service";
17588            procState = ActivityManager.PROCESS_STATE_SERVICE;
17589            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
17590        } else {
17591            // As far as we know the process is empty.  We may change our mind later.
17592            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17593            // At this point we don't actually know the adjustment.  Use the cached adj
17594            // value that the caller wants us to.
17595            adj = cachedAdj;
17596            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17597            app.cached = true;
17598            app.empty = true;
17599            app.adjType = "cch-empty";
17600        }
17601
17602        // Examine all activities if not already foreground.
17603        if (!foregroundActivities && activitiesSize > 0) {
17604            for (int j = 0; j < activitiesSize; j++) {
17605                final ActivityRecord r = app.activities.get(j);
17606                if (r.app != app) {
17607                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
17608                            + app + "?!? Using " + r.app + " instead.");
17609                    continue;
17610                }
17611                if (r.visible) {
17612                    // App has a visible activity; only upgrade adjustment.
17613                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17614                        adj = ProcessList.VISIBLE_APP_ADJ;
17615                        app.adjType = "visible";
17616                    }
17617                    if (procState > PROCESS_STATE_TOP) {
17618                        procState = PROCESS_STATE_TOP;
17619                    }
17620                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17621                    app.cached = false;
17622                    app.empty = false;
17623                    foregroundActivities = true;
17624                    break;
17625                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
17626                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17627                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17628                        app.adjType = "pausing";
17629                    }
17630                    if (procState > PROCESS_STATE_TOP) {
17631                        procState = PROCESS_STATE_TOP;
17632                    }
17633                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17634                    app.cached = false;
17635                    app.empty = false;
17636                    foregroundActivities = true;
17637                } else if (r.state == ActivityState.STOPPING) {
17638                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17639                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17640                        app.adjType = "stopping";
17641                    }
17642                    // For the process state, we will at this point consider the
17643                    // process to be cached.  It will be cached either as an activity
17644                    // or empty depending on whether the activity is finishing.  We do
17645                    // this so that we can treat the process as cached for purposes of
17646                    // memory trimming (determing current memory level, trim command to
17647                    // send to process) since there can be an arbitrary number of stopping
17648                    // processes and they should soon all go into the cached state.
17649                    if (!r.finishing) {
17650                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17651                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17652                        }
17653                    }
17654                    app.cached = false;
17655                    app.empty = false;
17656                    foregroundActivities = true;
17657                } else {
17658                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17659                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17660                        app.adjType = "cch-act";
17661                    }
17662                }
17663            }
17664        }
17665
17666        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17667            if (app.foregroundServices) {
17668                // The user is aware of this app, so make it visible.
17669                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17670                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17671                app.cached = false;
17672                app.adjType = "fg-service";
17673                schedGroup = Process.THREAD_GROUP_DEFAULT;
17674            } else if (app.forcingToForeground != null) {
17675                // The user is aware of this app, so make it visible.
17676                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17677                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17678                app.cached = false;
17679                app.adjType = "force-fg";
17680                app.adjSource = app.forcingToForeground;
17681                schedGroup = Process.THREAD_GROUP_DEFAULT;
17682            }
17683        }
17684
17685        if (app == mHeavyWeightProcess) {
17686            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
17687                // We don't want to kill the current heavy-weight process.
17688                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
17689                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17690                app.cached = false;
17691                app.adjType = "heavy";
17692            }
17693            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17694                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
17695            }
17696        }
17697
17698        if (app == mHomeProcess) {
17699            if (adj > ProcessList.HOME_APP_ADJ) {
17700                // This process is hosting what we currently consider to be the
17701                // home app, so we don't want to let it go into the background.
17702                adj = ProcessList.HOME_APP_ADJ;
17703                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17704                app.cached = false;
17705                app.adjType = "home";
17706            }
17707            if (procState > ActivityManager.PROCESS_STATE_HOME) {
17708                procState = ActivityManager.PROCESS_STATE_HOME;
17709            }
17710        }
17711
17712        if (app == mPreviousProcess && app.activities.size() > 0) {
17713            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
17714                // This was the previous process that showed UI to the user.
17715                // We want to try to keep it around more aggressively, to give
17716                // a good experience around switching between two apps.
17717                adj = ProcessList.PREVIOUS_APP_ADJ;
17718                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17719                app.cached = false;
17720                app.adjType = "previous";
17721            }
17722            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17723                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17724            }
17725        }
17726
17727        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
17728                + " reason=" + app.adjType);
17729
17730        // By default, we use the computed adjustment.  It may be changed if
17731        // there are applications dependent on our services or providers, but
17732        // this gives us a baseline and makes sure we don't get into an
17733        // infinite recursion.
17734        app.adjSeq = mAdjSeq;
17735        app.curRawAdj = adj;
17736        app.hasStartedServices = false;
17737
17738        if (mBackupTarget != null && app == mBackupTarget.app) {
17739            // If possible we want to avoid killing apps while they're being backed up
17740            if (adj > ProcessList.BACKUP_APP_ADJ) {
17741                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
17742                adj = ProcessList.BACKUP_APP_ADJ;
17743                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17744                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17745                }
17746                app.adjType = "backup";
17747                app.cached = false;
17748            }
17749            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
17750                procState = ActivityManager.PROCESS_STATE_BACKUP;
17751            }
17752        }
17753
17754        boolean mayBeTop = false;
17755
17756        for (int is = app.services.size()-1;
17757                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17758                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17759                        || procState > ActivityManager.PROCESS_STATE_TOP);
17760                is--) {
17761            ServiceRecord s = app.services.valueAt(is);
17762            if (s.startRequested) {
17763                app.hasStartedServices = true;
17764                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
17765                    procState = ActivityManager.PROCESS_STATE_SERVICE;
17766                }
17767                if (app.hasShownUi && app != mHomeProcess) {
17768                    // If this process has shown some UI, let it immediately
17769                    // go to the LRU list because it may be pretty heavy with
17770                    // UI stuff.  We'll tag it with a label just to help
17771                    // debug and understand what is going on.
17772                    if (adj > ProcessList.SERVICE_ADJ) {
17773                        app.adjType = "cch-started-ui-services";
17774                    }
17775                } else {
17776                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17777                        // This service has seen some activity within
17778                        // recent memory, so we will keep its process ahead
17779                        // of the background processes.
17780                        if (adj > ProcessList.SERVICE_ADJ) {
17781                            adj = ProcessList.SERVICE_ADJ;
17782                            app.adjType = "started-services";
17783                            app.cached = false;
17784                        }
17785                    }
17786                    // If we have let the service slide into the background
17787                    // state, still have some text describing what it is doing
17788                    // even though the service no longer has an impact.
17789                    if (adj > ProcessList.SERVICE_ADJ) {
17790                        app.adjType = "cch-started-services";
17791                    }
17792                }
17793            }
17794            for (int conni = s.connections.size()-1;
17795                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17796                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17797                            || procState > ActivityManager.PROCESS_STATE_TOP);
17798                    conni--) {
17799                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17800                for (int i = 0;
17801                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17802                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17803                                || procState > ActivityManager.PROCESS_STATE_TOP);
17804                        i++) {
17805                    // XXX should compute this based on the max of
17806                    // all connected clients.
17807                    ConnectionRecord cr = clist.get(i);
17808                    if (cr.binding.client == app) {
17809                        // Binding to ourself is not interesting.
17810                        continue;
17811                    }
17812                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17813                        ProcessRecord client = cr.binding.client;
17814                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
17815                                TOP_APP, doingAll, now);
17816                        int clientProcState = client.curProcState;
17817                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17818                            // If the other app is cached for any reason, for purposes here
17819                            // we are going to consider it empty.  The specific cached state
17820                            // doesn't propagate except under certain conditions.
17821                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17822                        }
17823                        String adjType = null;
17824                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17825                            // Not doing bind OOM management, so treat
17826                            // this guy more like a started service.
17827                            if (app.hasShownUi && app != mHomeProcess) {
17828                                // If this process has shown some UI, let it immediately
17829                                // go to the LRU list because it may be pretty heavy with
17830                                // UI stuff.  We'll tag it with a label just to help
17831                                // debug and understand what is going on.
17832                                if (adj > clientAdj) {
17833                                    adjType = "cch-bound-ui-services";
17834                                }
17835                                app.cached = false;
17836                                clientAdj = adj;
17837                                clientProcState = procState;
17838                            } else {
17839                                if (now >= (s.lastActivity
17840                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17841                                    // This service has not seen activity within
17842                                    // recent memory, so allow it to drop to the
17843                                    // LRU list if there is no other reason to keep
17844                                    // it around.  We'll also tag it with a label just
17845                                    // to help debug and undertand what is going on.
17846                                    if (adj > clientAdj) {
17847                                        adjType = "cch-bound-services";
17848                                    }
17849                                    clientAdj = adj;
17850                                }
17851                            }
17852                        }
17853                        if (adj > clientAdj) {
17854                            // If this process has recently shown UI, and
17855                            // the process that is binding to it is less
17856                            // important than being visible, then we don't
17857                            // care about the binding as much as we care
17858                            // about letting this process get into the LRU
17859                            // list to be killed and restarted if needed for
17860                            // memory.
17861                            if (app.hasShownUi && app != mHomeProcess
17862                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17863                                adjType = "cch-bound-ui-services";
17864                            } else {
17865                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17866                                        |Context.BIND_IMPORTANT)) != 0) {
17867                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17868                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17869                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17870                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17871                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17872                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17873                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17874                                    adj = clientAdj;
17875                                } else {
17876                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17877                                        adj = ProcessList.VISIBLE_APP_ADJ;
17878                                    }
17879                                }
17880                                if (!client.cached) {
17881                                    app.cached = false;
17882                                }
17883                                adjType = "service";
17884                            }
17885                        }
17886                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17887                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17888                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17889                            }
17890                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17891                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17892                                    // Special handling of clients who are in the top state.
17893                                    // We *may* want to consider this process to be in the
17894                                    // top state as well, but only if there is not another
17895                                    // reason for it to be running.  Being on the top is a
17896                                    // special state, meaning you are specifically running
17897                                    // for the current top app.  If the process is already
17898                                    // running in the background for some other reason, it
17899                                    // is more important to continue considering it to be
17900                                    // in the background state.
17901                                    mayBeTop = true;
17902                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17903                                } else {
17904                                    // Special handling for above-top states (persistent
17905                                    // processes).  These should not bring the current process
17906                                    // into the top state, since they are not on top.  Instead
17907                                    // give them the best state after that.
17908                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
17909                                        clientProcState =
17910                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
17911                                    } else if (mWakefulness
17912                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
17913                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
17914                                                    != 0) {
17915                                        clientProcState =
17916                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
17917                                    } else {
17918                                        clientProcState =
17919                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17920                                    }
17921                                }
17922                            }
17923                        } else {
17924                            if (clientProcState <
17925                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17926                                clientProcState =
17927                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17928                            }
17929                        }
17930                        if (procState > clientProcState) {
17931                            procState = clientProcState;
17932                        }
17933                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17934                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17935                            app.pendingUiClean = true;
17936                        }
17937                        if (adjType != null) {
17938                            app.adjType = adjType;
17939                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17940                                    .REASON_SERVICE_IN_USE;
17941                            app.adjSource = cr.binding.client;
17942                            app.adjSourceProcState = clientProcState;
17943                            app.adjTarget = s.name;
17944                        }
17945                    }
17946                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17947                        app.treatLikeActivity = true;
17948                    }
17949                    final ActivityRecord a = cr.activity;
17950                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17951                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17952                                (a.visible || a.state == ActivityState.RESUMED
17953                                 || a.state == ActivityState.PAUSING)) {
17954                            adj = ProcessList.FOREGROUND_APP_ADJ;
17955                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17956                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17957                            }
17958                            app.cached = false;
17959                            app.adjType = "service";
17960                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17961                                    .REASON_SERVICE_IN_USE;
17962                            app.adjSource = a;
17963                            app.adjSourceProcState = procState;
17964                            app.adjTarget = s.name;
17965                        }
17966                    }
17967                }
17968            }
17969        }
17970
17971        for (int provi = app.pubProviders.size()-1;
17972                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17973                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17974                        || procState > ActivityManager.PROCESS_STATE_TOP);
17975                provi--) {
17976            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17977            for (int i = cpr.connections.size()-1;
17978                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17979                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17980                            || procState > ActivityManager.PROCESS_STATE_TOP);
17981                    i--) {
17982                ContentProviderConnection conn = cpr.connections.get(i);
17983                ProcessRecord client = conn.client;
17984                if (client == app) {
17985                    // Being our own client is not interesting.
17986                    continue;
17987                }
17988                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17989                int clientProcState = client.curProcState;
17990                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17991                    // If the other app is cached for any reason, for purposes here
17992                    // we are going to consider it empty.
17993                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17994                }
17995                if (adj > clientAdj) {
17996                    if (app.hasShownUi && app != mHomeProcess
17997                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17998                        app.adjType = "cch-ui-provider";
17999                    } else {
18000                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18001                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18002                        app.adjType = "provider";
18003                    }
18004                    app.cached &= client.cached;
18005                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18006                            .REASON_PROVIDER_IN_USE;
18007                    app.adjSource = client;
18008                    app.adjSourceProcState = clientProcState;
18009                    app.adjTarget = cpr.name;
18010                }
18011                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18012                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18013                        // Special handling of clients who are in the top state.
18014                        // We *may* want to consider this process to be in the
18015                        // top state as well, but only if there is not another
18016                        // reason for it to be running.  Being on the top is a
18017                        // special state, meaning you are specifically running
18018                        // for the current top app.  If the process is already
18019                        // running in the background for some other reason, it
18020                        // is more important to continue considering it to be
18021                        // in the background state.
18022                        mayBeTop = true;
18023                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18024                    } else {
18025                        // Special handling for above-top states (persistent
18026                        // processes).  These should not bring the current process
18027                        // into the top state, since they are not on top.  Instead
18028                        // give them the best state after that.
18029                        clientProcState =
18030                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18031                    }
18032                }
18033                if (procState > clientProcState) {
18034                    procState = clientProcState;
18035                }
18036                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18037                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18038                }
18039            }
18040            // If the provider has external (non-framework) process
18041            // dependencies, ensure that its adjustment is at least
18042            // FOREGROUND_APP_ADJ.
18043            if (cpr.hasExternalProcessHandles()) {
18044                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
18045                    adj = ProcessList.FOREGROUND_APP_ADJ;
18046                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18047                    app.cached = false;
18048                    app.adjType = "provider";
18049                    app.adjTarget = cpr.name;
18050                }
18051                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18052                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18053                }
18054            }
18055        }
18056
18057        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
18058            // A client of one of our services or providers is in the top state.  We
18059            // *may* want to be in the top state, but not if we are already running in
18060            // the background for some other reason.  For the decision here, we are going
18061            // to pick out a few specific states that we want to remain in when a client
18062            // is top (states that tend to be longer-term) and otherwise allow it to go
18063            // to the top state.
18064            switch (procState) {
18065                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
18066                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
18067                case ActivityManager.PROCESS_STATE_SERVICE:
18068                    // These all are longer-term states, so pull them up to the top
18069                    // of the background states, but not all the way to the top state.
18070                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18071                    break;
18072                default:
18073                    // Otherwise, top is a better choice, so take it.
18074                    procState = ActivityManager.PROCESS_STATE_TOP;
18075                    break;
18076            }
18077        }
18078
18079        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
18080            if (app.hasClientActivities) {
18081                // This is a cached process, but with client activities.  Mark it so.
18082                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
18083                app.adjType = "cch-client-act";
18084            } else if (app.treatLikeActivity) {
18085                // This is a cached process, but somebody wants us to treat it like it has
18086                // an activity, okay!
18087                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18088                app.adjType = "cch-as-act";
18089            }
18090        }
18091
18092        if (adj == ProcessList.SERVICE_ADJ) {
18093            if (doingAll) {
18094                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
18095                mNewNumServiceProcs++;
18096                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
18097                if (!app.serviceb) {
18098                    // This service isn't far enough down on the LRU list to
18099                    // normally be a B service, but if we are low on RAM and it
18100                    // is large we want to force it down since we would prefer to
18101                    // keep launcher over it.
18102                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
18103                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
18104                        app.serviceHighRam = true;
18105                        app.serviceb = true;
18106                        //Slog.i(TAG, "ADJ " + app + " high ram!");
18107                    } else {
18108                        mNewNumAServiceProcs++;
18109                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
18110                    }
18111                } else {
18112                    app.serviceHighRam = false;
18113                }
18114            }
18115            if (app.serviceb) {
18116                adj = ProcessList.SERVICE_B_ADJ;
18117            }
18118        }
18119
18120        app.curRawAdj = adj;
18121
18122        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
18123        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
18124        if (adj > app.maxAdj) {
18125            adj = app.maxAdj;
18126            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
18127                schedGroup = Process.THREAD_GROUP_DEFAULT;
18128            }
18129        }
18130
18131        // Do final modification to adj.  Everything we do between here and applying
18132        // the final setAdj must be done in this function, because we will also use
18133        // it when computing the final cached adj later.  Note that we don't need to
18134        // worry about this for max adj above, since max adj will always be used to
18135        // keep it out of the cached vaues.
18136        app.curAdj = app.modifyRawOomAdj(adj);
18137        app.curSchedGroup = schedGroup;
18138        app.curProcState = procState;
18139        app.foregroundActivities = foregroundActivities;
18140
18141        return app.curRawAdj;
18142    }
18143
18144    /**
18145     * Record new PSS sample for a process.
18146     */
18147    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long now) {
18148        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024);
18149        proc.lastPssTime = now;
18150        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
18151        if (DEBUG_PSS) Slog.d(TAG_PSS,
18152                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
18153                + " state=" + ProcessList.makeProcStateString(procState));
18154        if (proc.initialIdlePss == 0) {
18155            proc.initialIdlePss = pss;
18156        }
18157        proc.lastPss = pss;
18158        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
18159            proc.lastCachedPss = pss;
18160        }
18161
18162        final SparseArray<Pair<Long, String>> watchUids
18163                = mMemWatchProcesses.getMap().get(proc.processName);
18164        Long check = null;
18165        if (watchUids != null) {
18166            Pair<Long, String> val = watchUids.get(proc.uid);
18167            if (val == null) {
18168                val = watchUids.get(0);
18169            }
18170            if (val != null) {
18171                check = val.first;
18172            }
18173        }
18174        if (check != null) {
18175            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
18176                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18177                if (!isDebuggable) {
18178                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
18179                        isDebuggable = true;
18180                    }
18181                }
18182                if (isDebuggable) {
18183                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
18184                    final ProcessRecord myProc = proc;
18185                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
18186                    mMemWatchDumpProcName = proc.processName;
18187                    mMemWatchDumpFile = heapdumpFile.toString();
18188                    mMemWatchDumpPid = proc.pid;
18189                    mMemWatchDumpUid = proc.uid;
18190                    BackgroundThread.getHandler().post(new Runnable() {
18191                        @Override
18192                        public void run() {
18193                            revokeUriPermission(ActivityThread.currentActivityThread()
18194                                            .getApplicationThread(),
18195                                    DumpHeapActivity.JAVA_URI,
18196                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
18197                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
18198                                    UserHandle.myUserId());
18199                            ParcelFileDescriptor fd = null;
18200                            try {
18201                                heapdumpFile.delete();
18202                                fd = ParcelFileDescriptor.open(heapdumpFile,
18203                                        ParcelFileDescriptor.MODE_CREATE |
18204                                                ParcelFileDescriptor.MODE_TRUNCATE |
18205                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
18206                                                ParcelFileDescriptor.MODE_APPEND);
18207                                IApplicationThread thread = myProc.thread;
18208                                if (thread != null) {
18209                                    try {
18210                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
18211                                                "Requesting dump heap from "
18212                                                + myProc + " to " + heapdumpFile);
18213                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
18214                                    } catch (RemoteException e) {
18215                                    }
18216                                }
18217                            } catch (FileNotFoundException e) {
18218                                e.printStackTrace();
18219                            } finally {
18220                                if (fd != null) {
18221                                    try {
18222                                        fd.close();
18223                                    } catch (IOException e) {
18224                                    }
18225                                }
18226                            }
18227                        }
18228                    });
18229                } else {
18230                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
18231                            + ", but debugging not enabled");
18232                }
18233            }
18234        }
18235    }
18236
18237    /**
18238     * Schedule PSS collection of a process.
18239     */
18240    void requestPssLocked(ProcessRecord proc, int procState) {
18241        if (mPendingPssProcesses.contains(proc)) {
18242            return;
18243        }
18244        if (mPendingPssProcesses.size() == 0) {
18245            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18246        }
18247        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
18248        proc.pssProcState = procState;
18249        mPendingPssProcesses.add(proc);
18250    }
18251
18252    /**
18253     * Schedule PSS collection of all processes.
18254     */
18255    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
18256        if (!always) {
18257            if (now < (mLastFullPssTime +
18258                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
18259                return;
18260            }
18261        }
18262        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
18263        mLastFullPssTime = now;
18264        mFullPssPending = true;
18265        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
18266        mPendingPssProcesses.clear();
18267        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18268            ProcessRecord app = mLruProcesses.get(i);
18269            if (app.thread == null
18270                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
18271                continue;
18272            }
18273            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
18274                app.pssProcState = app.setProcState;
18275                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18276                        mTestPssMode, isSleeping(), now);
18277                mPendingPssProcesses.add(app);
18278            }
18279        }
18280        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18281    }
18282
18283    public void setTestPssMode(boolean enabled) {
18284        synchronized (this) {
18285            mTestPssMode = enabled;
18286            if (enabled) {
18287                // Whenever we enable the mode, we want to take a snapshot all of current
18288                // process mem use.
18289                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
18290            }
18291        }
18292    }
18293
18294    /**
18295     * Ask a given process to GC right now.
18296     */
18297    final void performAppGcLocked(ProcessRecord app) {
18298        try {
18299            app.lastRequestedGc = SystemClock.uptimeMillis();
18300            if (app.thread != null) {
18301                if (app.reportLowMemory) {
18302                    app.reportLowMemory = false;
18303                    app.thread.scheduleLowMemory();
18304                } else {
18305                    app.thread.processInBackground();
18306                }
18307            }
18308        } catch (Exception e) {
18309            // whatever.
18310        }
18311    }
18312
18313    /**
18314     * Returns true if things are idle enough to perform GCs.
18315     */
18316    private final boolean canGcNowLocked() {
18317        boolean processingBroadcasts = false;
18318        for (BroadcastQueue q : mBroadcastQueues) {
18319            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
18320                processingBroadcasts = true;
18321            }
18322        }
18323        return !processingBroadcasts
18324                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
18325    }
18326
18327    /**
18328     * Perform GCs on all processes that are waiting for it, but only
18329     * if things are idle.
18330     */
18331    final void performAppGcsLocked() {
18332        final int N = mProcessesToGc.size();
18333        if (N <= 0) {
18334            return;
18335        }
18336        if (canGcNowLocked()) {
18337            while (mProcessesToGc.size() > 0) {
18338                ProcessRecord proc = mProcessesToGc.remove(0);
18339                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
18340                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
18341                            <= SystemClock.uptimeMillis()) {
18342                        // To avoid spamming the system, we will GC processes one
18343                        // at a time, waiting a few seconds between each.
18344                        performAppGcLocked(proc);
18345                        scheduleAppGcsLocked();
18346                        return;
18347                    } else {
18348                        // It hasn't been long enough since we last GCed this
18349                        // process...  put it in the list to wait for its time.
18350                        addProcessToGcListLocked(proc);
18351                        break;
18352                    }
18353                }
18354            }
18355
18356            scheduleAppGcsLocked();
18357        }
18358    }
18359
18360    /**
18361     * If all looks good, perform GCs on all processes waiting for them.
18362     */
18363    final void performAppGcsIfAppropriateLocked() {
18364        if (canGcNowLocked()) {
18365            performAppGcsLocked();
18366            return;
18367        }
18368        // Still not idle, wait some more.
18369        scheduleAppGcsLocked();
18370    }
18371
18372    /**
18373     * Schedule the execution of all pending app GCs.
18374     */
18375    final void scheduleAppGcsLocked() {
18376        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
18377
18378        if (mProcessesToGc.size() > 0) {
18379            // Schedule a GC for the time to the next process.
18380            ProcessRecord proc = mProcessesToGc.get(0);
18381            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
18382
18383            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
18384            long now = SystemClock.uptimeMillis();
18385            if (when < (now+GC_TIMEOUT)) {
18386                when = now + GC_TIMEOUT;
18387            }
18388            mHandler.sendMessageAtTime(msg, when);
18389        }
18390    }
18391
18392    /**
18393     * Add a process to the array of processes waiting to be GCed.  Keeps the
18394     * list in sorted order by the last GC time.  The process can't already be
18395     * on the list.
18396     */
18397    final void addProcessToGcListLocked(ProcessRecord proc) {
18398        boolean added = false;
18399        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
18400            if (mProcessesToGc.get(i).lastRequestedGc <
18401                    proc.lastRequestedGc) {
18402                added = true;
18403                mProcessesToGc.add(i+1, proc);
18404                break;
18405            }
18406        }
18407        if (!added) {
18408            mProcessesToGc.add(0, proc);
18409        }
18410    }
18411
18412    /**
18413     * Set up to ask a process to GC itself.  This will either do it
18414     * immediately, or put it on the list of processes to gc the next
18415     * time things are idle.
18416     */
18417    final void scheduleAppGcLocked(ProcessRecord app) {
18418        long now = SystemClock.uptimeMillis();
18419        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
18420            return;
18421        }
18422        if (!mProcessesToGc.contains(app)) {
18423            addProcessToGcListLocked(app);
18424            scheduleAppGcsLocked();
18425        }
18426    }
18427
18428    final void checkExcessivePowerUsageLocked(boolean doKills) {
18429        updateCpuStatsNow();
18430
18431        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18432        boolean doWakeKills = doKills;
18433        boolean doCpuKills = doKills;
18434        if (mLastPowerCheckRealtime == 0) {
18435            doWakeKills = false;
18436        }
18437        if (mLastPowerCheckUptime == 0) {
18438            doCpuKills = false;
18439        }
18440        if (stats.isScreenOn()) {
18441            doWakeKills = false;
18442        }
18443        final long curRealtime = SystemClock.elapsedRealtime();
18444        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
18445        final long curUptime = SystemClock.uptimeMillis();
18446        final long uptimeSince = curUptime - mLastPowerCheckUptime;
18447        mLastPowerCheckRealtime = curRealtime;
18448        mLastPowerCheckUptime = curUptime;
18449        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
18450            doWakeKills = false;
18451        }
18452        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
18453            doCpuKills = false;
18454        }
18455        int i = mLruProcesses.size();
18456        while (i > 0) {
18457            i--;
18458            ProcessRecord app = mLruProcesses.get(i);
18459            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18460                long wtime;
18461                synchronized (stats) {
18462                    wtime = stats.getProcessWakeTime(app.info.uid,
18463                            app.pid, curRealtime);
18464                }
18465                long wtimeUsed = wtime - app.lastWakeTime;
18466                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
18467                if (DEBUG_POWER) {
18468                    StringBuilder sb = new StringBuilder(128);
18469                    sb.append("Wake for ");
18470                    app.toShortString(sb);
18471                    sb.append(": over ");
18472                    TimeUtils.formatDuration(realtimeSince, sb);
18473                    sb.append(" used ");
18474                    TimeUtils.formatDuration(wtimeUsed, sb);
18475                    sb.append(" (");
18476                    sb.append((wtimeUsed*100)/realtimeSince);
18477                    sb.append("%)");
18478                    Slog.i(TAG_POWER, sb.toString());
18479                    sb.setLength(0);
18480                    sb.append("CPU for ");
18481                    app.toShortString(sb);
18482                    sb.append(": over ");
18483                    TimeUtils.formatDuration(uptimeSince, sb);
18484                    sb.append(" used ");
18485                    TimeUtils.formatDuration(cputimeUsed, sb);
18486                    sb.append(" (");
18487                    sb.append((cputimeUsed*100)/uptimeSince);
18488                    sb.append("%)");
18489                    Slog.i(TAG_POWER, sb.toString());
18490                }
18491                // If a process has held a wake lock for more
18492                // than 50% of the time during this period,
18493                // that sounds bad.  Kill!
18494                if (doWakeKills && realtimeSince > 0
18495                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
18496                    synchronized (stats) {
18497                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
18498                                realtimeSince, wtimeUsed);
18499                    }
18500                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
18501                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
18502                } else if (doCpuKills && uptimeSince > 0
18503                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
18504                    synchronized (stats) {
18505                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
18506                                uptimeSince, cputimeUsed);
18507                    }
18508                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
18509                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
18510                } else {
18511                    app.lastWakeTime = wtime;
18512                    app.lastCpuTime = app.curCpuTime;
18513                }
18514            }
18515        }
18516    }
18517
18518    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now) {
18519        boolean success = true;
18520
18521        if (app.curRawAdj != app.setRawAdj) {
18522            app.setRawAdj = app.curRawAdj;
18523        }
18524
18525        int changes = 0;
18526
18527        if (app.curAdj != app.setAdj) {
18528            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
18529            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18530                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
18531                    + app.adjType);
18532            app.setAdj = app.curAdj;
18533        }
18534
18535        if (app.setSchedGroup != app.curSchedGroup) {
18536            app.setSchedGroup = app.curSchedGroup;
18537            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18538                    "Setting process group of " + app.processName
18539                    + " to " + app.curSchedGroup);
18540            if (app.waitingToKill != null && app.curReceiver == null
18541                    && app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
18542                app.kill(app.waitingToKill, true);
18543                success = false;
18544            } else {
18545                if (true) {
18546                    long oldId = Binder.clearCallingIdentity();
18547                    try {
18548                        Process.setProcessGroup(app.pid, app.curSchedGroup);
18549                    } catch (Exception e) {
18550                        Slog.w(TAG, "Failed setting process group of " + app.pid
18551                                + " to " + app.curSchedGroup);
18552                        e.printStackTrace();
18553                    } finally {
18554                        Binder.restoreCallingIdentity(oldId);
18555                    }
18556                } else {
18557                    if (app.thread != null) {
18558                        try {
18559                            app.thread.setSchedulingGroup(app.curSchedGroup);
18560                        } catch (RemoteException e) {
18561                        }
18562                    }
18563                }
18564                Process.setSwappiness(app.pid,
18565                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
18566            }
18567        }
18568        if (app.repForegroundActivities != app.foregroundActivities) {
18569            app.repForegroundActivities = app.foregroundActivities;
18570            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
18571        }
18572        if (app.repProcState != app.curProcState) {
18573            app.repProcState = app.curProcState;
18574            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
18575            if (app.thread != null) {
18576                try {
18577                    if (false) {
18578                        //RuntimeException h = new RuntimeException("here");
18579                        Slog.i(TAG, "Sending new process state " + app.repProcState
18580                                + " to " + app /*, h*/);
18581                    }
18582                    app.thread.setProcessState(app.repProcState);
18583                } catch (RemoteException e) {
18584                }
18585            }
18586        }
18587        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
18588                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
18589            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
18590                // Experimental code to more aggressively collect pss while
18591                // running test...  the problem is that this tends to collect
18592                // the data right when a process is transitioning between process
18593                // states, which well tend to give noisy data.
18594                long start = SystemClock.uptimeMillis();
18595                long pss = Debug.getPss(app.pid, mTmpLong, null);
18596                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], now);
18597                mPendingPssProcesses.remove(app);
18598                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
18599                        + " to " + app.curProcState + ": "
18600                        + (SystemClock.uptimeMillis()-start) + "ms");
18601            }
18602            app.lastStateTime = now;
18603            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18604                    mTestPssMode, isSleeping(), now);
18605            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
18606                    + ProcessList.makeProcStateString(app.setProcState) + " to "
18607                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
18608                    + (app.nextPssTime-now) + ": " + app);
18609        } else {
18610            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
18611                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
18612                    mTestPssMode)))) {
18613                requestPssLocked(app, app.setProcState);
18614                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
18615                        mTestPssMode, isSleeping(), now);
18616            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
18617                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
18618        }
18619        if (app.setProcState != app.curProcState) {
18620            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18621                    "Proc state change of " + app.processName
18622                    + " to " + app.curProcState);
18623            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
18624            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
18625            if (setImportant && !curImportant) {
18626                // This app is no longer something we consider important enough to allow to
18627                // use arbitrary amounts of battery power.  Note
18628                // its current wake lock time to later know to kill it if
18629                // it is not behaving well.
18630                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18631                synchronized (stats) {
18632                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
18633                            app.pid, SystemClock.elapsedRealtime());
18634                }
18635                app.lastCpuTime = app.curCpuTime;
18636
18637            }
18638            // Inform UsageStats of important process state change
18639            // Must be called before updating setProcState
18640            maybeUpdateUsageStatsLocked(app);
18641
18642            app.setProcState = app.curProcState;
18643            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18644                app.notCachedSinceIdle = false;
18645            }
18646            if (!doingAll) {
18647                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
18648            } else {
18649                app.procStateChanged = true;
18650            }
18651        }
18652
18653        if (changes != 0) {
18654            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18655                    "Changes in " + app + ": " + changes);
18656            int i = mPendingProcessChanges.size()-1;
18657            ProcessChangeItem item = null;
18658            while (i >= 0) {
18659                item = mPendingProcessChanges.get(i);
18660                if (item.pid == app.pid) {
18661                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18662                            "Re-using existing item: " + item);
18663                    break;
18664                }
18665                i--;
18666            }
18667            if (i < 0) {
18668                // No existing item in pending changes; need a new one.
18669                final int NA = mAvailProcessChanges.size();
18670                if (NA > 0) {
18671                    item = mAvailProcessChanges.remove(NA-1);
18672                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18673                            "Retrieving available item: " + item);
18674                } else {
18675                    item = new ProcessChangeItem();
18676                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18677                            "Allocating new item: " + item);
18678                }
18679                item.changes = 0;
18680                item.pid = app.pid;
18681                item.uid = app.info.uid;
18682                if (mPendingProcessChanges.size() == 0) {
18683                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18684                            "*** Enqueueing dispatch processes changed!");
18685                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
18686                }
18687                mPendingProcessChanges.add(item);
18688            }
18689            item.changes |= changes;
18690            item.processState = app.repProcState;
18691            item.foregroundActivities = app.repForegroundActivities;
18692            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18693                    "Item " + Integer.toHexString(System.identityHashCode(item))
18694                    + " " + app.toShortString() + ": changes=" + item.changes
18695                    + " procState=" + item.processState
18696                    + " foreground=" + item.foregroundActivities
18697                    + " type=" + app.adjType + " source=" + app.adjSource
18698                    + " target=" + app.adjTarget);
18699        }
18700
18701        return success;
18702    }
18703
18704    private final void enqueueUidChangeLocked(UidRecord uidRec, boolean gone) {
18705        if (uidRec.pendingChange == null) {
18706            if (mPendingUidChanges.size() == 0) {
18707                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18708                        "*** Enqueueing dispatch uid changed!");
18709                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_MSG).sendToTarget();
18710            }
18711            final int NA = mAvailUidChanges.size();
18712            if (NA > 0) {
18713                uidRec.pendingChange = mAvailUidChanges.remove(NA-1);
18714                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18715                        "Retrieving available item: " + uidRec.pendingChange);
18716            } else {
18717                uidRec.pendingChange = new UidRecord.ChangeItem();
18718                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18719                        "Allocating new item: " + uidRec.pendingChange);
18720            }
18721            uidRec.pendingChange.uidRecord = uidRec;
18722            uidRec.pendingChange.uid = uidRec.uid;
18723            mPendingUidChanges.add(uidRec.pendingChange);
18724        }
18725        uidRec.pendingChange.gone = gone;
18726        uidRec.pendingChange.processState = uidRec.setProcState;
18727    }
18728
18729    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
18730            String authority) {
18731        if (app == null) return;
18732        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18733            UserState userState = mStartedUsers.get(app.userId);
18734            if (userState == null) return;
18735            final long now = SystemClock.elapsedRealtime();
18736            Long lastReported = userState.mProviderLastReportedFg.get(authority);
18737            if (lastReported == null || lastReported < now - 60 * 1000L) {
18738                mUsageStatsService.reportContentProviderUsage(
18739                        authority, providerPkgName, app.userId);
18740                userState.mProviderLastReportedFg.put(authority, now);
18741            }
18742        }
18743    }
18744
18745    private void maybeUpdateUsageStatsLocked(ProcessRecord app) {
18746        if (DEBUG_USAGE_STATS) {
18747            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
18748                    + "] state changes: old = " + app.setProcState + ", new = "
18749                    + app.curProcState);
18750        }
18751        if (mUsageStatsService == null) {
18752            return;
18753        }
18754        boolean isInteraction;
18755        // To avoid some abuse patterns, we are going to be careful about what we consider
18756        // to be an app interaction.  Being the top activity doesn't count while the display
18757        // is sleeping, nor do short foreground services.
18758        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
18759            isInteraction = true;
18760            app.fgInteractionTime = 0;
18761        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
18762            final long now = SystemClock.elapsedRealtime();
18763            if (app.fgInteractionTime == 0) {
18764                app.fgInteractionTime = now;
18765                isInteraction = false;
18766            } else {
18767                isInteraction = now > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
18768            }
18769        } else {
18770            isInteraction = app.curProcState
18771                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18772            app.fgInteractionTime = 0;
18773        }
18774        if (isInteraction && !app.reportedInteraction) {
18775            String[] packages = app.getPackageList();
18776            if (packages != null) {
18777                for (int i = 0; i < packages.length; i++) {
18778                    mUsageStatsService.reportEvent(packages[i], app.userId,
18779                            UsageEvents.Event.SYSTEM_INTERACTION);
18780                }
18781            }
18782        }
18783        app.reportedInteraction = isInteraction;
18784    }
18785
18786    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
18787        if (proc.thread != null) {
18788            if (proc.baseProcessTracker != null) {
18789                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
18790            }
18791            if (proc.repProcState >= 0) {
18792                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
18793                        proc.repProcState);
18794            }
18795        }
18796    }
18797
18798    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
18799            ProcessRecord TOP_APP, boolean doingAll, long now) {
18800        if (app.thread == null) {
18801            return false;
18802        }
18803
18804        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
18805
18806        return applyOomAdjLocked(app, doingAll, now);
18807    }
18808
18809    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
18810            boolean oomAdj) {
18811        if (isForeground != proc.foregroundServices) {
18812            proc.foregroundServices = isForeground;
18813            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
18814                    proc.info.uid);
18815            if (isForeground) {
18816                if (curProcs == null) {
18817                    curProcs = new ArrayList<ProcessRecord>();
18818                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
18819                }
18820                if (!curProcs.contains(proc)) {
18821                    curProcs.add(proc);
18822                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
18823                            proc.info.packageName, proc.info.uid);
18824                }
18825            } else {
18826                if (curProcs != null) {
18827                    if (curProcs.remove(proc)) {
18828                        mBatteryStatsService.noteEvent(
18829                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
18830                                proc.info.packageName, proc.info.uid);
18831                        if (curProcs.size() <= 0) {
18832                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
18833                        }
18834                    }
18835                }
18836            }
18837            if (oomAdj) {
18838                updateOomAdjLocked();
18839            }
18840        }
18841    }
18842
18843    private final ActivityRecord resumedAppLocked() {
18844        ActivityRecord act = mStackSupervisor.resumedAppLocked();
18845        String pkg;
18846        int uid;
18847        if (act != null) {
18848            pkg = act.packageName;
18849            uid = act.info.applicationInfo.uid;
18850        } else {
18851            pkg = null;
18852            uid = -1;
18853        }
18854        // Has the UID or resumed package name changed?
18855        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
18856                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
18857            if (mCurResumedPackage != null) {
18858                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
18859                        mCurResumedPackage, mCurResumedUid);
18860            }
18861            mCurResumedPackage = pkg;
18862            mCurResumedUid = uid;
18863            if (mCurResumedPackage != null) {
18864                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
18865                        mCurResumedPackage, mCurResumedUid);
18866            }
18867        }
18868        return act;
18869    }
18870
18871    final boolean updateOomAdjLocked(ProcessRecord app) {
18872        final ActivityRecord TOP_ACT = resumedAppLocked();
18873        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18874        final boolean wasCached = app.cached;
18875
18876        mAdjSeq++;
18877
18878        // This is the desired cached adjusment we want to tell it to use.
18879        // If our app is currently cached, we know it, and that is it.  Otherwise,
18880        // we don't know it yet, and it needs to now be cached we will then
18881        // need to do a complete oom adj.
18882        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
18883                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
18884        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
18885                SystemClock.uptimeMillis());
18886        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
18887            // Changed to/from cached state, so apps after it in the LRU
18888            // list may also be changed.
18889            updateOomAdjLocked();
18890        }
18891        return success;
18892    }
18893
18894    final void updateOomAdjLocked() {
18895        final ActivityRecord TOP_ACT = resumedAppLocked();
18896        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18897        final long now = SystemClock.uptimeMillis();
18898        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
18899        final int N = mLruProcesses.size();
18900
18901        if (false) {
18902            RuntimeException e = new RuntimeException();
18903            e.fillInStackTrace();
18904            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
18905        }
18906
18907        // Reset state in all uid records.
18908        for (int i=mActiveUids.size()-1; i>=0; i--) {
18909            final UidRecord uidRec = mActiveUids.valueAt(i);
18910            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18911                    "Starting update of " + uidRec);
18912            uidRec.reset();
18913        }
18914
18915        mAdjSeq++;
18916        mNewNumServiceProcs = 0;
18917        mNewNumAServiceProcs = 0;
18918
18919        final int emptyProcessLimit;
18920        final int cachedProcessLimit;
18921        if (mProcessLimit <= 0) {
18922            emptyProcessLimit = cachedProcessLimit = 0;
18923        } else if (mProcessLimit == 1) {
18924            emptyProcessLimit = 1;
18925            cachedProcessLimit = 0;
18926        } else {
18927            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
18928            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
18929        }
18930
18931        // Let's determine how many processes we have running vs.
18932        // how many slots we have for background processes; we may want
18933        // to put multiple processes in a slot of there are enough of
18934        // them.
18935        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
18936                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
18937        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
18938        if (numEmptyProcs > cachedProcessLimit) {
18939            // If there are more empty processes than our limit on cached
18940            // processes, then use the cached process limit for the factor.
18941            // This ensures that the really old empty processes get pushed
18942            // down to the bottom, so if we are running low on memory we will
18943            // have a better chance at keeping around more cached processes
18944            // instead of a gazillion empty processes.
18945            numEmptyProcs = cachedProcessLimit;
18946        }
18947        int emptyFactor = numEmptyProcs/numSlots;
18948        if (emptyFactor < 1) emptyFactor = 1;
18949        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
18950        if (cachedFactor < 1) cachedFactor = 1;
18951        int stepCached = 0;
18952        int stepEmpty = 0;
18953        int numCached = 0;
18954        int numEmpty = 0;
18955        int numTrimming = 0;
18956
18957        mNumNonCachedProcs = 0;
18958        mNumCachedHiddenProcs = 0;
18959
18960        // First update the OOM adjustment for each of the
18961        // application processes based on their current state.
18962        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
18963        int nextCachedAdj = curCachedAdj+1;
18964        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
18965        int nextEmptyAdj = curEmptyAdj+2;
18966        for (int i=N-1; i>=0; i--) {
18967            ProcessRecord app = mLruProcesses.get(i);
18968            if (!app.killedByAm && app.thread != null) {
18969                app.procStateChanged = false;
18970                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
18971
18972                // If we haven't yet assigned the final cached adj
18973                // to the process, do that now.
18974                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
18975                    switch (app.curProcState) {
18976                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18977                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18978                            // This process is a cached process holding activities...
18979                            // assign it the next cached value for that type, and then
18980                            // step that cached level.
18981                            app.curRawAdj = curCachedAdj;
18982                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
18983                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
18984                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
18985                                    + ")");
18986                            if (curCachedAdj != nextCachedAdj) {
18987                                stepCached++;
18988                                if (stepCached >= cachedFactor) {
18989                                    stepCached = 0;
18990                                    curCachedAdj = nextCachedAdj;
18991                                    nextCachedAdj += 2;
18992                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18993                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
18994                                    }
18995                                }
18996                            }
18997                            break;
18998                        default:
18999                            // For everything else, assign next empty cached process
19000                            // level and bump that up.  Note that this means that
19001                            // long-running services that have dropped down to the
19002                            // cached level will be treated as empty (since their process
19003                            // state is still as a service), which is what we want.
19004                            app.curRawAdj = curEmptyAdj;
19005                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
19006                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
19007                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
19008                                    + ")");
19009                            if (curEmptyAdj != nextEmptyAdj) {
19010                                stepEmpty++;
19011                                if (stepEmpty >= emptyFactor) {
19012                                    stepEmpty = 0;
19013                                    curEmptyAdj = nextEmptyAdj;
19014                                    nextEmptyAdj += 2;
19015                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19016                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
19017                                    }
19018                                }
19019                            }
19020                            break;
19021                    }
19022                }
19023
19024                applyOomAdjLocked(app, true, now);
19025
19026                // Count the number of process types.
19027                switch (app.curProcState) {
19028                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19029                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19030                        mNumCachedHiddenProcs++;
19031                        numCached++;
19032                        if (numCached > cachedProcessLimit) {
19033                            app.kill("cached #" + numCached, true);
19034                        }
19035                        break;
19036                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
19037                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
19038                                && app.lastActivityTime < oldTime) {
19039                            app.kill("empty for "
19040                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
19041                                    / 1000) + "s", true);
19042                        } else {
19043                            numEmpty++;
19044                            if (numEmpty > emptyProcessLimit) {
19045                                app.kill("empty #" + numEmpty, true);
19046                            }
19047                        }
19048                        break;
19049                    default:
19050                        mNumNonCachedProcs++;
19051                        break;
19052                }
19053
19054                if (app.isolated && app.services.size() <= 0) {
19055                    // If this is an isolated process, and there are no
19056                    // services running in it, then the process is no longer
19057                    // needed.  We agressively kill these because we can by
19058                    // definition not re-use the same process again, and it is
19059                    // good to avoid having whatever code was running in them
19060                    // left sitting around after no longer needed.
19061                    app.kill("isolated not needed", true);
19062                } else {
19063                    // Keeping this process, update its uid.
19064                    final UidRecord uidRec = app.uidRecord;
19065                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
19066                        uidRec.curProcState = app.curProcState;
19067                    }
19068                }
19069
19070                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19071                        && !app.killedByAm) {
19072                    numTrimming++;
19073                }
19074            }
19075        }
19076
19077        mNumServiceProcs = mNewNumServiceProcs;
19078
19079        // Now determine the memory trimming level of background processes.
19080        // Unfortunately we need to start at the back of the list to do this
19081        // properly.  We only do this if the number of background apps we
19082        // are managing to keep around is less than half the maximum we desire;
19083        // if we are keeping a good number around, we'll let them use whatever
19084        // memory they want.
19085        final int numCachedAndEmpty = numCached + numEmpty;
19086        int memFactor;
19087        if (numCached <= ProcessList.TRIM_CACHED_APPS
19088                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
19089            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
19090                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
19091            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
19092                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
19093            } else {
19094                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
19095            }
19096        } else {
19097            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
19098        }
19099        // We always allow the memory level to go up (better).  We only allow it to go
19100        // down if we are in a state where that is allowed, *and* the total number of processes
19101        // has gone down since last time.
19102        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
19103                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
19104                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
19105        if (memFactor > mLastMemoryLevel) {
19106            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
19107                memFactor = mLastMemoryLevel;
19108                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
19109            }
19110        }
19111        mLastMemoryLevel = memFactor;
19112        mLastNumProcesses = mLruProcesses.size();
19113        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
19114        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
19115        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
19116            if (mLowRamStartTime == 0) {
19117                mLowRamStartTime = now;
19118            }
19119            int step = 0;
19120            int fgTrimLevel;
19121            switch (memFactor) {
19122                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
19123                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
19124                    break;
19125                case ProcessStats.ADJ_MEM_FACTOR_LOW:
19126                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
19127                    break;
19128                default:
19129                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
19130                    break;
19131            }
19132            int factor = numTrimming/3;
19133            int minFactor = 2;
19134            if (mHomeProcess != null) minFactor++;
19135            if (mPreviousProcess != null) minFactor++;
19136            if (factor < minFactor) factor = minFactor;
19137            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
19138            for (int i=N-1; i>=0; i--) {
19139                ProcessRecord app = mLruProcesses.get(i);
19140                if (allChanged || app.procStateChanged) {
19141                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
19142                    app.procStateChanged = false;
19143                }
19144                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19145                        && !app.killedByAm) {
19146                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
19147                        try {
19148                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19149                                    "Trimming memory of " + app.processName + " to " + curLevel);
19150                            app.thread.scheduleTrimMemory(curLevel);
19151                        } catch (RemoteException e) {
19152                        }
19153                        if (false) {
19154                            // For now we won't do this; our memory trimming seems
19155                            // to be good enough at this point that destroying
19156                            // activities causes more harm than good.
19157                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
19158                                    && app != mHomeProcess && app != mPreviousProcess) {
19159                                // Need to do this on its own message because the stack may not
19160                                // be in a consistent state at this point.
19161                                // For these apps we will also finish their activities
19162                                // to help them free memory.
19163                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
19164                            }
19165                        }
19166                    }
19167                    app.trimMemoryLevel = curLevel;
19168                    step++;
19169                    if (step >= factor) {
19170                        step = 0;
19171                        switch (curLevel) {
19172                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
19173                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
19174                                break;
19175                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
19176                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19177                                break;
19178                        }
19179                    }
19180                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19181                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
19182                            && app.thread != null) {
19183                        try {
19184                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19185                                    "Trimming memory of heavy-weight " + app.processName
19186                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19187                            app.thread.scheduleTrimMemory(
19188                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19189                        } catch (RemoteException e) {
19190                        }
19191                    }
19192                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19193                } else {
19194                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19195                            || app.systemNoUi) && app.pendingUiClean) {
19196                        // If this application is now in the background and it
19197                        // had done UI, then give it the special trim level to
19198                        // have it free UI resources.
19199                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
19200                        if (app.trimMemoryLevel < level && app.thread != null) {
19201                            try {
19202                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19203                                        "Trimming memory of bg-ui " + app.processName
19204                                        + " to " + level);
19205                                app.thread.scheduleTrimMemory(level);
19206                            } catch (RemoteException e) {
19207                            }
19208                        }
19209                        app.pendingUiClean = false;
19210                    }
19211                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
19212                        try {
19213                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19214                                    "Trimming memory of fg " + app.processName
19215                                    + " to " + fgTrimLevel);
19216                            app.thread.scheduleTrimMemory(fgTrimLevel);
19217                        } catch (RemoteException e) {
19218                        }
19219                    }
19220                    app.trimMemoryLevel = fgTrimLevel;
19221                }
19222            }
19223        } else {
19224            if (mLowRamStartTime != 0) {
19225                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
19226                mLowRamStartTime = 0;
19227            }
19228            for (int i=N-1; i>=0; i--) {
19229                ProcessRecord app = mLruProcesses.get(i);
19230                if (allChanged || app.procStateChanged) {
19231                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
19232                    app.procStateChanged = false;
19233                }
19234                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19235                        || app.systemNoUi) && app.pendingUiClean) {
19236                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
19237                            && app.thread != null) {
19238                        try {
19239                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19240                                    "Trimming memory of ui hidden " + app.processName
19241                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19242                            app.thread.scheduleTrimMemory(
19243                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19244                        } catch (RemoteException e) {
19245                        }
19246                    }
19247                    app.pendingUiClean = false;
19248                }
19249                app.trimMemoryLevel = 0;
19250            }
19251        }
19252
19253        if (mAlwaysFinishActivities) {
19254            // Need to do this on its own message because the stack may not
19255            // be in a consistent state at this point.
19256            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
19257        }
19258
19259        if (allChanged) {
19260            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
19261        }
19262
19263        // Update from any uid changes.
19264        for (int i=mActiveUids.size()-1; i>=0; i--) {
19265            final UidRecord uidRec = mActiveUids.valueAt(i);
19266            if (uidRec.setProcState != uidRec.curProcState) {
19267                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19268                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
19269                        + " to " + uidRec.curProcState);
19270                uidRec.setProcState = uidRec.curProcState;
19271                enqueueUidChangeLocked(uidRec, false);
19272            }
19273        }
19274
19275        if (mProcessStats.shouldWriteNowLocked(now)) {
19276            mHandler.post(new Runnable() {
19277                @Override public void run() {
19278                    synchronized (ActivityManagerService.this) {
19279                        mProcessStats.writeStateAsyncLocked();
19280                    }
19281                }
19282            });
19283        }
19284
19285        if (DEBUG_OOM_ADJ) {
19286            final long duration = SystemClock.uptimeMillis() - now;
19287            if (false) {
19288                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
19289                        new RuntimeException("here").fillInStackTrace());
19290            } else {
19291                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
19292            }
19293        }
19294    }
19295
19296    final void trimApplications() {
19297        synchronized (this) {
19298            int i;
19299
19300            // First remove any unused application processes whose package
19301            // has been removed.
19302            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
19303                final ProcessRecord app = mRemovedProcesses.get(i);
19304                if (app.activities.size() == 0
19305                        && app.curReceiver == null && app.services.size() == 0) {
19306                    Slog.i(
19307                        TAG, "Exiting empty application process "
19308                        + app.processName + " ("
19309                        + (app.thread != null ? app.thread.asBinder() : null)
19310                        + ")\n");
19311                    if (app.pid > 0 && app.pid != MY_PID) {
19312                        app.kill("empty", false);
19313                    } else {
19314                        try {
19315                            app.thread.scheduleExit();
19316                        } catch (Exception e) {
19317                            // Ignore exceptions.
19318                        }
19319                    }
19320                    cleanUpApplicationRecordLocked(app, false, true, -1);
19321                    mRemovedProcesses.remove(i);
19322
19323                    if (app.persistent) {
19324                        addAppLocked(app.info, false, null /* ABI override */);
19325                    }
19326                }
19327            }
19328
19329            // Now update the oom adj for all processes.
19330            updateOomAdjLocked();
19331        }
19332    }
19333
19334    /** This method sends the specified signal to each of the persistent apps */
19335    public void signalPersistentProcesses(int sig) throws RemoteException {
19336        if (sig != Process.SIGNAL_USR1) {
19337            throw new SecurityException("Only SIGNAL_USR1 is allowed");
19338        }
19339
19340        synchronized (this) {
19341            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
19342                    != PackageManager.PERMISSION_GRANTED) {
19343                throw new SecurityException("Requires permission "
19344                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
19345            }
19346
19347            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
19348                ProcessRecord r = mLruProcesses.get(i);
19349                if (r.thread != null && r.persistent) {
19350                    Process.sendSignal(r.pid, sig);
19351                }
19352            }
19353        }
19354    }
19355
19356    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
19357        if (proc == null || proc == mProfileProc) {
19358            proc = mProfileProc;
19359            profileType = mProfileType;
19360            clearProfilerLocked();
19361        }
19362        if (proc == null) {
19363            return;
19364        }
19365        try {
19366            proc.thread.profilerControl(false, null, profileType);
19367        } catch (RemoteException e) {
19368            throw new IllegalStateException("Process disappeared");
19369        }
19370    }
19371
19372    private void clearProfilerLocked() {
19373        if (mProfileFd != null) {
19374            try {
19375                mProfileFd.close();
19376            } catch (IOException e) {
19377            }
19378        }
19379        mProfileApp = null;
19380        mProfileProc = null;
19381        mProfileFile = null;
19382        mProfileType = 0;
19383        mAutoStopProfiler = false;
19384        mSamplingInterval = 0;
19385    }
19386
19387    public boolean profileControl(String process, int userId, boolean start,
19388            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
19389
19390        try {
19391            synchronized (this) {
19392                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19393                // its own permission.
19394                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19395                        != PackageManager.PERMISSION_GRANTED) {
19396                    throw new SecurityException("Requires permission "
19397                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19398                }
19399
19400                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
19401                    throw new IllegalArgumentException("null profile info or fd");
19402                }
19403
19404                ProcessRecord proc = null;
19405                if (process != null) {
19406                    proc = findProcessLocked(process, userId, "profileControl");
19407                }
19408
19409                if (start && (proc == null || proc.thread == null)) {
19410                    throw new IllegalArgumentException("Unknown process: " + process);
19411                }
19412
19413                if (start) {
19414                    stopProfilerLocked(null, 0);
19415                    setProfileApp(proc.info, proc.processName, profilerInfo);
19416                    mProfileProc = proc;
19417                    mProfileType = profileType;
19418                    ParcelFileDescriptor fd = profilerInfo.profileFd;
19419                    try {
19420                        fd = fd.dup();
19421                    } catch (IOException e) {
19422                        fd = null;
19423                    }
19424                    profilerInfo.profileFd = fd;
19425                    proc.thread.profilerControl(start, profilerInfo, profileType);
19426                    fd = null;
19427                    mProfileFd = null;
19428                } else {
19429                    stopProfilerLocked(proc, profileType);
19430                    if (profilerInfo != null && profilerInfo.profileFd != null) {
19431                        try {
19432                            profilerInfo.profileFd.close();
19433                        } catch (IOException e) {
19434                        }
19435                    }
19436                }
19437
19438                return true;
19439            }
19440        } catch (RemoteException e) {
19441            throw new IllegalStateException("Process disappeared");
19442        } finally {
19443            if (profilerInfo != null && profilerInfo.profileFd != null) {
19444                try {
19445                    profilerInfo.profileFd.close();
19446                } catch (IOException e) {
19447                }
19448            }
19449        }
19450    }
19451
19452    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
19453        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19454                userId, true, ALLOW_FULL_ONLY, callName, null);
19455        ProcessRecord proc = null;
19456        try {
19457            int pid = Integer.parseInt(process);
19458            synchronized (mPidsSelfLocked) {
19459                proc = mPidsSelfLocked.get(pid);
19460            }
19461        } catch (NumberFormatException e) {
19462        }
19463
19464        if (proc == null) {
19465            ArrayMap<String, SparseArray<ProcessRecord>> all
19466                    = mProcessNames.getMap();
19467            SparseArray<ProcessRecord> procs = all.get(process);
19468            if (procs != null && procs.size() > 0) {
19469                proc = procs.valueAt(0);
19470                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
19471                    for (int i=1; i<procs.size(); i++) {
19472                        ProcessRecord thisProc = procs.valueAt(i);
19473                        if (thisProc.userId == userId) {
19474                            proc = thisProc;
19475                            break;
19476                        }
19477                    }
19478                }
19479            }
19480        }
19481
19482        return proc;
19483    }
19484
19485    public boolean dumpHeap(String process, int userId, boolean managed,
19486            String path, ParcelFileDescriptor fd) throws RemoteException {
19487
19488        try {
19489            synchronized (this) {
19490                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19491                // its own permission (same as profileControl).
19492                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19493                        != PackageManager.PERMISSION_GRANTED) {
19494                    throw new SecurityException("Requires permission "
19495                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19496                }
19497
19498                if (fd == null) {
19499                    throw new IllegalArgumentException("null fd");
19500                }
19501
19502                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
19503                if (proc == null || proc.thread == null) {
19504                    throw new IllegalArgumentException("Unknown process: " + process);
19505                }
19506
19507                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19508                if (!isDebuggable) {
19509                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19510                        throw new SecurityException("Process not debuggable: " + proc);
19511                    }
19512                }
19513
19514                proc.thread.dumpHeap(managed, path, fd);
19515                fd = null;
19516                return true;
19517            }
19518        } catch (RemoteException e) {
19519            throw new IllegalStateException("Process disappeared");
19520        } finally {
19521            if (fd != null) {
19522                try {
19523                    fd.close();
19524                } catch (IOException e) {
19525                }
19526            }
19527        }
19528    }
19529
19530    @Override
19531    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
19532            String reportPackage) {
19533        if (processName != null) {
19534            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
19535                    "setDumpHeapDebugLimit()");
19536        } else {
19537            synchronized (mPidsSelfLocked) {
19538                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
19539                if (proc == null) {
19540                    throw new SecurityException("No process found for calling pid "
19541                            + Binder.getCallingPid());
19542                }
19543                if (!Build.IS_DEBUGGABLE
19544                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19545                    throw new SecurityException("Not running a debuggable build");
19546                }
19547                processName = proc.processName;
19548                uid = proc.uid;
19549                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
19550                    throw new SecurityException("Package " + reportPackage + " is not running in "
19551                            + proc);
19552                }
19553            }
19554        }
19555        synchronized (this) {
19556            if (maxMemSize > 0) {
19557                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
19558            } else {
19559                if (uid != 0) {
19560                    mMemWatchProcesses.remove(processName, uid);
19561                } else {
19562                    mMemWatchProcesses.getMap().remove(processName);
19563                }
19564            }
19565        }
19566    }
19567
19568    @Override
19569    public void dumpHeapFinished(String path) {
19570        synchronized (this) {
19571            if (Binder.getCallingPid() != mMemWatchDumpPid) {
19572                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
19573                        + " does not match last pid " + mMemWatchDumpPid);
19574                return;
19575            }
19576            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
19577                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
19578                        + " does not match last path " + mMemWatchDumpFile);
19579                return;
19580            }
19581            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
19582            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
19583        }
19584    }
19585
19586    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
19587    public void monitor() {
19588        synchronized (this) { }
19589    }
19590
19591    void onCoreSettingsChange(Bundle settings) {
19592        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19593            ProcessRecord processRecord = mLruProcesses.get(i);
19594            try {
19595                if (processRecord.thread != null) {
19596                    processRecord.thread.setCoreSettings(settings);
19597                }
19598            } catch (RemoteException re) {
19599                /* ignore */
19600            }
19601        }
19602    }
19603
19604    // Multi-user methods
19605
19606    /**
19607     * Start user, if its not already running, but don't bring it to foreground.
19608     */
19609    @Override
19610    public boolean startUserInBackground(final int userId) {
19611        return startUser(userId, /* foreground */ false);
19612    }
19613
19614    /**
19615     * Start user, if its not already running, and bring it to foreground.
19616     */
19617    boolean startUserInForeground(final int userId, Dialog dlg) {
19618        boolean result = startUser(userId, /* foreground */ true);
19619        dlg.dismiss();
19620        return result;
19621    }
19622
19623    /**
19624     * Refreshes the list of users related to the current user when either a
19625     * user switch happens or when a new related user is started in the
19626     * background.
19627     */
19628    private void updateCurrentProfileIdsLocked() {
19629        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19630                mCurrentUserId, false /* enabledOnly */);
19631        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
19632        for (int i = 0; i < currentProfileIds.length; i++) {
19633            currentProfileIds[i] = profiles.get(i).id;
19634        }
19635        mCurrentProfileIds = currentProfileIds;
19636
19637        synchronized (mUserProfileGroupIdsSelfLocked) {
19638            mUserProfileGroupIdsSelfLocked.clear();
19639            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
19640            for (int i = 0; i < users.size(); i++) {
19641                UserInfo user = users.get(i);
19642                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
19643                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
19644                }
19645            }
19646        }
19647    }
19648
19649    private Set<Integer> getProfileIdsLocked(int userId) {
19650        Set<Integer> userIds = new HashSet<Integer>();
19651        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19652                userId, false /* enabledOnly */);
19653        for (UserInfo user : profiles) {
19654            userIds.add(Integer.valueOf(user.id));
19655        }
19656        return userIds;
19657    }
19658
19659    @Override
19660    public boolean switchUser(final int userId) {
19661        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19662        String userName;
19663        synchronized (this) {
19664            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19665            if (userInfo == null) {
19666                Slog.w(TAG, "No user info for user #" + userId);
19667                return false;
19668            }
19669            if (userInfo.isManagedProfile()) {
19670                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19671                return false;
19672            }
19673            userName = userInfo.name;
19674            mTargetUserId = userId;
19675        }
19676        mUiHandler.removeMessages(START_USER_SWITCH_MSG);
19677        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
19678        return true;
19679    }
19680
19681    private void showUserSwitchDialog(int userId, String userName) {
19682        // The dialog will show and then initiate the user switch by calling startUserInForeground
19683        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
19684                true /* above system */);
19685        d.show();
19686    }
19687
19688    private boolean startUser(final int userId, final boolean foreground) {
19689        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19690                != PackageManager.PERMISSION_GRANTED) {
19691            String msg = "Permission Denial: switchUser() from pid="
19692                    + Binder.getCallingPid()
19693                    + ", uid=" + Binder.getCallingUid()
19694                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19695            Slog.w(TAG, msg);
19696            throw new SecurityException(msg);
19697        }
19698
19699        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
19700
19701        final long ident = Binder.clearCallingIdentity();
19702        try {
19703            synchronized (this) {
19704                final int oldUserId = mCurrentUserId;
19705                if (oldUserId == userId) {
19706                    return true;
19707                }
19708
19709                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
19710                        "startUser", false);
19711
19712                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19713                if (userInfo == null) {
19714                    Slog.w(TAG, "No user info for user #" + userId);
19715                    return false;
19716                }
19717                if (foreground && userInfo.isManagedProfile()) {
19718                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19719                    return false;
19720                }
19721
19722                if (foreground) {
19723                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
19724                            R.anim.screen_user_enter);
19725                }
19726
19727                boolean needStart = false;
19728
19729                // If the user we are switching to is not currently started, then
19730                // we need to start it now.
19731                if (mStartedUsers.get(userId) == null) {
19732                    mStartedUsers.put(userId, new UserState(new UserHandle(userId), false));
19733                    updateStartedUserArrayLocked();
19734                    needStart = true;
19735                }
19736
19737                final Integer userIdInt = Integer.valueOf(userId);
19738                mUserLru.remove(userIdInt);
19739                mUserLru.add(userIdInt);
19740
19741                if (foreground) {
19742                    mCurrentUserId = userId;
19743                    updateUserConfigurationLocked();
19744                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
19745                    updateCurrentProfileIdsLocked();
19746                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
19747                    // Once the internal notion of the active user has switched, we lock the device
19748                    // with the option to show the user switcher on the keyguard.
19749                    mWindowManager.lockNow(null);
19750                } else {
19751                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
19752                    updateCurrentProfileIdsLocked();
19753                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
19754                    mUserLru.remove(currentUserIdInt);
19755                    mUserLru.add(currentUserIdInt);
19756                }
19757
19758                final UserState uss = mStartedUsers.get(userId);
19759
19760                // Make sure user is in the started state.  If it is currently
19761                // stopping, we need to knock that off.
19762                if (uss.mState == UserState.STATE_STOPPING) {
19763                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
19764                    // so we can just fairly silently bring the user back from
19765                    // the almost-dead.
19766                    uss.mState = UserState.STATE_RUNNING;
19767                    updateStartedUserArrayLocked();
19768                    needStart = true;
19769                } else if (uss.mState == UserState.STATE_SHUTDOWN) {
19770                    // This means ACTION_SHUTDOWN has been sent, so we will
19771                    // need to treat this as a new boot of the user.
19772                    uss.mState = UserState.STATE_BOOTING;
19773                    updateStartedUserArrayLocked();
19774                    needStart = true;
19775                }
19776
19777                if (uss.mState == UserState.STATE_BOOTING) {
19778                    // Booting up a new user, need to tell system services about it.
19779                    // Note that this is on the same handler as scheduling of broadcasts,
19780                    // which is important because it needs to go first.
19781                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
19782                }
19783
19784                if (foreground) {
19785                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
19786                            oldUserId));
19787                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
19788                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19789                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
19790                            oldUserId, userId, uss));
19791                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
19792                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
19793                }
19794
19795                if (needStart) {
19796                    // Send USER_STARTED broadcast
19797                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
19798                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19799                            | Intent.FLAG_RECEIVER_FOREGROUND);
19800                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19801                    broadcastIntentLocked(null, null, intent,
19802                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19803                            null, false, false, MY_PID, Process.SYSTEM_UID, userId);
19804                }
19805
19806                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
19807                    if (userId != UserHandle.USER_OWNER) {
19808                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
19809                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19810                        broadcastIntentLocked(null, null, intent, null,
19811                                new IIntentReceiver.Stub() {
19812                                    public void performReceive(Intent intent, int resultCode,
19813                                            String data, Bundle extras, boolean ordered,
19814                                            boolean sticky, int sendingUser) {
19815                                        onUserInitialized(uss, foreground, oldUserId, userId);
19816                                    }
19817                                }, 0, null, null, null, AppOpsManager.OP_NONE,
19818                                null, true, false, MY_PID, Process.SYSTEM_UID, userId);
19819                        uss.initializing = true;
19820                    } else {
19821                        getUserManagerLocked().makeInitialized(userInfo.id);
19822                    }
19823                }
19824
19825                if (foreground) {
19826                    if (!uss.initializing) {
19827                        moveUserToForegroundLocked(uss, oldUserId, userId);
19828                    }
19829                } else {
19830                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
19831                }
19832
19833                if (needStart) {
19834                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
19835                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19836                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19837                    broadcastIntentLocked(null, null, intent,
19838                            null, new IIntentReceiver.Stub() {
19839                                @Override
19840                                public void performReceive(Intent intent, int resultCode,
19841                                        String data, Bundle extras, boolean ordered, boolean sticky,
19842                                        int sendingUser) throws RemoteException {
19843                                }
19844                            }, 0, null, null,
19845                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19846                            null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19847                }
19848            }
19849        } finally {
19850            Binder.restoreCallingIdentity(ident);
19851        }
19852
19853        return true;
19854    }
19855
19856    void dispatchForegroundProfileChanged(int userId) {
19857        final int N = mUserSwitchObservers.beginBroadcast();
19858        for (int i = 0; i < N; i++) {
19859            try {
19860                mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
19861            } catch (RemoteException e) {
19862                // Ignore
19863            }
19864        }
19865        mUserSwitchObservers.finishBroadcast();
19866    }
19867
19868    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
19869        long ident = Binder.clearCallingIdentity();
19870        try {
19871            Intent intent;
19872            if (oldUserId >= 0) {
19873                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
19874                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
19875                int count = profiles.size();
19876                for (int i = 0; i < count; i++) {
19877                    int profileUserId = profiles.get(i).id;
19878                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
19879                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19880                            | Intent.FLAG_RECEIVER_FOREGROUND);
19881                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19882                    broadcastIntentLocked(null, null, intent,
19883                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19884                            null, false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19885                }
19886            }
19887            if (newUserId >= 0) {
19888                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
19889                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
19890                int count = profiles.size();
19891                for (int i = 0; i < count; i++) {
19892                    int profileUserId = profiles.get(i).id;
19893                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
19894                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19895                            | Intent.FLAG_RECEIVER_FOREGROUND);
19896                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19897                    broadcastIntentLocked(null, null, intent,
19898                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19899                            null, false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19900                }
19901                intent = new Intent(Intent.ACTION_USER_SWITCHED);
19902                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19903                        | Intent.FLAG_RECEIVER_FOREGROUND);
19904                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
19905                broadcastIntentLocked(null, null, intent,
19906                        null, null, 0, null, null,
19907                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
19908                        null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19909            }
19910        } finally {
19911            Binder.restoreCallingIdentity(ident);
19912        }
19913    }
19914
19915    void dispatchUserSwitch(final UserState uss, final int oldUserId,
19916            final int newUserId) {
19917        final int N = mUserSwitchObservers.beginBroadcast();
19918        if (N > 0) {
19919            final IRemoteCallback callback = new IRemoteCallback.Stub() {
19920                int mCount = 0;
19921                @Override
19922                public void sendResult(Bundle data) throws RemoteException {
19923                    synchronized (ActivityManagerService.this) {
19924                        if (mCurUserSwitchCallback == this) {
19925                            mCount++;
19926                            if (mCount == N) {
19927                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19928                            }
19929                        }
19930                    }
19931                }
19932            };
19933            synchronized (this) {
19934                uss.switching = true;
19935                mCurUserSwitchCallback = callback;
19936            }
19937            for (int i=0; i<N; i++) {
19938                try {
19939                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
19940                            newUserId, callback);
19941                } catch (RemoteException e) {
19942                }
19943            }
19944        } else {
19945            synchronized (this) {
19946                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19947            }
19948        }
19949        mUserSwitchObservers.finishBroadcast();
19950    }
19951
19952    void timeoutUserSwitch(UserState uss, int oldUserId, int newUserId) {
19953        synchronized (this) {
19954            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
19955            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19956        }
19957    }
19958
19959    void sendContinueUserSwitchLocked(UserState uss, int oldUserId, int newUserId) {
19960        mCurUserSwitchCallback = null;
19961        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19962        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
19963                oldUserId, newUserId, uss));
19964    }
19965
19966    void onUserInitialized(UserState uss, boolean foreground, int oldUserId, int newUserId) {
19967        synchronized (this) {
19968            if (foreground) {
19969                moveUserToForegroundLocked(uss, oldUserId, newUserId);
19970            }
19971        }
19972
19973        completeSwitchAndInitialize(uss, newUserId, true, false);
19974    }
19975
19976    void moveUserToForegroundLocked(UserState uss, int oldUserId, int newUserId) {
19977        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
19978        if (homeInFront) {
19979            startHomeActivityLocked(newUserId, "moveUserToFroreground");
19980        } else {
19981            mStackSupervisor.resumeTopActivitiesLocked();
19982        }
19983        EventLogTags.writeAmSwitchUser(newUserId);
19984        getUserManagerLocked().onUserForeground(newUserId);
19985        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
19986    }
19987
19988    private void updateUserConfigurationLocked() {
19989        Configuration configuration = new Configuration(mConfiguration);
19990        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
19991                mCurrentUserId);
19992        updateConfigurationLocked(configuration, null, false);
19993    }
19994
19995    void continueUserSwitch(UserState uss, int oldUserId, int newUserId) {
19996        completeSwitchAndInitialize(uss, newUserId, false, true);
19997    }
19998
19999    void completeSwitchAndInitialize(UserState uss, int newUserId,
20000            boolean clearInitializing, boolean clearSwitching) {
20001        boolean unfrozen = false;
20002        synchronized (this) {
20003            if (clearInitializing) {
20004                uss.initializing = false;
20005                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
20006            }
20007            if (clearSwitching) {
20008                uss.switching = false;
20009            }
20010            if (!uss.switching && !uss.initializing) {
20011                mWindowManager.stopFreezingScreen();
20012                unfrozen = true;
20013            }
20014        }
20015        if (unfrozen) {
20016            mHandler.removeMessages(REPORT_USER_SWITCH_COMPLETE_MSG);
20017            mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_COMPLETE_MSG,
20018                    newUserId, 0));
20019        }
20020        stopGuestUserIfBackground();
20021    }
20022
20023    /** Called on handler thread */
20024    void dispatchUserSwitchComplete(int userId) {
20025        final int observerCount = mUserSwitchObservers.beginBroadcast();
20026        for (int i = 0; i < observerCount; i++) {
20027            try {
20028                mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(userId);
20029            } catch (RemoteException e) {
20030            }
20031        }
20032        mUserSwitchObservers.finishBroadcast();
20033    }
20034
20035    /**
20036     * Stops the guest user if it has gone to the background.
20037     */
20038    private void stopGuestUserIfBackground() {
20039        synchronized (this) {
20040            final int num = mUserLru.size();
20041            for (int i = 0; i < num; i++) {
20042                Integer oldUserId = mUserLru.get(i);
20043                UserState oldUss = mStartedUsers.get(oldUserId);
20044                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
20045                        || oldUss.mState == UserState.STATE_STOPPING
20046                        || oldUss.mState == UserState.STATE_SHUTDOWN) {
20047                    continue;
20048                }
20049                UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
20050                if (userInfo.isGuest()) {
20051                    // This is a user to be stopped.
20052                    stopUserLocked(oldUserId, null);
20053                    break;
20054                }
20055            }
20056        }
20057    }
20058
20059    void scheduleStartProfilesLocked() {
20060        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20061            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20062                    DateUtils.SECOND_IN_MILLIS);
20063        }
20064    }
20065
20066    void startProfilesLocked() {
20067        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
20068        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
20069                mCurrentUserId, false /* enabledOnly */);
20070        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
20071        for (UserInfo user : profiles) {
20072            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
20073                    && user.id != mCurrentUserId) {
20074                toStart.add(user);
20075            }
20076        }
20077        final int n = toStart.size();
20078        int i = 0;
20079        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
20080            startUserInBackground(toStart.get(i).id);
20081        }
20082        if (i < n) {
20083            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
20084        }
20085    }
20086
20087    void finishUserBoot(UserState uss) {
20088        synchronized (this) {
20089            if (uss.mState == UserState.STATE_BOOTING
20090                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
20091                uss.mState = UserState.STATE_RUNNING;
20092                final int userId = uss.mHandle.getIdentifier();
20093                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
20094                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20095                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
20096                broadcastIntentLocked(null, null, intent,
20097                        null, null, 0, null, null,
20098                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
20099                        null, true, false, MY_PID, Process.SYSTEM_UID, userId);
20100            }
20101        }
20102    }
20103
20104    void finishUserSwitch(UserState uss) {
20105        synchronized (this) {
20106            finishUserBoot(uss);
20107
20108            startProfilesLocked();
20109
20110            int num = mUserLru.size();
20111            int i = 0;
20112            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
20113                Integer oldUserId = mUserLru.get(i);
20114                UserState oldUss = mStartedUsers.get(oldUserId);
20115                if (oldUss == null) {
20116                    // Shouldn't happen, but be sane if it does.
20117                    mUserLru.remove(i);
20118                    num--;
20119                    continue;
20120                }
20121                if (oldUss.mState == UserState.STATE_STOPPING
20122                        || oldUss.mState == UserState.STATE_SHUTDOWN) {
20123                    // This user is already stopping, doesn't count.
20124                    num--;
20125                    i++;
20126                    continue;
20127                }
20128                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
20129                    // Owner and current can't be stopped, but count as running.
20130                    i++;
20131                    continue;
20132                }
20133                // This is a user to be stopped.
20134                stopUserLocked(oldUserId, null);
20135                num--;
20136                i++;
20137            }
20138        }
20139    }
20140
20141    @Override
20142    public int stopUser(final int userId, final IStopUserCallback callback) {
20143        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20144                != PackageManager.PERMISSION_GRANTED) {
20145            String msg = "Permission Denial: switchUser() from pid="
20146                    + Binder.getCallingPid()
20147                    + ", uid=" + Binder.getCallingUid()
20148                    + " requires " + INTERACT_ACROSS_USERS_FULL;
20149            Slog.w(TAG, msg);
20150            throw new SecurityException(msg);
20151        }
20152        if (userId < 0 || userId == UserHandle.USER_OWNER) {
20153            throw new IllegalArgumentException("Can't stop primary user " + userId);
20154        }
20155        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
20156        synchronized (this) {
20157            return stopUserLocked(userId, callback);
20158        }
20159    }
20160
20161    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
20162        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
20163        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
20164            return ActivityManager.USER_OP_IS_CURRENT;
20165        }
20166
20167        final UserState uss = mStartedUsers.get(userId);
20168        if (uss == null) {
20169            // User is not started, nothing to do...  but we do need to
20170            // callback if requested.
20171            if (callback != null) {
20172                mHandler.post(new Runnable() {
20173                    @Override
20174                    public void run() {
20175                        try {
20176                            callback.userStopped(userId);
20177                        } catch (RemoteException e) {
20178                        }
20179                    }
20180                });
20181            }
20182            return ActivityManager.USER_OP_SUCCESS;
20183        }
20184
20185        if (callback != null) {
20186            uss.mStopCallbacks.add(callback);
20187        }
20188
20189        if (uss.mState != UserState.STATE_STOPPING
20190                && uss.mState != UserState.STATE_SHUTDOWN) {
20191            uss.mState = UserState.STATE_STOPPING;
20192            updateStartedUserArrayLocked();
20193
20194            long ident = Binder.clearCallingIdentity();
20195            try {
20196                // We are going to broadcast ACTION_USER_STOPPING and then
20197                // once that is done send a final ACTION_SHUTDOWN and then
20198                // stop the user.
20199                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
20200                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20201                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20202                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
20203                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
20204                // This is the result receiver for the final shutdown broadcast.
20205                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
20206                    @Override
20207                    public void performReceive(Intent intent, int resultCode, String data,
20208                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
20209                        finishUserStop(uss);
20210                    }
20211                };
20212                // This is the result receiver for the initial stopping broadcast.
20213                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
20214                    @Override
20215                    public void performReceive(Intent intent, int resultCode, String data,
20216                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
20217                        // On to the next.
20218                        synchronized (ActivityManagerService.this) {
20219                            if (uss.mState != UserState.STATE_STOPPING) {
20220                                // Whoops, we are being started back up.  Abort, abort!
20221                                return;
20222                            }
20223                            uss.mState = UserState.STATE_SHUTDOWN;
20224                        }
20225                        mBatteryStatsService.noteEvent(
20226                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
20227                                Integer.toString(userId), userId);
20228                        mSystemServiceManager.stopUser(userId);
20229                        broadcastIntentLocked(null, null, shutdownIntent,
20230                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
20231                                null, true, false, MY_PID, Process.SYSTEM_UID, userId);
20232                    }
20233                };
20234                // Kick things off.
20235                broadcastIntentLocked(null, null, stoppingIntent,
20236                        null, stoppingReceiver, 0, null, null,
20237                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
20238                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
20239            } finally {
20240                Binder.restoreCallingIdentity(ident);
20241            }
20242        }
20243
20244        return ActivityManager.USER_OP_SUCCESS;
20245    }
20246
20247    void finishUserStop(UserState uss) {
20248        final int userId = uss.mHandle.getIdentifier();
20249        boolean stopped;
20250        ArrayList<IStopUserCallback> callbacks;
20251        synchronized (this) {
20252            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
20253            if (mStartedUsers.get(userId) != uss) {
20254                stopped = false;
20255            } else if (uss.mState != UserState.STATE_SHUTDOWN) {
20256                stopped = false;
20257            } else {
20258                stopped = true;
20259                // User can no longer run.
20260                mStartedUsers.remove(userId);
20261                mUserLru.remove(Integer.valueOf(userId));
20262                updateStartedUserArrayLocked();
20263
20264                // Clean up all state and processes associated with the user.
20265                // Kill all the processes for the user.
20266                forceStopUserLocked(userId, "finish user");
20267            }
20268
20269            // Explicitly remove the old information in mRecentTasks.
20270            mRecentTasks.removeTasksForUserLocked(userId);
20271        }
20272
20273        for (int i=0; i<callbacks.size(); i++) {
20274            try {
20275                if (stopped) callbacks.get(i).userStopped(userId);
20276                else callbacks.get(i).userStopAborted(userId);
20277            } catch (RemoteException e) {
20278            }
20279        }
20280
20281        if (stopped) {
20282            mSystemServiceManager.cleanupUser(userId);
20283            synchronized (this) {
20284                mStackSupervisor.removeUserLocked(userId);
20285            }
20286        }
20287    }
20288
20289    @Override
20290    public UserInfo getCurrentUser() {
20291        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
20292                != PackageManager.PERMISSION_GRANTED) && (
20293                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20294                != PackageManager.PERMISSION_GRANTED)) {
20295            String msg = "Permission Denial: getCurrentUser() from pid="
20296                    + Binder.getCallingPid()
20297                    + ", uid=" + Binder.getCallingUid()
20298                    + " requires " + INTERACT_ACROSS_USERS;
20299            Slog.w(TAG, msg);
20300            throw new SecurityException(msg);
20301        }
20302        synchronized (this) {
20303            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20304            return getUserManagerLocked().getUserInfo(userId);
20305        }
20306    }
20307
20308    int getCurrentUserIdLocked() {
20309        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20310    }
20311
20312    @Override
20313    public boolean isUserRunning(int userId, boolean orStopped) {
20314        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20315                != PackageManager.PERMISSION_GRANTED) {
20316            String msg = "Permission Denial: isUserRunning() from pid="
20317                    + Binder.getCallingPid()
20318                    + ", uid=" + Binder.getCallingUid()
20319                    + " requires " + INTERACT_ACROSS_USERS;
20320            Slog.w(TAG, msg);
20321            throw new SecurityException(msg);
20322        }
20323        synchronized (this) {
20324            return isUserRunningLocked(userId, orStopped);
20325        }
20326    }
20327
20328    boolean isUserRunningLocked(int userId, boolean orStopped) {
20329        UserState state = mStartedUsers.get(userId);
20330        if (state == null) {
20331            return false;
20332        }
20333        if (orStopped) {
20334            return true;
20335        }
20336        return state.mState != UserState.STATE_STOPPING
20337                && state.mState != UserState.STATE_SHUTDOWN;
20338    }
20339
20340    @Override
20341    public int[] getRunningUserIds() {
20342        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20343                != PackageManager.PERMISSION_GRANTED) {
20344            String msg = "Permission Denial: isUserRunning() from pid="
20345                    + Binder.getCallingPid()
20346                    + ", uid=" + Binder.getCallingUid()
20347                    + " requires " + INTERACT_ACROSS_USERS;
20348            Slog.w(TAG, msg);
20349            throw new SecurityException(msg);
20350        }
20351        synchronized (this) {
20352            return mStartedUserArray;
20353        }
20354    }
20355
20356    private void updateStartedUserArrayLocked() {
20357        int num = 0;
20358        for (int i=0; i<mStartedUsers.size();  i++) {
20359            UserState uss = mStartedUsers.valueAt(i);
20360            // This list does not include stopping users.
20361            if (uss.mState != UserState.STATE_STOPPING
20362                    && uss.mState != UserState.STATE_SHUTDOWN) {
20363                num++;
20364            }
20365        }
20366        mStartedUserArray = new int[num];
20367        num = 0;
20368        for (int i=0; i<mStartedUsers.size();  i++) {
20369            UserState uss = mStartedUsers.valueAt(i);
20370            if (uss.mState != UserState.STATE_STOPPING
20371                    && uss.mState != UserState.STATE_SHUTDOWN) {
20372                mStartedUserArray[num] = mStartedUsers.keyAt(i);
20373                num++;
20374            }
20375        }
20376    }
20377
20378    @Override
20379    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20380        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20381                != PackageManager.PERMISSION_GRANTED) {
20382            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
20383                    + Binder.getCallingPid()
20384                    + ", uid=" + Binder.getCallingUid()
20385                    + " requires " + INTERACT_ACROSS_USERS_FULL;
20386            Slog.w(TAG, msg);
20387            throw new SecurityException(msg);
20388        }
20389
20390        mUserSwitchObservers.register(observer);
20391    }
20392
20393    @Override
20394    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20395        mUserSwitchObservers.unregister(observer);
20396    }
20397
20398    int[] getUsersLocked() {
20399        UserManagerService ums = getUserManagerLocked();
20400        return ums != null ? ums.getUserIds() : new int[] { 0 };
20401    }
20402
20403    UserManagerService getUserManagerLocked() {
20404        if (mUserManager == null) {
20405            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
20406            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
20407        }
20408        return mUserManager;
20409    }
20410
20411    private int applyUserId(int uid, int userId) {
20412        return UserHandle.getUid(userId, uid);
20413    }
20414
20415    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20416        if (info == null) return null;
20417        ApplicationInfo newInfo = new ApplicationInfo(info);
20418        newInfo.uid = applyUserId(info.uid, userId);
20419        newInfo.dataDir = Environment
20420                .getDataUserPackageDirectory(info.volumeUuid, userId, info.packageName)
20421                .getAbsolutePath();
20422        return newInfo;
20423    }
20424
20425    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20426        if (aInfo == null
20427                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20428            return aInfo;
20429        }
20430
20431        ActivityInfo info = new ActivityInfo(aInfo);
20432        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20433        return info;
20434    }
20435
20436    private boolean processSanityChecksLocked(ProcessRecord process) {
20437        if (process == null || process.thread == null) {
20438            return false;
20439        }
20440
20441        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20442        if (!isDebuggable) {
20443            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20444                return false;
20445            }
20446        }
20447
20448        return true;
20449    }
20450
20451    public boolean startBinderTracking() throws RemoteException {
20452        synchronized (this) {
20453            mBinderTransactionTrackingEnabled = true;
20454            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20455            // permission (same as profileControl).
20456            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20457                    != PackageManager.PERMISSION_GRANTED) {
20458                throw new SecurityException("Requires permission "
20459                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20460            }
20461
20462            for (int i = 0; i < mLruProcesses.size(); i++) {
20463                ProcessRecord process = mLruProcesses.get(i);
20464                if (!processSanityChecksLocked(process)) {
20465                    continue;
20466                }
20467                try {
20468                    process.thread.startBinderTracking();
20469                } catch (RemoteException e) {
20470                    Log.v(TAG, "Process disappared");
20471                }
20472            }
20473            return true;
20474        }
20475    }
20476
20477    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
20478        try {
20479            synchronized (this) {
20480                mBinderTransactionTrackingEnabled = false;
20481                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20482                // permission (same as profileControl).
20483                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20484                        != PackageManager.PERMISSION_GRANTED) {
20485                    throw new SecurityException("Requires permission "
20486                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20487                }
20488
20489                if (fd == null) {
20490                    throw new IllegalArgumentException("null fd");
20491                }
20492
20493                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
20494                pw.println("Binder transaction traces for all processes.\n");
20495                for (ProcessRecord process : mLruProcesses) {
20496                    if (!processSanityChecksLocked(process)) {
20497                        continue;
20498                    }
20499
20500                    pw.println("Traces for process: " + process.processName);
20501                    pw.flush();
20502                    try {
20503                        TransferPipe tp = new TransferPipe();
20504                        try {
20505                            process.thread.stopBinderTrackingAndDump(
20506                                    tp.getWriteFd().getFileDescriptor());
20507                            tp.go(fd.getFileDescriptor());
20508                        } finally {
20509                            tp.kill();
20510                        }
20511                    } catch (IOException e) {
20512                        pw.println("Failure while dumping IPC traces from " + process +
20513                                ".  Exception: " + e);
20514                        pw.flush();
20515                    } catch (RemoteException e) {
20516                        pw.println("Got a RemoteException while dumping IPC traces from " +
20517                                process + ".  Exception: " + e);
20518                        pw.flush();
20519                    }
20520                }
20521                fd = null;
20522                return true;
20523            }
20524        } finally {
20525            if (fd != null) {
20526                try {
20527                    fd.close();
20528                } catch (IOException e) {
20529                }
20530            }
20531        }
20532    }
20533
20534    private final class LocalService extends ActivityManagerInternal {
20535        @Override
20536        public void onWakefulnessChanged(int wakefulness) {
20537            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20538        }
20539
20540        @Override
20541        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20542                String processName, String abiOverride, int uid, Runnable crashHandler) {
20543            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20544                    processName, abiOverride, uid, crashHandler);
20545        }
20546
20547        @Override
20548        public SleepToken acquireSleepToken(String tag) {
20549            Preconditions.checkNotNull(tag);
20550
20551            synchronized (ActivityManagerService.this) {
20552                SleepTokenImpl token = new SleepTokenImpl(tag);
20553                mSleepTokens.add(token);
20554                updateSleepIfNeededLocked();
20555                return token;
20556            }
20557        }
20558
20559        @Override
20560        public ComponentName getHomeActivityForUser(int userId) {
20561            synchronized (ActivityManagerService.this) {
20562                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20563                return homeActivity == null ? null : homeActivity.realActivity;
20564            }
20565        }
20566    }
20567
20568    private final class SleepTokenImpl extends SleepToken {
20569        private final String mTag;
20570        private final long mAcquireTime;
20571
20572        public SleepTokenImpl(String tag) {
20573            mTag = tag;
20574            mAcquireTime = SystemClock.uptimeMillis();
20575        }
20576
20577        @Override
20578        public void release() {
20579            synchronized (ActivityManagerService.this) {
20580                if (mSleepTokens.remove(this)) {
20581                    updateSleepIfNeededLocked();
20582                }
20583            }
20584        }
20585
20586        @Override
20587        public String toString() {
20588            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20589        }
20590    }
20591
20592    /**
20593     * An implementation of IAppTask, that allows an app to manage its own tasks via
20594     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
20595     * only the process that calls getAppTasks() can call the AppTask methods.
20596     */
20597    class AppTaskImpl extends IAppTask.Stub {
20598        private int mTaskId;
20599        private int mCallingUid;
20600
20601        public AppTaskImpl(int taskId, int callingUid) {
20602            mTaskId = taskId;
20603            mCallingUid = callingUid;
20604        }
20605
20606        private void checkCaller() {
20607            if (mCallingUid != Binder.getCallingUid()) {
20608                throw new SecurityException("Caller " + mCallingUid
20609                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
20610            }
20611        }
20612
20613        @Override
20614        public void finishAndRemoveTask() {
20615            checkCaller();
20616
20617            synchronized (ActivityManagerService.this) {
20618                long origId = Binder.clearCallingIdentity();
20619                try {
20620                    if (!removeTaskByIdLocked(mTaskId, false)) {
20621                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20622                    }
20623                } finally {
20624                    Binder.restoreCallingIdentity(origId);
20625                }
20626            }
20627        }
20628
20629        @Override
20630        public ActivityManager.RecentTaskInfo getTaskInfo() {
20631            checkCaller();
20632
20633            synchronized (ActivityManagerService.this) {
20634                long origId = Binder.clearCallingIdentity();
20635                try {
20636                    TaskRecord tr = mRecentTasks.taskForIdLocked(mTaskId);
20637                    if (tr == null) {
20638                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20639                    }
20640                    return createRecentTaskInfoFromTaskRecord(tr);
20641                } finally {
20642                    Binder.restoreCallingIdentity(origId);
20643                }
20644            }
20645        }
20646
20647        @Override
20648        public void moveToFront() {
20649            checkCaller();
20650            // Will bring task to front if it already has a root activity.
20651            startActivityFromRecentsInner(mTaskId, null);
20652        }
20653
20654        @Override
20655        public int startActivity(IBinder whoThread, String callingPackage,
20656                Intent intent, String resolvedType, Bundle options) {
20657            checkCaller();
20658
20659            int callingUser = UserHandle.getCallingUserId();
20660            TaskRecord tr;
20661            IApplicationThread appThread;
20662            synchronized (ActivityManagerService.this) {
20663                tr = mRecentTasks.taskForIdLocked(mTaskId);
20664                if (tr == null) {
20665                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20666                }
20667                appThread = ApplicationThreadNative.asInterface(whoThread);
20668                if (appThread == null) {
20669                    throw new IllegalArgumentException("Bad app thread " + appThread);
20670                }
20671            }
20672            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
20673                    resolvedType, null, null, null, null, 0, 0, null, null,
20674                    null, options, callingUser, null, tr);
20675        }
20676
20677        @Override
20678        public void setExcludeFromRecents(boolean exclude) {
20679            checkCaller();
20680
20681            synchronized (ActivityManagerService.this) {
20682                long origId = Binder.clearCallingIdentity();
20683                try {
20684                    TaskRecord tr = mRecentTasks.taskForIdLocked(mTaskId);
20685                    if (tr == null) {
20686                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20687                    }
20688                    Intent intent = tr.getBaseIntent();
20689                    if (exclude) {
20690                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20691                    } else {
20692                        intent.setFlags(intent.getFlags()
20693                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20694                    }
20695                } finally {
20696                    Binder.restoreCallingIdentity(origId);
20697                }
20698            }
20699        }
20700    }
20701}
20702