ActivityManagerService.java revision 1fa2a0888284ae00c905dce7a3003b995815467a
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 = 1000;
399
400    // Necessary ApplicationInfo flags to mark an app as persistent
401    private static final int PERSISTENT_MASK =
402            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
403
404    /** 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    /**
649     * Last time we requested PSS data of all processes.
650     */
651    long mLastFullPssTime = SystemClock.uptimeMillis();
652
653    /**
654     * If set, the next time we collect PSS data we should do a full collection
655     * with data from native processes and the kernel.
656     */
657    boolean mFullPssPending = false;
658
659    /**
660     * This is the process holding what we currently consider to be
661     * the "home" activity.
662     */
663    ProcessRecord mHomeProcess;
664
665    /**
666     * This is the process holding the activity the user last visited that
667     * is in a different process from the one they are currently in.
668     */
669    ProcessRecord mPreviousProcess;
670
671    /**
672     * The time at which the previous process was last visible.
673     */
674    long mPreviousProcessVisibleTime;
675
676    /**
677     * Track all uids that have actively running processes.
678     */
679    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
680
681    /**
682     * Which users have been started, so are allowed to run code.
683     */
684    final SparseArray<UserState> mStartedUsers = new SparseArray<>();
685
686    /**
687     * LRU list of history of current users.  Most recently current is at the end.
688     */
689    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
690
691    /**
692     * Constant array of the users that are currently started.
693     */
694    int[] mStartedUserArray = new int[] { 0 };
695
696    /**
697     * Registered observers of the user switching mechanics.
698     */
699    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
700            = new RemoteCallbackList<IUserSwitchObserver>();
701
702    /**
703     * Currently active user switch.
704     */
705    Object mCurUserSwitchCallback;
706
707    /**
708     * Packages that the user has asked to have run in screen size
709     * compatibility mode instead of filling the screen.
710     */
711    final CompatModePackages mCompatModePackages;
712
713    /**
714     * Set of IntentSenderRecord objects that are currently active.
715     */
716    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
717            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
718
719    /**
720     * Fingerprints (hashCode()) of stack traces that we've
721     * already logged DropBox entries for.  Guarded by itself.  If
722     * something (rogue user app) forces this over
723     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
724     */
725    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
726    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
727
728    /**
729     * Strict Mode background batched logging state.
730     *
731     * The string buffer is guarded by itself, and its lock is also
732     * used to determine if another batched write is already
733     * in-flight.
734     */
735    private final StringBuilder mStrictModeBuffer = new StringBuilder();
736
737    /**
738     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
739     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
740     */
741    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
742
743    /**
744     * Resolver for broadcast intents to registered receivers.
745     * Holds BroadcastFilter (subclass of IntentFilter).
746     */
747    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
748            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
749        @Override
750        protected boolean allowFilterResult(
751                BroadcastFilter filter, List<BroadcastFilter> dest) {
752            IBinder target = filter.receiverList.receiver.asBinder();
753            for (int i = dest.size() - 1; i >= 0; i--) {
754                if (dest.get(i).receiverList.receiver.asBinder() == target) {
755                    return false;
756                }
757            }
758            return true;
759        }
760
761        @Override
762        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
763            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
764                    || userId == filter.owningUserId) {
765                return super.newResult(filter, match, userId);
766            }
767            return null;
768        }
769
770        @Override
771        protected BroadcastFilter[] newArray(int size) {
772            return new BroadcastFilter[size];
773        }
774
775        @Override
776        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
777            return packageName.equals(filter.packageName);
778        }
779    };
780
781    /**
782     * State of all active sticky broadcasts per user.  Keys are the action of the
783     * sticky Intent, values are an ArrayList of all broadcasted intents with
784     * that action (which should usually be one).  The SparseArray is keyed
785     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
786     * for stickies that are sent to all users.
787     */
788    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
789            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
790
791    final ActiveServices mServices;
792
793    final static class Association {
794        final int mSourceUid;
795        final String mSourceProcess;
796        final int mTargetUid;
797        final ComponentName mTargetComponent;
798        final String mTargetProcess;
799
800        int mCount;
801        long mTime;
802
803        int mNesting;
804        long mStartTime;
805
806        Association(int sourceUid, String sourceProcess, int targetUid,
807                ComponentName targetComponent, String targetProcess) {
808            mSourceUid = sourceUid;
809            mSourceProcess = sourceProcess;
810            mTargetUid = targetUid;
811            mTargetComponent = targetComponent;
812            mTargetProcess = targetProcess;
813        }
814    }
815
816    /**
817     * When service association tracking is enabled, this is all of the associations we
818     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
819     * -> association data.
820     */
821    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
822            mAssociations = new SparseArray<>();
823    boolean mTrackingAssociations;
824
825    /**
826     * Backup/restore process management
827     */
828    String mBackupAppName = null;
829    BackupRecord mBackupTarget = null;
830
831    final ProviderMap mProviderMap;
832
833    /**
834     * List of content providers who have clients waiting for them.  The
835     * application is currently being launched and the provider will be
836     * removed from this list once it is published.
837     */
838    final ArrayList<ContentProviderRecord> mLaunchingProviders
839            = new ArrayList<ContentProviderRecord>();
840
841    /**
842     * File storing persisted {@link #mGrantedUriPermissions}.
843     */
844    private final AtomicFile mGrantFile;
845
846    /** XML constants used in {@link #mGrantFile} */
847    private static final String TAG_URI_GRANTS = "uri-grants";
848    private static final String TAG_URI_GRANT = "uri-grant";
849    private static final String ATTR_USER_HANDLE = "userHandle";
850    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
851    private static final String ATTR_TARGET_USER_ID = "targetUserId";
852    private static final String ATTR_SOURCE_PKG = "sourcePkg";
853    private static final String ATTR_TARGET_PKG = "targetPkg";
854    private static final String ATTR_URI = "uri";
855    private static final String ATTR_MODE_FLAGS = "modeFlags";
856    private static final String ATTR_CREATED_TIME = "createdTime";
857    private static final String ATTR_PREFIX = "prefix";
858
859    /**
860     * Global set of specific {@link Uri} permissions that have been granted.
861     * This optimized lookup structure maps from {@link UriPermission#targetUid}
862     * to {@link UriPermission#uri} to {@link UriPermission}.
863     */
864    @GuardedBy("this")
865    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
866            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
867
868    public static class GrantUri {
869        public final int sourceUserId;
870        public final Uri uri;
871        public boolean prefix;
872
873        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
874            this.sourceUserId = sourceUserId;
875            this.uri = uri;
876            this.prefix = prefix;
877        }
878
879        @Override
880        public int hashCode() {
881            int hashCode = 1;
882            hashCode = 31 * hashCode + sourceUserId;
883            hashCode = 31 * hashCode + uri.hashCode();
884            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
885            return hashCode;
886        }
887
888        @Override
889        public boolean equals(Object o) {
890            if (o instanceof GrantUri) {
891                GrantUri other = (GrantUri) o;
892                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
893                        && prefix == other.prefix;
894            }
895            return false;
896        }
897
898        @Override
899        public String toString() {
900            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
901            if (prefix) result += " [prefix]";
902            return result;
903        }
904
905        public String toSafeString() {
906            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
907            if (prefix) result += " [prefix]";
908            return result;
909        }
910
911        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
912            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
913                    ContentProvider.getUriWithoutUserId(uri), false);
914        }
915    }
916
917    CoreSettingsObserver mCoreSettingsObserver;
918
919    /**
920     * Thread-local storage used to carry caller permissions over through
921     * indirect content-provider access.
922     */
923    private class Identity {
924        public final IBinder token;
925        public final int pid;
926        public final int uid;
927
928        Identity(IBinder _token, int _pid, int _uid) {
929            token = _token;
930            pid = _pid;
931            uid = _uid;
932        }
933    }
934
935    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
936
937    /**
938     * All information we have collected about the runtime performance of
939     * any user id that can impact battery performance.
940     */
941    final BatteryStatsService mBatteryStatsService;
942
943    /**
944     * Information about component usage
945     */
946    UsageStatsManagerInternal mUsageStatsService;
947
948    /**
949     * Access to DeviceIdleController service.
950     */
951    DeviceIdleController.LocalService mLocalDeviceIdleController;
952
953    /**
954     * Information about and control over application operations
955     */
956    final AppOpsService mAppOpsService;
957
958    /**
959     * Save recent tasks information across reboots.
960     */
961    final TaskPersister mTaskPersister;
962
963    /**
964     * Current configuration information.  HistoryRecord objects are given
965     * a reference to this object to indicate which configuration they are
966     * currently running in, so this object must be kept immutable.
967     */
968    Configuration mConfiguration = new Configuration();
969
970    /**
971     * Current sequencing integer of the configuration, for skipping old
972     * configurations.
973     */
974    int mConfigurationSeq = 0;
975
976    /**
977     * Hardware-reported OpenGLES version.
978     */
979    final int GL_ES_VERSION;
980
981    /**
982     * List of initialization arguments to pass to all processes when binding applications to them.
983     * For example, references to the commonly used services.
984     */
985    HashMap<String, IBinder> mAppBindArgs;
986
987    /**
988     * Temporary to avoid allocations.  Protected by main lock.
989     */
990    final StringBuilder mStringBuilder = new StringBuilder(256);
991
992    /**
993     * Used to control how we initialize the service.
994     */
995    ComponentName mTopComponent;
996    String mTopAction = Intent.ACTION_MAIN;
997    String mTopData;
998    boolean mProcessesReady = false;
999    boolean mSystemReady = false;
1000    boolean mBooting = false;
1001    boolean mCallFinishBooting = false;
1002    boolean mBootAnimationComplete = false;
1003    boolean mWaitingUpdate = false;
1004    boolean mDidUpdate = false;
1005    boolean mOnBattery = false;
1006    boolean mLaunchWarningShown = false;
1007
1008    Context mContext;
1009
1010    int mFactoryTest;
1011
1012    boolean mCheckedForSetup;
1013
1014    /**
1015     * The time at which we will allow normal application switches again,
1016     * after a call to {@link #stopAppSwitches()}.
1017     */
1018    long mAppSwitchesAllowedTime;
1019
1020    /**
1021     * This is set to true after the first switch after mAppSwitchesAllowedTime
1022     * is set; any switches after that will clear the time.
1023     */
1024    boolean mDidAppSwitch;
1025
1026    /**
1027     * Last time (in realtime) at which we checked for power usage.
1028     */
1029    long mLastPowerCheckRealtime;
1030
1031    /**
1032     * Last time (in uptime) at which we checked for power usage.
1033     */
1034    long mLastPowerCheckUptime;
1035
1036    /**
1037     * Set while we are wanting to sleep, to prevent any
1038     * activities from being started/resumed.
1039     */
1040    private boolean mSleeping = false;
1041
1042    /**
1043     * The process state used for processes that are running the top activities.
1044     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1045     */
1046    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1047
1048    /**
1049     * Set while we are running a voice interaction.  This overrides
1050     * sleeping while it is active.
1051     */
1052    private IVoiceInteractionSession mRunningVoice;
1053
1054    /**
1055     * For some direct access we need to power manager.
1056     */
1057    PowerManagerInternal mLocalPowerManager;
1058
1059    /**
1060     * We want to hold a wake lock while running a voice interaction session, since
1061     * this may happen with the screen off and we need to keep the CPU running to
1062     * be able to continue to interact with the user.
1063     */
1064    PowerManager.WakeLock mVoiceWakeLock;
1065
1066    /**
1067     * State of external calls telling us if the device is awake or asleep.
1068     */
1069    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1070
1071    /**
1072     * A list of tokens that cause the top activity to be put to sleep.
1073     * They are used by components that may hide and block interaction with underlying
1074     * activities.
1075     */
1076    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1077
1078    static final int LOCK_SCREEN_HIDDEN = 0;
1079    static final int LOCK_SCREEN_LEAVING = 1;
1080    static final int LOCK_SCREEN_SHOWN = 2;
1081    /**
1082     * State of external call telling us if the lock screen is shown.
1083     */
1084    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1085
1086    /**
1087     * Set if we are shutting down the system, similar to sleeping.
1088     */
1089    boolean mShuttingDown = false;
1090
1091    /**
1092     * Current sequence id for oom_adj computation traversal.
1093     */
1094    int mAdjSeq = 0;
1095
1096    /**
1097     * Current sequence id for process LRU updating.
1098     */
1099    int mLruSeq = 0;
1100
1101    /**
1102     * Keep track of the non-cached/empty process we last found, to help
1103     * determine how to distribute cached/empty processes next time.
1104     */
1105    int mNumNonCachedProcs = 0;
1106
1107    /**
1108     * Keep track of the number of cached hidden procs, to balance oom adj
1109     * distribution between those and empty procs.
1110     */
1111    int mNumCachedHiddenProcs = 0;
1112
1113    /**
1114     * Keep track of the number of service processes we last found, to
1115     * determine on the next iteration which should be B services.
1116     */
1117    int mNumServiceProcs = 0;
1118    int mNewNumAServiceProcs = 0;
1119    int mNewNumServiceProcs = 0;
1120
1121    /**
1122     * Allow the current computed overall memory level of the system to go down?
1123     * This is set to false when we are killing processes for reasons other than
1124     * memory management, so that the now smaller process list will not be taken as
1125     * an indication that memory is tighter.
1126     */
1127    boolean mAllowLowerMemLevel = false;
1128
1129    /**
1130     * The last computed memory level, for holding when we are in a state that
1131     * processes are going away for other reasons.
1132     */
1133    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1134
1135    /**
1136     * The last total number of process we have, to determine if changes actually look
1137     * like a shrinking number of process due to lower RAM.
1138     */
1139    int mLastNumProcesses;
1140
1141    /**
1142     * The uptime of the last time we performed idle maintenance.
1143     */
1144    long mLastIdleTime = SystemClock.uptimeMillis();
1145
1146    /**
1147     * Total time spent with RAM that has been added in the past since the last idle time.
1148     */
1149    long mLowRamTimeSinceLastIdle = 0;
1150
1151    /**
1152     * If RAM is currently low, when that horrible situation started.
1153     */
1154    long mLowRamStartTime = 0;
1155
1156    /**
1157     * For reporting to battery stats the current top application.
1158     */
1159    private String mCurResumedPackage = null;
1160    private int mCurResumedUid = -1;
1161
1162    /**
1163     * For reporting to battery stats the apps currently running foreground
1164     * service.  The ProcessMap is package/uid tuples; each of these contain
1165     * an array of the currently foreground processes.
1166     */
1167    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1168            = new ProcessMap<ArrayList<ProcessRecord>>();
1169
1170    /**
1171     * This is set if we had to do a delayed dexopt of an app before launching
1172     * it, to increase the ANR timeouts in that case.
1173     */
1174    boolean mDidDexOpt;
1175
1176    /**
1177     * Set if the systemServer made a call to enterSafeMode.
1178     */
1179    boolean mSafeMode;
1180
1181    /**
1182     * If true, we are running under a test environment so will sample PSS from processes
1183     * much more rapidly to try to collect better data when the tests are rapidly
1184     * running through apps.
1185     */
1186    boolean mTestPssMode = false;
1187
1188    String mDebugApp = null;
1189    boolean mWaitForDebugger = false;
1190    boolean mDebugTransient = false;
1191    String mOrigDebugApp = null;
1192    boolean mOrigWaitForDebugger = false;
1193    boolean mAlwaysFinishActivities = false;
1194    IActivityController mController = null;
1195    String mProfileApp = null;
1196    ProcessRecord mProfileProc = null;
1197    String mProfileFile;
1198    ParcelFileDescriptor mProfileFd;
1199    int mSamplingInterval = 0;
1200    boolean mAutoStopProfiler = false;
1201    int mProfileType = 0;
1202    String mOpenGlTraceApp = null;
1203    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1204    String mMemWatchDumpProcName;
1205    String mMemWatchDumpFile;
1206    int mMemWatchDumpPid;
1207    int mMemWatchDumpUid;
1208    String mTrackAllocationApp = null;
1209
1210    final long[] mTmpLong = new long[1];
1211
1212    static final class ProcessChangeItem {
1213        static final int CHANGE_ACTIVITIES = 1<<0;
1214        static final int CHANGE_PROCESS_STATE = 1<<1;
1215        int changes;
1216        int uid;
1217        int pid;
1218        int processState;
1219        boolean foregroundActivities;
1220    }
1221
1222    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1223    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1224
1225    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1226    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1227
1228    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1229    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1230
1231    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1232    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1233
1234    /**
1235     * Runtime CPU use collection thread.  This object's lock is used to
1236     * perform synchronization with the thread (notifying it to run).
1237     */
1238    final Thread mProcessCpuThread;
1239
1240    /**
1241     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1242     * Must acquire this object's lock when accessing it.
1243     * NOTE: this lock will be held while doing long operations (trawling
1244     * through all processes in /proc), so it should never be acquired by
1245     * any critical paths such as when holding the main activity manager lock.
1246     */
1247    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1248            MONITOR_THREAD_CPU_USAGE);
1249    final AtomicLong mLastCpuTime = new AtomicLong(0);
1250    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1251
1252    long mLastWriteTime = 0;
1253
1254    /**
1255     * Used to retain an update lock when the foreground activity is in
1256     * immersive mode.
1257     */
1258    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1259
1260    /**
1261     * Set to true after the system has finished booting.
1262     */
1263    boolean mBooted = false;
1264
1265    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1266    int mProcessLimitOverride = -1;
1267
1268    WindowManagerService mWindowManager;
1269
1270    final ActivityThread mSystemThread;
1271
1272    // Holds the current foreground user's id
1273    int mCurrentUserId = 0;
1274    // Holds the target user's id during a user switch
1275    int mTargetUserId = UserHandle.USER_NULL;
1276    // If there are multiple profiles for the current user, their ids are here
1277    // Currently only the primary user can have managed profiles
1278    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1279
1280    /**
1281     * Mapping from each known user ID to the profile group ID it is associated with.
1282     */
1283    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1284
1285    private UserManagerService mUserManager;
1286
1287    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1288        final ProcessRecord mApp;
1289        final int mPid;
1290        final IApplicationThread mAppThread;
1291
1292        AppDeathRecipient(ProcessRecord app, int pid,
1293                IApplicationThread thread) {
1294            if (DEBUG_ALL) Slog.v(
1295                TAG, "New death recipient " + this
1296                + " for thread " + thread.asBinder());
1297            mApp = app;
1298            mPid = pid;
1299            mAppThread = thread;
1300        }
1301
1302        @Override
1303        public void binderDied() {
1304            if (DEBUG_ALL) Slog.v(
1305                TAG, "Death received in " + this
1306                + " for thread " + mAppThread.asBinder());
1307            synchronized(ActivityManagerService.this) {
1308                appDiedLocked(mApp, mPid, mAppThread, true);
1309            }
1310        }
1311    }
1312
1313    static final int SHOW_ERROR_MSG = 1;
1314    static final int SHOW_NOT_RESPONDING_MSG = 2;
1315    static final int SHOW_FACTORY_ERROR_MSG = 3;
1316    static final int UPDATE_CONFIGURATION_MSG = 4;
1317    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1318    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1319    static final int SERVICE_TIMEOUT_MSG = 12;
1320    static final int UPDATE_TIME_ZONE = 13;
1321    static final int SHOW_UID_ERROR_MSG = 14;
1322    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1323    static final int PROC_START_TIMEOUT_MSG = 20;
1324    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1325    static final int KILL_APPLICATION_MSG = 22;
1326    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1327    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1328    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1329    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1330    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1331    static final int CLEAR_DNS_CACHE_MSG = 28;
1332    static final int UPDATE_HTTP_PROXY_MSG = 29;
1333    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1334    static final int DISPATCH_PROCESSES_CHANGED = 31;
1335    static final int DISPATCH_PROCESS_DIED = 32;
1336    static final int REPORT_MEM_USAGE_MSG = 33;
1337    static final int REPORT_USER_SWITCH_MSG = 34;
1338    static final int CONTINUE_USER_SWITCH_MSG = 35;
1339    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1340    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1341    static final int PERSIST_URI_GRANTS_MSG = 38;
1342    static final int REQUEST_ALL_PSS_MSG = 39;
1343    static final int START_PROFILES_MSG = 40;
1344    static final int UPDATE_TIME = 41;
1345    static final int SYSTEM_USER_START_MSG = 42;
1346    static final int SYSTEM_USER_CURRENT_MSG = 43;
1347    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1348    static final int FINISH_BOOTING_MSG = 45;
1349    static final int START_USER_SWITCH_MSG = 46;
1350    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1351    static final int DISMISS_DIALOG_MSG = 48;
1352    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1353    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1354    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1355    static final int DELETE_DUMPHEAP_MSG = 52;
1356    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1357    static final int DISPATCH_UIDS_CHANGED_MSG = 54;
1358    static final int REPORT_TIME_TRACKER_MSG = 55;
1359    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1360
1361    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1362    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1363    static final int FIRST_COMPAT_MODE_MSG = 300;
1364    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1365
1366    CompatModeDialog mCompatModeDialog;
1367    long mLastMemUsageReportTime = 0;
1368
1369    /**
1370     * Flag whether the current user is a "monkey", i.e. whether
1371     * the UI is driven by a UI automation tool.
1372     */
1373    private boolean mUserIsMonkey;
1374
1375    /** Flag whether the device has a Recents UI */
1376    boolean mHasRecents;
1377
1378    /** The dimensions of the thumbnails in the Recents UI. */
1379    int mThumbnailWidth;
1380    int mThumbnailHeight;
1381
1382    final ServiceThread mHandlerThread;
1383    final MainHandler mHandler;
1384    final UiHandler mUiHandler;
1385
1386    final class UiHandler extends Handler {
1387        public UiHandler() {
1388            super(com.android.server.UiThread.get().getLooper(), null, true);
1389        }
1390
1391        @Override
1392        public void handleMessage(Message msg) {
1393            switch (msg.what) {
1394            case SHOW_ERROR_MSG: {
1395                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1396                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1397                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1398                synchronized (ActivityManagerService.this) {
1399                    ProcessRecord proc = (ProcessRecord)data.get("app");
1400                    AppErrorResult res = (AppErrorResult) data.get("result");
1401                    if (proc != null && proc.crashDialog != null) {
1402                        Slog.e(TAG, "App already has crash dialog: " + proc);
1403                        if (res != null) {
1404                            res.set(0);
1405                        }
1406                        return;
1407                    }
1408                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1409                            >= Process.FIRST_APPLICATION_UID
1410                            && proc.pid != MY_PID);
1411                    for (int userId : mCurrentProfileIds) {
1412                        isBackground &= (proc.userId != userId);
1413                    }
1414                    if (isBackground && !showBackground) {
1415                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1416                        if (res != null) {
1417                            res.set(0);
1418                        }
1419                        return;
1420                    }
1421                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1422                        Dialog d = new AppErrorDialog(mContext,
1423                                ActivityManagerService.this, res, proc);
1424                        d.show();
1425                        proc.crashDialog = d;
1426                    } else {
1427                        // The device is asleep, so just pretend that the user
1428                        // saw a crash dialog and hit "force quit".
1429                        if (res != null) {
1430                            res.set(0);
1431                        }
1432                    }
1433                }
1434
1435                ensureBootCompleted();
1436            } break;
1437            case SHOW_NOT_RESPONDING_MSG: {
1438                synchronized (ActivityManagerService.this) {
1439                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1440                    ProcessRecord proc = (ProcessRecord)data.get("app");
1441                    if (proc != null && proc.anrDialog != null) {
1442                        Slog.e(TAG, "App already has anr dialog: " + proc);
1443                        return;
1444                    }
1445
1446                    Intent intent = new Intent("android.intent.action.ANR");
1447                    if (!mProcessesReady) {
1448                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1449                                | Intent.FLAG_RECEIVER_FOREGROUND);
1450                    }
1451                    broadcastIntentLocked(null, null, intent,
1452                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1453                            null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1454
1455                    if (mShowDialogs) {
1456                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1457                                mContext, proc, (ActivityRecord)data.get("activity"),
1458                                msg.arg1 != 0);
1459                        d.show();
1460                        proc.anrDialog = d;
1461                    } else {
1462                        // Just kill the app if there is no dialog to be shown.
1463                        killAppAtUsersRequest(proc, null);
1464                    }
1465                }
1466
1467                ensureBootCompleted();
1468            } break;
1469            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1470                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1471                synchronized (ActivityManagerService.this) {
1472                    ProcessRecord proc = (ProcessRecord) data.get("app");
1473                    if (proc == null) {
1474                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1475                        break;
1476                    }
1477                    if (proc.crashDialog != null) {
1478                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1479                        return;
1480                    }
1481                    AppErrorResult res = (AppErrorResult) data.get("result");
1482                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1483                        Dialog d = new StrictModeViolationDialog(mContext,
1484                                ActivityManagerService.this, res, proc);
1485                        d.show();
1486                        proc.crashDialog = d;
1487                    } else {
1488                        // The device is asleep, so just pretend that the user
1489                        // saw a crash dialog and hit "force quit".
1490                        res.set(0);
1491                    }
1492                }
1493                ensureBootCompleted();
1494            } break;
1495            case SHOW_FACTORY_ERROR_MSG: {
1496                Dialog d = new FactoryErrorDialog(
1497                    mContext, msg.getData().getCharSequence("msg"));
1498                d.show();
1499                ensureBootCompleted();
1500            } break;
1501            case WAIT_FOR_DEBUGGER_MSG: {
1502                synchronized (ActivityManagerService.this) {
1503                    ProcessRecord app = (ProcessRecord)msg.obj;
1504                    if (msg.arg1 != 0) {
1505                        if (!app.waitedForDebugger) {
1506                            Dialog d = new AppWaitingForDebuggerDialog(
1507                                    ActivityManagerService.this,
1508                                    mContext, app);
1509                            app.waitDialog = d;
1510                            app.waitedForDebugger = true;
1511                            d.show();
1512                        }
1513                    } else {
1514                        if (app.waitDialog != null) {
1515                            app.waitDialog.dismiss();
1516                            app.waitDialog = null;
1517                        }
1518                    }
1519                }
1520            } break;
1521            case SHOW_UID_ERROR_MSG: {
1522                if (mShowDialogs) {
1523                    AlertDialog d = new BaseErrorDialog(mContext);
1524                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1525                    d.setCancelable(false);
1526                    d.setTitle(mContext.getText(R.string.android_system_label));
1527                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1528                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1529                            obtainMessage(DISMISS_DIALOG_MSG, d));
1530                    d.show();
1531                }
1532            } break;
1533            case SHOW_FINGERPRINT_ERROR_MSG: {
1534                if (mShowDialogs) {
1535                    AlertDialog d = new BaseErrorDialog(mContext);
1536                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1537                    d.setCancelable(false);
1538                    d.setTitle(mContext.getText(R.string.android_system_label));
1539                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1540                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1541                            obtainMessage(DISMISS_DIALOG_MSG, d));
1542                    d.show();
1543                }
1544            } break;
1545            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1546                synchronized (ActivityManagerService.this) {
1547                    ActivityRecord ar = (ActivityRecord) msg.obj;
1548                    if (mCompatModeDialog != null) {
1549                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1550                                ar.info.applicationInfo.packageName)) {
1551                            return;
1552                        }
1553                        mCompatModeDialog.dismiss();
1554                        mCompatModeDialog = null;
1555                    }
1556                    if (ar != null && false) {
1557                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1558                                ar.packageName)) {
1559                            int mode = mCompatModePackages.computeCompatModeLocked(
1560                                    ar.info.applicationInfo);
1561                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1562                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1563                                mCompatModeDialog = new CompatModeDialog(
1564                                        ActivityManagerService.this, mContext,
1565                                        ar.info.applicationInfo);
1566                                mCompatModeDialog.show();
1567                            }
1568                        }
1569                    }
1570                }
1571                break;
1572            }
1573            case START_USER_SWITCH_MSG: {
1574                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1575                break;
1576            }
1577            case DISMISS_DIALOG_MSG: {
1578                final Dialog d = (Dialog) msg.obj;
1579                d.dismiss();
1580                break;
1581            }
1582            case DISPATCH_PROCESSES_CHANGED: {
1583                dispatchProcessesChanged();
1584                break;
1585            }
1586            case DISPATCH_PROCESS_DIED: {
1587                final int pid = msg.arg1;
1588                final int uid = msg.arg2;
1589                dispatchProcessDied(pid, uid);
1590                break;
1591            }
1592            case DISPATCH_UIDS_CHANGED_MSG: {
1593                dispatchUidsChanged();
1594            } break;
1595            }
1596        }
1597    }
1598
1599    final class MainHandler extends Handler {
1600        public MainHandler(Looper looper) {
1601            super(looper, null, true);
1602        }
1603
1604        @Override
1605        public void handleMessage(Message msg) {
1606            switch (msg.what) {
1607            case UPDATE_CONFIGURATION_MSG: {
1608                final ContentResolver resolver = mContext.getContentResolver();
1609                Settings.System.putConfiguration(resolver, (Configuration) msg.obj);
1610            } break;
1611            case GC_BACKGROUND_PROCESSES_MSG: {
1612                synchronized (ActivityManagerService.this) {
1613                    performAppGcsIfAppropriateLocked();
1614                }
1615            } break;
1616            case SERVICE_TIMEOUT_MSG: {
1617                if (mDidDexOpt) {
1618                    mDidDexOpt = false;
1619                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1620                    nmsg.obj = msg.obj;
1621                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1622                    return;
1623                }
1624                mServices.serviceTimeout((ProcessRecord)msg.obj);
1625            } break;
1626            case UPDATE_TIME_ZONE: {
1627                synchronized (ActivityManagerService.this) {
1628                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1629                        ProcessRecord r = mLruProcesses.get(i);
1630                        if (r.thread != null) {
1631                            try {
1632                                r.thread.updateTimeZone();
1633                            } catch (RemoteException ex) {
1634                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1635                            }
1636                        }
1637                    }
1638                }
1639            } break;
1640            case CLEAR_DNS_CACHE_MSG: {
1641                synchronized (ActivityManagerService.this) {
1642                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1643                        ProcessRecord r = mLruProcesses.get(i);
1644                        if (r.thread != null) {
1645                            try {
1646                                r.thread.clearDnsCache();
1647                            } catch (RemoteException ex) {
1648                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1649                            }
1650                        }
1651                    }
1652                }
1653            } break;
1654            case UPDATE_HTTP_PROXY_MSG: {
1655                ProxyInfo proxy = (ProxyInfo)msg.obj;
1656                String host = "";
1657                String port = "";
1658                String exclList = "";
1659                Uri pacFileUrl = Uri.EMPTY;
1660                if (proxy != null) {
1661                    host = proxy.getHost();
1662                    port = Integer.toString(proxy.getPort());
1663                    exclList = proxy.getExclusionListAsString();
1664                    pacFileUrl = proxy.getPacFileUrl();
1665                }
1666                synchronized (ActivityManagerService.this) {
1667                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1668                        ProcessRecord r = mLruProcesses.get(i);
1669                        if (r.thread != null) {
1670                            try {
1671                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1672                            } catch (RemoteException ex) {
1673                                Slog.w(TAG, "Failed to update http proxy for: " +
1674                                        r.info.processName);
1675                            }
1676                        }
1677                    }
1678                }
1679            } break;
1680            case PROC_START_TIMEOUT_MSG: {
1681                if (mDidDexOpt) {
1682                    mDidDexOpt = false;
1683                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1684                    nmsg.obj = msg.obj;
1685                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1686                    return;
1687                }
1688                ProcessRecord app = (ProcessRecord)msg.obj;
1689                synchronized (ActivityManagerService.this) {
1690                    processStartTimedOutLocked(app);
1691                }
1692            } break;
1693            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1694                synchronized (ActivityManagerService.this) {
1695                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1696                }
1697            } break;
1698            case KILL_APPLICATION_MSG: {
1699                synchronized (ActivityManagerService.this) {
1700                    int appid = msg.arg1;
1701                    boolean restart = (msg.arg2 == 1);
1702                    Bundle bundle = (Bundle)msg.obj;
1703                    String pkg = bundle.getString("pkg");
1704                    String reason = bundle.getString("reason");
1705                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1706                            false, UserHandle.USER_ALL, reason);
1707                }
1708            } break;
1709            case FINALIZE_PENDING_INTENT_MSG: {
1710                ((PendingIntentRecord)msg.obj).completeFinalize();
1711            } break;
1712            case POST_HEAVY_NOTIFICATION_MSG: {
1713                INotificationManager inm = NotificationManager.getService();
1714                if (inm == null) {
1715                    return;
1716                }
1717
1718                ActivityRecord root = (ActivityRecord)msg.obj;
1719                ProcessRecord process = root.app;
1720                if (process == null) {
1721                    return;
1722                }
1723
1724                try {
1725                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1726                    String text = mContext.getString(R.string.heavy_weight_notification,
1727                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1728                    Notification notification = new Notification.Builder(context)
1729                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1730                            .setWhen(0)
1731                            .setOngoing(true)
1732                            .setTicker(text)
1733                            .setColor(mContext.getColor(
1734                                    com.android.internal.R.color.system_notification_accent_color))
1735                            .setContentTitle(text)
1736                            .setContentText(
1737                                    mContext.getText(R.string.heavy_weight_notification_detail))
1738                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1739                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1740                                    new UserHandle(root.userId)))
1741                            .build();
1742                    try {
1743                        int[] outId = new int[1];
1744                        inm.enqueueNotificationWithTag("android", "android", null,
1745                                R.string.heavy_weight_notification,
1746                                notification, outId, root.userId);
1747                    } catch (RuntimeException e) {
1748                        Slog.w(ActivityManagerService.TAG,
1749                                "Error showing notification for heavy-weight app", e);
1750                    } catch (RemoteException e) {
1751                    }
1752                } catch (NameNotFoundException e) {
1753                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1754                }
1755            } break;
1756            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1757                INotificationManager inm = NotificationManager.getService();
1758                if (inm == null) {
1759                    return;
1760                }
1761                try {
1762                    inm.cancelNotificationWithTag("android", null,
1763                            R.string.heavy_weight_notification,  msg.arg1);
1764                } catch (RuntimeException e) {
1765                    Slog.w(ActivityManagerService.TAG,
1766                            "Error canceling notification for service", e);
1767                } catch (RemoteException e) {
1768                }
1769            } break;
1770            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1771                synchronized (ActivityManagerService.this) {
1772                    checkExcessivePowerUsageLocked(true);
1773                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1774                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1775                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1776                }
1777            } break;
1778            case REPORT_MEM_USAGE_MSG: {
1779                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1780                Thread thread = new Thread() {
1781                    @Override public void run() {
1782                        reportMemUsage(memInfos);
1783                    }
1784                };
1785                thread.start();
1786                break;
1787            }
1788            case REPORT_USER_SWITCH_MSG: {
1789                dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1790                break;
1791            }
1792            case CONTINUE_USER_SWITCH_MSG: {
1793                continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1794                break;
1795            }
1796            case USER_SWITCH_TIMEOUT_MSG: {
1797                timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1798                break;
1799            }
1800            case IMMERSIVE_MODE_LOCK_MSG: {
1801                final boolean nextState = (msg.arg1 != 0);
1802                if (mUpdateLock.isHeld() != nextState) {
1803                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1804                            "Applying new update lock state '" + nextState
1805                            + "' for " + (ActivityRecord)msg.obj);
1806                    if (nextState) {
1807                        mUpdateLock.acquire();
1808                    } else {
1809                        mUpdateLock.release();
1810                    }
1811                }
1812                break;
1813            }
1814            case PERSIST_URI_GRANTS_MSG: {
1815                writeGrantedUriPermissions();
1816                break;
1817            }
1818            case REQUEST_ALL_PSS_MSG: {
1819                synchronized (ActivityManagerService.this) {
1820                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1821                }
1822                break;
1823            }
1824            case START_PROFILES_MSG: {
1825                synchronized (ActivityManagerService.this) {
1826                    startProfilesLocked();
1827                }
1828                break;
1829            }
1830            case UPDATE_TIME: {
1831                synchronized (ActivityManagerService.this) {
1832                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1833                        ProcessRecord r = mLruProcesses.get(i);
1834                        if (r.thread != null) {
1835                            try {
1836                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1837                            } catch (RemoteException ex) {
1838                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1839                            }
1840                        }
1841                    }
1842                }
1843                break;
1844            }
1845            case SYSTEM_USER_START_MSG: {
1846                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1847                        Integer.toString(msg.arg1), msg.arg1);
1848                mSystemServiceManager.startUser(msg.arg1);
1849                break;
1850            }
1851            case SYSTEM_USER_CURRENT_MSG: {
1852                mBatteryStatsService.noteEvent(
1853                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1854                        Integer.toString(msg.arg2), msg.arg2);
1855                mBatteryStatsService.noteEvent(
1856                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1857                        Integer.toString(msg.arg1), msg.arg1);
1858                mSystemServiceManager.switchUser(msg.arg1);
1859                break;
1860            }
1861            case ENTER_ANIMATION_COMPLETE_MSG: {
1862                synchronized (ActivityManagerService.this) {
1863                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1864                    if (r != null && r.app != null && r.app.thread != null) {
1865                        try {
1866                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1867                        } catch (RemoteException e) {
1868                        }
1869                    }
1870                }
1871                break;
1872            }
1873            case FINISH_BOOTING_MSG: {
1874                if (msg.arg1 != 0) {
1875                    finishBooting();
1876                }
1877                if (msg.arg2 != 0) {
1878                    enableScreenAfterBoot();
1879                }
1880                break;
1881            }
1882            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1883                try {
1884                    Locale l = (Locale) msg.obj;
1885                    IBinder service = ServiceManager.getService("mount");
1886                    IMountService mountService = IMountService.Stub.asInterface(service);
1887                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1888                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1889                } catch (RemoteException e) {
1890                    Log.e(TAG, "Error storing locale for decryption UI", e);
1891                }
1892                break;
1893            }
1894            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1895                synchronized (ActivityManagerService.this) {
1896                    int i = mTaskStackListeners.beginBroadcast();
1897                    while (i > 0) {
1898                        i--;
1899                        try {
1900                            // Make a one-way callback to the listener
1901                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1902                        } catch (RemoteException e){
1903                            // Handled by the RemoteCallbackList
1904                        }
1905                    }
1906                    mTaskStackListeners.finishBroadcast();
1907                }
1908                break;
1909            }
1910            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1911                final int uid = msg.arg1;
1912                final byte[] firstPacket = (byte[]) msg.obj;
1913
1914                synchronized (mPidsSelfLocked) {
1915                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
1916                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
1917                        if (p.uid == uid) {
1918                            try {
1919                                p.thread.notifyCleartextNetwork(firstPacket);
1920                            } catch (RemoteException ignored) {
1921                            }
1922                        }
1923                    }
1924                }
1925                break;
1926            }
1927            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
1928                final String procName;
1929                final int uid;
1930                final long memLimit;
1931                final String reportPackage;
1932                synchronized (ActivityManagerService.this) {
1933                    procName = mMemWatchDumpProcName;
1934                    uid = mMemWatchDumpUid;
1935                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
1936                    if (val == null) {
1937                        val = mMemWatchProcesses.get(procName, 0);
1938                    }
1939                    if (val != null) {
1940                        memLimit = val.first;
1941                        reportPackage = val.second;
1942                    } else {
1943                        memLimit = 0;
1944                        reportPackage = null;
1945                    }
1946                }
1947                if (procName == null) {
1948                    return;
1949                }
1950
1951                if (DEBUG_PSS) Slog.d(TAG_PSS,
1952                        "Showing dump heap notification from " + procName + "/" + uid);
1953
1954                INotificationManager inm = NotificationManager.getService();
1955                if (inm == null) {
1956                    return;
1957                }
1958
1959                String text = mContext.getString(R.string.dump_heap_notification, procName);
1960
1961
1962                Intent deleteIntent = new Intent();
1963                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
1964                Intent intent = new Intent();
1965                intent.setClassName("android", DumpHeapActivity.class.getName());
1966                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
1967                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
1968                if (reportPackage != null) {
1969                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
1970                }
1971                int userId = UserHandle.getUserId(uid);
1972                Notification notification = new Notification.Builder(mContext)
1973                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1974                        .setWhen(0)
1975                        .setOngoing(true)
1976                        .setAutoCancel(true)
1977                        .setTicker(text)
1978                        .setColor(mContext.getColor(
1979                                com.android.internal.R.color.system_notification_accent_color))
1980                        .setContentTitle(text)
1981                        .setContentText(
1982                                mContext.getText(R.string.dump_heap_notification_detail))
1983                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1984                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1985                                new UserHandle(userId)))
1986                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
1987                                deleteIntent, 0, UserHandle.OWNER))
1988                        .build();
1989
1990                try {
1991                    int[] outId = new int[1];
1992                    inm.enqueueNotificationWithTag("android", "android", null,
1993                            R.string.dump_heap_notification,
1994                            notification, outId, userId);
1995                } catch (RuntimeException e) {
1996                    Slog.w(ActivityManagerService.TAG,
1997                            "Error showing notification for dump heap", e);
1998                } catch (RemoteException e) {
1999                }
2000            } break;
2001            case DELETE_DUMPHEAP_MSG: {
2002                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2003                        DumpHeapActivity.JAVA_URI,
2004                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2005                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2006                        UserHandle.myUserId());
2007                synchronized (ActivityManagerService.this) {
2008                    mMemWatchDumpFile = null;
2009                    mMemWatchDumpProcName = null;
2010                    mMemWatchDumpPid = -1;
2011                    mMemWatchDumpUid = -1;
2012                }
2013            } break;
2014            case FOREGROUND_PROFILE_CHANGED_MSG: {
2015                dispatchForegroundProfileChanged(msg.arg1);
2016            } break;
2017            case REPORT_TIME_TRACKER_MSG: {
2018                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2019                tracker.deliverResult(mContext);
2020            } break;
2021            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2022                dispatchUserSwitchComplete(msg.arg1);
2023            } break;
2024            }
2025        }
2026    };
2027
2028    static final int COLLECT_PSS_BG_MSG = 1;
2029
2030    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2031        @Override
2032        public void handleMessage(Message msg) {
2033            switch (msg.what) {
2034            case COLLECT_PSS_BG_MSG: {
2035                long start = SystemClock.uptimeMillis();
2036                MemInfoReader memInfo = null;
2037                synchronized (ActivityManagerService.this) {
2038                    if (mFullPssPending) {
2039                        mFullPssPending = false;
2040                        memInfo = new MemInfoReader();
2041                    }
2042                }
2043                if (memInfo != null) {
2044                    updateCpuStatsNow();
2045                    long nativeTotalPss = 0;
2046                    synchronized (mProcessCpuTracker) {
2047                        final int N = mProcessCpuTracker.countStats();
2048                        for (int j=0; j<N; j++) {
2049                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2050                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2051                                // This is definitely an application process; skip it.
2052                                continue;
2053                            }
2054                            synchronized (mPidsSelfLocked) {
2055                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2056                                    // This is one of our own processes; skip it.
2057                                    continue;
2058                                }
2059                            }
2060                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2061                        }
2062                    }
2063                    memInfo.readMemInfo();
2064                    synchronized (ActivityManagerService.this) {
2065                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2066                                + (SystemClock.uptimeMillis()-start) + "ms");
2067                        final long cachedKb = memInfo.getCachedSizeKb();
2068                        final long freeKb = memInfo.getFreeSizeKb();
2069                        final long zramKb = memInfo.getZramTotalSizeKb();
2070                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2071                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2072                                kernelKb*1024, nativeTotalPss*1024);
2073                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2074                                nativeTotalPss);
2075                    }
2076                }
2077
2078                int num = 0;
2079                long[] tmp = new long[1];
2080                do {
2081                    ProcessRecord proc;
2082                    int procState;
2083                    int pid;
2084                    long lastPssTime;
2085                    synchronized (ActivityManagerService.this) {
2086                        if (mPendingPssProcesses.size() <= 0) {
2087                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2088                                    "Collected PSS of " + num + " processes in "
2089                                    + (SystemClock.uptimeMillis() - start) + "ms");
2090                            mPendingPssProcesses.clear();
2091                            return;
2092                        }
2093                        proc = mPendingPssProcesses.remove(0);
2094                        procState = proc.pssProcState;
2095                        lastPssTime = proc.lastPssTime;
2096                        if (proc.thread != null && procState == proc.setProcState
2097                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2098                                        < SystemClock.uptimeMillis()) {
2099                            pid = proc.pid;
2100                        } else {
2101                            proc = null;
2102                            pid = 0;
2103                        }
2104                    }
2105                    if (proc != null) {
2106                        long pss = Debug.getPss(pid, tmp, null);
2107                        synchronized (ActivityManagerService.this) {
2108                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2109                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2110                                num++;
2111                                recordPssSampleLocked(proc, procState, pss, tmp[0],
2112                                        SystemClock.uptimeMillis());
2113                            }
2114                        }
2115                    }
2116                } while (true);
2117            }
2118            }
2119        }
2120    };
2121
2122    public void setSystemProcess() {
2123        try {
2124            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2125            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2126            ServiceManager.addService("meminfo", new MemBinder(this));
2127            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2128            ServiceManager.addService("dbinfo", new DbBinder(this));
2129            if (MONITOR_CPU_USAGE) {
2130                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2131            }
2132            ServiceManager.addService("permission", new PermissionController(this));
2133            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2134
2135            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2136                    "android", STOCK_PM_FLAGS);
2137            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2138
2139            synchronized (this) {
2140                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2141                app.persistent = true;
2142                app.pid = MY_PID;
2143                app.maxAdj = ProcessList.SYSTEM_ADJ;
2144                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2145                synchronized (mPidsSelfLocked) {
2146                    mPidsSelfLocked.put(app.pid, app);
2147                }
2148                updateLruProcessLocked(app, false, null);
2149                updateOomAdjLocked();
2150            }
2151        } catch (PackageManager.NameNotFoundException e) {
2152            throw new RuntimeException(
2153                    "Unable to find android system package", e);
2154        }
2155    }
2156
2157    public void setWindowManager(WindowManagerService wm) {
2158        mWindowManager = wm;
2159        mStackSupervisor.setWindowManager(wm);
2160    }
2161
2162    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2163        mUsageStatsService = usageStatsManager;
2164    }
2165
2166    public void startObservingNativeCrashes() {
2167        final NativeCrashListener ncl = new NativeCrashListener(this);
2168        ncl.start();
2169    }
2170
2171    public IAppOpsService getAppOpsService() {
2172        return mAppOpsService;
2173    }
2174
2175    static class MemBinder extends Binder {
2176        ActivityManagerService mActivityManagerService;
2177        MemBinder(ActivityManagerService activityManagerService) {
2178            mActivityManagerService = activityManagerService;
2179        }
2180
2181        @Override
2182        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2183            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2184                    != PackageManager.PERMISSION_GRANTED) {
2185                pw.println("Permission Denial: can't dump meminfo from from pid="
2186                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2187                        + " without permission " + android.Manifest.permission.DUMP);
2188                return;
2189            }
2190
2191            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2192        }
2193    }
2194
2195    static class GraphicsBinder extends Binder {
2196        ActivityManagerService mActivityManagerService;
2197        GraphicsBinder(ActivityManagerService activityManagerService) {
2198            mActivityManagerService = activityManagerService;
2199        }
2200
2201        @Override
2202        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2203            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2204                    != PackageManager.PERMISSION_GRANTED) {
2205                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2206                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2207                        + " without permission " + android.Manifest.permission.DUMP);
2208                return;
2209            }
2210
2211            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2212        }
2213    }
2214
2215    static class DbBinder extends Binder {
2216        ActivityManagerService mActivityManagerService;
2217        DbBinder(ActivityManagerService activityManagerService) {
2218            mActivityManagerService = activityManagerService;
2219        }
2220
2221        @Override
2222        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2223            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2224                    != PackageManager.PERMISSION_GRANTED) {
2225                pw.println("Permission Denial: can't dump dbinfo from from pid="
2226                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2227                        + " without permission " + android.Manifest.permission.DUMP);
2228                return;
2229            }
2230
2231            mActivityManagerService.dumpDbInfo(fd, pw, args);
2232        }
2233    }
2234
2235    static class CpuBinder extends Binder {
2236        ActivityManagerService mActivityManagerService;
2237        CpuBinder(ActivityManagerService activityManagerService) {
2238            mActivityManagerService = activityManagerService;
2239        }
2240
2241        @Override
2242        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2243            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2244                    != PackageManager.PERMISSION_GRANTED) {
2245                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2246                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2247                        + " without permission " + android.Manifest.permission.DUMP);
2248                return;
2249            }
2250
2251            synchronized (mActivityManagerService.mProcessCpuTracker) {
2252                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2253                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2254                        SystemClock.uptimeMillis()));
2255            }
2256        }
2257    }
2258
2259    public static final class Lifecycle extends SystemService {
2260        private final ActivityManagerService mService;
2261
2262        public Lifecycle(Context context) {
2263            super(context);
2264            mService = new ActivityManagerService(context);
2265        }
2266
2267        @Override
2268        public void onStart() {
2269            mService.start();
2270        }
2271
2272        public ActivityManagerService getService() {
2273            return mService;
2274        }
2275    }
2276
2277    // Note: This method is invoked on the main thread but may need to attach various
2278    // handlers to other threads.  So take care to be explicit about the looper.
2279    public ActivityManagerService(Context systemContext) {
2280        mContext = systemContext;
2281        mFactoryTest = FactoryTest.getMode();
2282        mSystemThread = ActivityThread.currentActivityThread();
2283
2284        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2285
2286        mHandlerThread = new ServiceThread(TAG,
2287                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2288        mHandlerThread.start();
2289        mHandler = new MainHandler(mHandlerThread.getLooper());
2290        mUiHandler = new UiHandler();
2291
2292        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2293                "foreground", BROADCAST_FG_TIMEOUT, false);
2294        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2295                "background", BROADCAST_BG_TIMEOUT, true);
2296        mBroadcastQueues[0] = mFgBroadcastQueue;
2297        mBroadcastQueues[1] = mBgBroadcastQueue;
2298
2299        mServices = new ActiveServices(this);
2300        mProviderMap = new ProviderMap(this);
2301
2302        // TODO: Move creation of battery stats service outside of activity manager service.
2303        File dataDir = Environment.getDataDirectory();
2304        File systemDir = new File(dataDir, "system");
2305        systemDir.mkdirs();
2306        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2307        mBatteryStatsService.getActiveStatistics().readLocked();
2308        mBatteryStatsService.scheduleWriteToDisk();
2309        mOnBattery = DEBUG_POWER ? true
2310                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2311        mBatteryStatsService.getActiveStatistics().setCallback(this);
2312
2313        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2314
2315        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2316
2317        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2318
2319        // User 0 is the first and only user that runs at boot.
2320        mStartedUsers.put(UserHandle.USER_OWNER, new UserState(UserHandle.OWNER, true));
2321        mUserLru.add(UserHandle.USER_OWNER);
2322        updateStartedUserArrayLocked();
2323
2324        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2325            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2326
2327        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2328
2329        mConfiguration.setToDefaults();
2330        mConfiguration.setLocale(Locale.getDefault());
2331
2332        mConfigurationSeq = mConfiguration.seq = 1;
2333        mProcessCpuTracker.init();
2334
2335        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2336        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2337        mRecentTasks = new RecentTasks(this);
2338        mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
2339        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
2340
2341        mProcessCpuThread = new Thread("CpuTracker") {
2342            @Override
2343            public void run() {
2344                while (true) {
2345                    try {
2346                        try {
2347                            synchronized(this) {
2348                                final long now = SystemClock.uptimeMillis();
2349                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2350                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2351                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2352                                //        + ", write delay=" + nextWriteDelay);
2353                                if (nextWriteDelay < nextCpuDelay) {
2354                                    nextCpuDelay = nextWriteDelay;
2355                                }
2356                                if (nextCpuDelay > 0) {
2357                                    mProcessCpuMutexFree.set(true);
2358                                    this.wait(nextCpuDelay);
2359                                }
2360                            }
2361                        } catch (InterruptedException e) {
2362                        }
2363                        updateCpuStatsNow();
2364                    } catch (Exception e) {
2365                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2366                    }
2367                }
2368            }
2369        };
2370
2371        Watchdog.getInstance().addMonitor(this);
2372        Watchdog.getInstance().addThread(mHandler);
2373    }
2374
2375    public void setSystemServiceManager(SystemServiceManager mgr) {
2376        mSystemServiceManager = mgr;
2377    }
2378
2379    public void setInstaller(Installer installer) {
2380        mInstaller = installer;
2381    }
2382
2383    private void start() {
2384        Process.removeAllProcessGroups();
2385        mProcessCpuThread.start();
2386
2387        mBatteryStatsService.publish(mContext);
2388        mAppOpsService.publish(mContext);
2389        Slog.d("AppOps", "AppOpsService published");
2390        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2391    }
2392
2393    public void initPowerManagement() {
2394        mStackSupervisor.initPowerManagement();
2395        mBatteryStatsService.initPowerManagement();
2396        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2397        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2398        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2399        mVoiceWakeLock.setReferenceCounted(false);
2400    }
2401
2402    @Override
2403    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2404            throws RemoteException {
2405        if (code == SYSPROPS_TRANSACTION) {
2406            // We need to tell all apps about the system property change.
2407            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2408            synchronized(this) {
2409                final int NP = mProcessNames.getMap().size();
2410                for (int ip=0; ip<NP; ip++) {
2411                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2412                    final int NA = apps.size();
2413                    for (int ia=0; ia<NA; ia++) {
2414                        ProcessRecord app = apps.valueAt(ia);
2415                        if (app.thread != null) {
2416                            procs.add(app.thread.asBinder());
2417                        }
2418                    }
2419                }
2420            }
2421
2422            int N = procs.size();
2423            for (int i=0; i<N; i++) {
2424                Parcel data2 = Parcel.obtain();
2425                try {
2426                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2427                } catch (RemoteException e) {
2428                }
2429                data2.recycle();
2430            }
2431        }
2432        try {
2433            return super.onTransact(code, data, reply, flags);
2434        } catch (RuntimeException e) {
2435            // The activity manager only throws security exceptions, so let's
2436            // log all others.
2437            if (!(e instanceof SecurityException)) {
2438                Slog.wtf(TAG, "Activity Manager Crash", e);
2439            }
2440            throw e;
2441        }
2442    }
2443
2444    void updateCpuStats() {
2445        final long now = SystemClock.uptimeMillis();
2446        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2447            return;
2448        }
2449        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2450            synchronized (mProcessCpuThread) {
2451                mProcessCpuThread.notify();
2452            }
2453        }
2454    }
2455
2456    void updateCpuStatsNow() {
2457        synchronized (mProcessCpuTracker) {
2458            mProcessCpuMutexFree.set(false);
2459            final long now = SystemClock.uptimeMillis();
2460            boolean haveNewCpuStats = false;
2461
2462            if (MONITOR_CPU_USAGE &&
2463                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2464                mLastCpuTime.set(now);
2465                mProcessCpuTracker.update();
2466                if (mProcessCpuTracker.hasGoodLastStats()) {
2467                    haveNewCpuStats = true;
2468                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2469                    //Slog.i(TAG, "Total CPU usage: "
2470                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2471
2472                    // Slog the cpu usage if the property is set.
2473                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2474                        int user = mProcessCpuTracker.getLastUserTime();
2475                        int system = mProcessCpuTracker.getLastSystemTime();
2476                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2477                        int irq = mProcessCpuTracker.getLastIrqTime();
2478                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2479                        int idle = mProcessCpuTracker.getLastIdleTime();
2480
2481                        int total = user + system + iowait + irq + softIrq + idle;
2482                        if (total == 0) total = 1;
2483
2484                        EventLog.writeEvent(EventLogTags.CPU,
2485                                ((user+system+iowait+irq+softIrq) * 100) / total,
2486                                (user * 100) / total,
2487                                (system * 100) / total,
2488                                (iowait * 100) / total,
2489                                (irq * 100) / total,
2490                                (softIrq * 100) / total);
2491                    }
2492                }
2493            }
2494
2495            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2496            synchronized(bstats) {
2497                synchronized(mPidsSelfLocked) {
2498                    if (haveNewCpuStats) {
2499                        if (bstats.startAddingCpuLocked()) {
2500                            int totalUTime = 0;
2501                            int totalSTime = 0;
2502                            final int N = mProcessCpuTracker.countStats();
2503                            for (int i=0; i<N; i++) {
2504                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2505                                if (!st.working) {
2506                                    continue;
2507                                }
2508                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2509                                totalUTime += st.rel_utime;
2510                                totalSTime += st.rel_stime;
2511                                if (pr != null) {
2512                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2513                                    if (ps == null || !ps.isActive()) {
2514                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2515                                                pr.info.uid, pr.processName);
2516                                    }
2517                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2518                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2519                                } else {
2520                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2521                                    if (ps == null || !ps.isActive()) {
2522                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2523                                                bstats.mapUid(st.uid), st.name);
2524                                    }
2525                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2526                                }
2527                            }
2528                            final int userTime = mProcessCpuTracker.getLastUserTime();
2529                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2530                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2531                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2532                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2533                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2534                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2535                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2536                        }
2537                    }
2538                }
2539
2540                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2541                    mLastWriteTime = now;
2542                    mBatteryStatsService.scheduleWriteToDisk();
2543                }
2544            }
2545        }
2546    }
2547
2548    @Override
2549    public void batteryNeedsCpuUpdate() {
2550        updateCpuStatsNow();
2551    }
2552
2553    @Override
2554    public void batteryPowerChanged(boolean onBattery) {
2555        // When plugging in, update the CPU stats first before changing
2556        // the plug state.
2557        updateCpuStatsNow();
2558        synchronized (this) {
2559            synchronized(mPidsSelfLocked) {
2560                mOnBattery = DEBUG_POWER ? true : onBattery;
2561            }
2562        }
2563    }
2564
2565    @Override
2566    public void batterySendBroadcast(Intent intent) {
2567        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2568                AppOpsManager.OP_NONE, null, false, false,
2569                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2570    }
2571
2572    /**
2573     * Initialize the application bind args. These are passed to each
2574     * process when the bindApplication() IPC is sent to the process. They're
2575     * lazily setup to make sure the services are running when they're asked for.
2576     */
2577    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2578        if (mAppBindArgs == null) {
2579            mAppBindArgs = new HashMap<>();
2580
2581            // Isolated processes won't get this optimization, so that we don't
2582            // violate the rules about which services they have access to.
2583            if (!isolated) {
2584                // Setup the application init args
2585                mAppBindArgs.put("package", ServiceManager.getService("package"));
2586                mAppBindArgs.put("window", ServiceManager.getService("window"));
2587                mAppBindArgs.put(Context.ALARM_SERVICE,
2588                        ServiceManager.getService(Context.ALARM_SERVICE));
2589            }
2590        }
2591        return mAppBindArgs;
2592    }
2593
2594    final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2595        if (r != null && mFocusedActivity != r) {
2596            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2597            ActivityRecord last = mFocusedActivity;
2598            mFocusedActivity = r;
2599            if (r.task.taskType != ActivityRecord.HOME_ACTIVITY_TYPE
2600                    && r.task.taskType != ActivityRecord.RECENTS_ACTIVITY_TYPE) {
2601                if (mCurAppTimeTracker != r.appTimeTracker) {
2602                    // We are switching app tracking.  Complete the current one.
2603                    if (mCurAppTimeTracker != null) {
2604                        mCurAppTimeTracker.stop();
2605                        mHandler.obtainMessage(REPORT_TIME_TRACKER_MSG,
2606                                mCurAppTimeTracker).sendToTarget();
2607                        mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2608                        mCurAppTimeTracker = null;
2609                    }
2610                    if (r.appTimeTracker != null) {
2611                        mCurAppTimeTracker = r.appTimeTracker;
2612                        startTimeTrackingFocusedActivityLocked();
2613                    }
2614                } else {
2615                    startTimeTrackingFocusedActivityLocked();
2616                }
2617            } else {
2618                r.appTimeTracker = null;
2619            }
2620            if (r.task != null && r.task.voiceInteractor != null) {
2621                startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2622            } else {
2623                finishRunningVoiceLocked();
2624                if (last != null && last.task.voiceSession != null) {
2625                    // We had been in a voice interaction session, but now focused has
2626                    // move to something different.  Just finish the session, we can't
2627                    // return to it and retain the proper state and synchronization with
2628                    // the voice interaction service.
2629                    finishVoiceTask(last.task.voiceSession);
2630                }
2631            }
2632            if (mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
2633                mWindowManager.setFocusedApp(r.appToken, true);
2634            }
2635            applyUpdateLockStateLocked(r);
2636            if (mFocusedActivity.userId != mLastFocusedUserId) {
2637                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2638                mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2639                        mFocusedActivity.userId, 0));
2640                mLastFocusedUserId = mFocusedActivity.userId;
2641            }
2642        }
2643        EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY,
2644                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2645                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2646    }
2647
2648    final void clearFocusedActivity(ActivityRecord r) {
2649        if (mFocusedActivity == r) {
2650            ActivityStack stack = mStackSupervisor.getFocusedStack();
2651            if (stack != null) {
2652                ActivityRecord top = stack.topActivity();
2653                if (top != null && top.userId != mLastFocusedUserId) {
2654                    mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2655                    mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2656                                    top.userId, 0));
2657                    mLastFocusedUserId = top.userId;
2658                }
2659            }
2660            mFocusedActivity = null;
2661            EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, -1, "NULL");
2662        }
2663    }
2664
2665    @Override
2666    public void setFocusedStack(int stackId) {
2667        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2668        synchronized (ActivityManagerService.this) {
2669            ActivityStack stack = mStackSupervisor.getStack(stackId);
2670            if (stack != null) {
2671                ActivityRecord r = stack.topRunningActivityLocked(null);
2672                if (r != null) {
2673                    setFocusedActivityLocked(r, "setFocusedStack");
2674                    mStackSupervisor.resumeTopActivitiesLocked(stack, null, null);
2675                }
2676            }
2677        }
2678    }
2679
2680    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2681    @Override
2682    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2683        synchronized (ActivityManagerService.this) {
2684            if (listener != null) {
2685                mTaskStackListeners.register(listener);
2686            }
2687        }
2688    }
2689
2690    @Override
2691    public void notifyActivityDrawn(IBinder token) {
2692        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2693        synchronized (this) {
2694            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2695            if (r != null) {
2696                r.task.stack.notifyActivityDrawnLocked(r);
2697            }
2698        }
2699    }
2700
2701    final void applyUpdateLockStateLocked(ActivityRecord r) {
2702        // Modifications to the UpdateLock state are done on our handler, outside
2703        // the activity manager's locks.  The new state is determined based on the
2704        // state *now* of the relevant activity record.  The object is passed to
2705        // the handler solely for logging detail, not to be consulted/modified.
2706        final boolean nextState = r != null && r.immersive;
2707        mHandler.sendMessage(
2708                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2709    }
2710
2711    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2712        Message msg = Message.obtain();
2713        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2714        msg.obj = r.task.askedCompatMode ? null : r;
2715        mUiHandler.sendMessage(msg);
2716    }
2717
2718    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2719            String what, Object obj, ProcessRecord srcApp) {
2720        app.lastActivityTime = now;
2721
2722        if (app.activities.size() > 0) {
2723            // Don't want to touch dependent processes that are hosting activities.
2724            return index;
2725        }
2726
2727        int lrui = mLruProcesses.lastIndexOf(app);
2728        if (lrui < 0) {
2729            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2730                    + what + " " + obj + " from " + srcApp);
2731            return index;
2732        }
2733
2734        if (lrui >= index) {
2735            // Don't want to cause this to move dependent processes *back* in the
2736            // list as if they were less frequently used.
2737            return index;
2738        }
2739
2740        if (lrui >= mLruProcessActivityStart) {
2741            // Don't want to touch dependent processes that are hosting activities.
2742            return index;
2743        }
2744
2745        mLruProcesses.remove(lrui);
2746        if (index > 0) {
2747            index--;
2748        }
2749        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2750                + " in LRU list: " + app);
2751        mLruProcesses.add(index, app);
2752        return index;
2753    }
2754
2755    private static void killProcessGroup(int uid, int pid) {
2756        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
2757        Process.killProcessGroup(uid, pid);
2758        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2759    }
2760
2761    final void removeLruProcessLocked(ProcessRecord app) {
2762        int lrui = mLruProcesses.lastIndexOf(app);
2763        if (lrui >= 0) {
2764            if (!app.killed) {
2765                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2766                Process.killProcessQuiet(app.pid);
2767                killProcessGroup(app.info.uid, app.pid);
2768            }
2769            if (lrui <= mLruProcessActivityStart) {
2770                mLruProcessActivityStart--;
2771            }
2772            if (lrui <= mLruProcessServiceStart) {
2773                mLruProcessServiceStart--;
2774            }
2775            mLruProcesses.remove(lrui);
2776        }
2777    }
2778
2779    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2780            ProcessRecord client) {
2781        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2782                || app.treatLikeActivity;
2783        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2784        if (!activityChange && hasActivity) {
2785            // The process has activities, so we are only allowing activity-based adjustments
2786            // to move it.  It should be kept in the front of the list with other
2787            // processes that have activities, and we don't want those to change their
2788            // order except due to activity operations.
2789            return;
2790        }
2791
2792        mLruSeq++;
2793        final long now = SystemClock.uptimeMillis();
2794        app.lastActivityTime = now;
2795
2796        // First a quick reject: if the app is already at the position we will
2797        // put it, then there is nothing to do.
2798        if (hasActivity) {
2799            final int N = mLruProcesses.size();
2800            if (N > 0 && mLruProcesses.get(N-1) == app) {
2801                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
2802                return;
2803            }
2804        } else {
2805            if (mLruProcessServiceStart > 0
2806                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2807                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
2808                return;
2809            }
2810        }
2811
2812        int lrui = mLruProcesses.lastIndexOf(app);
2813
2814        if (app.persistent && lrui >= 0) {
2815            // We don't care about the position of persistent processes, as long as
2816            // they are in the list.
2817            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
2818            return;
2819        }
2820
2821        /* In progress: compute new position first, so we can avoid doing work
2822           if the process is not actually going to move.  Not yet working.
2823        int addIndex;
2824        int nextIndex;
2825        boolean inActivity = false, inService = false;
2826        if (hasActivity) {
2827            // Process has activities, put it at the very tipsy-top.
2828            addIndex = mLruProcesses.size();
2829            nextIndex = mLruProcessServiceStart;
2830            inActivity = true;
2831        } else if (hasService) {
2832            // Process has services, put it at the top of the service list.
2833            addIndex = mLruProcessActivityStart;
2834            nextIndex = mLruProcessServiceStart;
2835            inActivity = true;
2836            inService = true;
2837        } else  {
2838            // Process not otherwise of interest, it goes to the top of the non-service area.
2839            addIndex = mLruProcessServiceStart;
2840            if (client != null) {
2841                int clientIndex = mLruProcesses.lastIndexOf(client);
2842                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2843                        + app);
2844                if (clientIndex >= 0 && addIndex > clientIndex) {
2845                    addIndex = clientIndex;
2846                }
2847            }
2848            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2849        }
2850
2851        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2852                + mLruProcessActivityStart + "): " + app);
2853        */
2854
2855        if (lrui >= 0) {
2856            if (lrui < mLruProcessActivityStart) {
2857                mLruProcessActivityStart--;
2858            }
2859            if (lrui < mLruProcessServiceStart) {
2860                mLruProcessServiceStart--;
2861            }
2862            /*
2863            if (addIndex > lrui) {
2864                addIndex--;
2865            }
2866            if (nextIndex > lrui) {
2867                nextIndex--;
2868            }
2869            */
2870            mLruProcesses.remove(lrui);
2871        }
2872
2873        /*
2874        mLruProcesses.add(addIndex, app);
2875        if (inActivity) {
2876            mLruProcessActivityStart++;
2877        }
2878        if (inService) {
2879            mLruProcessActivityStart++;
2880        }
2881        */
2882
2883        int nextIndex;
2884        if (hasActivity) {
2885            final int N = mLruProcesses.size();
2886            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
2887                // Process doesn't have activities, but has clients with
2888                // activities...  move it up, but one below the top (the top
2889                // should always have a real activity).
2890                if (DEBUG_LRU) Slog.d(TAG_LRU,
2891                        "Adding to second-top of LRU activity list: " + app);
2892                mLruProcesses.add(N - 1, app);
2893                // To keep it from spamming the LRU list (by making a bunch of clients),
2894                // we will push down any other entries owned by the app.
2895                final int uid = app.info.uid;
2896                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
2897                    ProcessRecord subProc = mLruProcesses.get(i);
2898                    if (subProc.info.uid == uid) {
2899                        // We want to push this one down the list.  If the process after
2900                        // it is for the same uid, however, don't do so, because we don't
2901                        // want them internally to be re-ordered.
2902                        if (mLruProcesses.get(i - 1).info.uid != uid) {
2903                            if (DEBUG_LRU) Slog.d(TAG_LRU,
2904                                    "Pushing uid " + uid + " swapping at " + i + ": "
2905                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
2906                            ProcessRecord tmp = mLruProcesses.get(i);
2907                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
2908                            mLruProcesses.set(i - 1, tmp);
2909                            i--;
2910                        }
2911                    } else {
2912                        // A gap, we can stop here.
2913                        break;
2914                    }
2915                }
2916            } else {
2917                // Process has activities, put it at the very tipsy-top.
2918                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
2919                mLruProcesses.add(app);
2920            }
2921            nextIndex = mLruProcessServiceStart;
2922        } else if (hasService) {
2923            // Process has services, put it at the top of the service list.
2924            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
2925            mLruProcesses.add(mLruProcessActivityStart, app);
2926            nextIndex = mLruProcessServiceStart;
2927            mLruProcessActivityStart++;
2928        } else  {
2929            // Process not otherwise of interest, it goes to the top of the non-service area.
2930            int index = mLruProcessServiceStart;
2931            if (client != null) {
2932                // If there is a client, don't allow the process to be moved up higher
2933                // in the list than that client.
2934                int clientIndex = mLruProcesses.lastIndexOf(client);
2935                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
2936                        + " when updating " + app);
2937                if (clientIndex <= lrui) {
2938                    // Don't allow the client index restriction to push it down farther in the
2939                    // list than it already is.
2940                    clientIndex = lrui;
2941                }
2942                if (clientIndex >= 0 && index > clientIndex) {
2943                    index = clientIndex;
2944                }
2945            }
2946            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
2947            mLruProcesses.add(index, app);
2948            nextIndex = index-1;
2949            mLruProcessActivityStart++;
2950            mLruProcessServiceStart++;
2951        }
2952
2953        // If the app is currently using a content provider or service,
2954        // bump those processes as well.
2955        for (int j=app.connections.size()-1; j>=0; j--) {
2956            ConnectionRecord cr = app.connections.valueAt(j);
2957            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2958                    && cr.binding.service.app != null
2959                    && cr.binding.service.app.lruSeq != mLruSeq
2960                    && !cr.binding.service.app.persistent) {
2961                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2962                        "service connection", cr, app);
2963            }
2964        }
2965        for (int j=app.conProviders.size()-1; j>=0; j--) {
2966            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2967            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2968                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2969                        "provider reference", cpr, app);
2970            }
2971        }
2972    }
2973
2974    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2975        if (uid == Process.SYSTEM_UID) {
2976            // The system gets to run in any process.  If there are multiple
2977            // processes with the same uid, just pick the first (this
2978            // should never happen).
2979            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2980            if (procs == null) return null;
2981            final int procCount = procs.size();
2982            for (int i = 0; i < procCount; i++) {
2983                final int procUid = procs.keyAt(i);
2984                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
2985                    // Don't use an app process or different user process for system component.
2986                    continue;
2987                }
2988                return procs.valueAt(i);
2989            }
2990        }
2991        ProcessRecord proc = mProcessNames.get(processName, uid);
2992        if (false && proc != null && !keepIfLarge
2993                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2994                && proc.lastCachedPss >= 4000) {
2995            // Turn this condition on to cause killing to happen regularly, for testing.
2996            if (proc.baseProcessTracker != null) {
2997                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2998            }
2999            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3000        } else if (proc != null && !keepIfLarge
3001                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3002                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3003            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3004            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3005                if (proc.baseProcessTracker != null) {
3006                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3007                }
3008                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3009            }
3010        }
3011        return proc;
3012    }
3013
3014    void ensurePackageDexOpt(String packageName) {
3015        IPackageManager pm = AppGlobals.getPackageManager();
3016        try {
3017            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
3018                mDidDexOpt = true;
3019            }
3020        } catch (RemoteException e) {
3021        }
3022    }
3023
3024    boolean isNextTransitionForward() {
3025        int transit = mWindowManager.getPendingAppTransition();
3026        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
3027                || transit == AppTransition.TRANSIT_TASK_OPEN
3028                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
3029    }
3030
3031    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3032            String processName, String abiOverride, int uid, Runnable crashHandler) {
3033        synchronized(this) {
3034            ApplicationInfo info = new ApplicationInfo();
3035            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3036            // For isolated processes, the former contains the parent's uid and the latter the
3037            // actual uid of the isolated process.
3038            // In the special case introduced by this method (which is, starting an isolated
3039            // process directly from the SystemServer without an actual parent app process) the
3040            // closest thing to a parent's uid is SYSTEM_UID.
3041            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3042            // the |isolated| logic in the ProcessRecord constructor.
3043            info.uid = Process.SYSTEM_UID;
3044            info.processName = processName;
3045            info.className = entryPoint;
3046            info.packageName = "android";
3047            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3048                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3049                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3050                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3051                    crashHandler);
3052            return proc != null ? proc.pid : 0;
3053        }
3054    }
3055
3056    final ProcessRecord startProcessLocked(String processName,
3057            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3058            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3059            boolean isolated, boolean keepIfLarge) {
3060        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3061                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3062                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3063                null /* crashHandler */);
3064    }
3065
3066    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3067            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3068            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3069            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3070        long startTime = SystemClock.elapsedRealtime();
3071        ProcessRecord app;
3072        if (!isolated) {
3073            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3074            checkTime(startTime, "startProcess: after getProcessRecord");
3075
3076            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3077                // If we are in the background, then check to see if this process
3078                // is bad.  If so, we will just silently fail.
3079                if (mBadProcesses.get(info.processName, info.uid) != null) {
3080                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3081                            + "/" + info.processName);
3082                    return null;
3083                }
3084            } else {
3085                // When the user is explicitly starting a process, then clear its
3086                // crash count so that we won't make it bad until they see at
3087                // least one crash dialog again, and make the process good again
3088                // if it had been bad.
3089                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3090                        + "/" + info.processName);
3091                mProcessCrashTimes.remove(info.processName, info.uid);
3092                if (mBadProcesses.get(info.processName, info.uid) != null) {
3093                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3094                            UserHandle.getUserId(info.uid), info.uid,
3095                            info.processName);
3096                    mBadProcesses.remove(info.processName, info.uid);
3097                    if (app != null) {
3098                        app.bad = false;
3099                    }
3100                }
3101            }
3102        } else {
3103            // If this is an isolated process, it can't re-use an existing process.
3104            app = null;
3105        }
3106
3107        // We don't have to do anything more if:
3108        // (1) There is an existing application record; and
3109        // (2) The caller doesn't think it is dead, OR there is no thread
3110        //     object attached to it so we know it couldn't have crashed; and
3111        // (3) There is a pid assigned to it, so it is either starting or
3112        //     already running.
3113        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3114                + " app=" + app + " knownToBeDead=" + knownToBeDead
3115                + " thread=" + (app != null ? app.thread : null)
3116                + " pid=" + (app != null ? app.pid : -1));
3117        if (app != null && app.pid > 0) {
3118            if (!knownToBeDead || app.thread == null) {
3119                // We already have the app running, or are waiting for it to
3120                // come up (we have a pid but not yet its thread), so keep it.
3121                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3122                // If this is a new package in the process, add the package to the list
3123                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3124                checkTime(startTime, "startProcess: done, added package to proc");
3125                return app;
3126            }
3127
3128            // An application record is attached to a previous process,
3129            // clean it up now.
3130            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3131            checkTime(startTime, "startProcess: bad proc running, killing");
3132            killProcessGroup(app.info.uid, app.pid);
3133            handleAppDiedLocked(app, true, true);
3134            checkTime(startTime, "startProcess: done killing old proc");
3135        }
3136
3137        String hostingNameStr = hostingName != null
3138                ? hostingName.flattenToShortString() : null;
3139
3140        if (app == null) {
3141            checkTime(startTime, "startProcess: creating new process record");
3142            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3143            if (app == null) {
3144                Slog.w(TAG, "Failed making new process record for "
3145                        + processName + "/" + info.uid + " isolated=" + isolated);
3146                return null;
3147            }
3148            app.crashHandler = crashHandler;
3149            checkTime(startTime, "startProcess: done creating new process record");
3150        } else {
3151            // If this is a new package in the process, add the package to the list
3152            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3153            checkTime(startTime, "startProcess: added package to existing proc");
3154        }
3155
3156        // If the system is not ready yet, then hold off on starting this
3157        // process until it is.
3158        if (!mProcessesReady
3159                && !isAllowedWhileBooting(info)
3160                && !allowWhileBooting) {
3161            if (!mProcessesOnHold.contains(app)) {
3162                mProcessesOnHold.add(app);
3163            }
3164            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3165                    "System not ready, putting on hold: " + app);
3166            checkTime(startTime, "startProcess: returning with proc on hold");
3167            return app;
3168        }
3169
3170        checkTime(startTime, "startProcess: stepping in to startProcess");
3171        startProcessLocked(
3172                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3173        checkTime(startTime, "startProcess: done starting proc!");
3174        return (app.pid != 0) ? app : null;
3175    }
3176
3177    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3178        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3179    }
3180
3181    private final void startProcessLocked(ProcessRecord app,
3182            String hostingType, String hostingNameStr) {
3183        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3184                null /* entryPoint */, null /* entryPointArgs */);
3185    }
3186
3187    private final void startProcessLocked(ProcessRecord app, String hostingType,
3188            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3189        long startTime = SystemClock.elapsedRealtime();
3190        if (app.pid > 0 && app.pid != MY_PID) {
3191            checkTime(startTime, "startProcess: removing from pids map");
3192            synchronized (mPidsSelfLocked) {
3193                mPidsSelfLocked.remove(app.pid);
3194                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3195            }
3196            checkTime(startTime, "startProcess: done removing from pids map");
3197            app.setPid(0);
3198        }
3199
3200        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3201                "startProcessLocked removing on hold: " + app);
3202        mProcessesOnHold.remove(app);
3203
3204        checkTime(startTime, "startProcess: starting to update cpu stats");
3205        updateCpuStats();
3206        checkTime(startTime, "startProcess: done updating cpu stats");
3207
3208        try {
3209            try {
3210                if (AppGlobals.getPackageManager().isPackageFrozen(app.info.packageName)) {
3211                    // This is caught below as if we had failed to fork zygote
3212                    throw new RuntimeException("Package " + app.info.packageName + " is frozen!");
3213                }
3214            } catch (RemoteException e) {
3215                throw e.rethrowAsRuntimeException();
3216            }
3217
3218            int uid = app.uid;
3219            int[] gids = null;
3220            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3221            if (!app.isolated) {
3222                int[] permGids = null;
3223                try {
3224                    checkTime(startTime, "startProcess: getting gids from package manager");
3225                    final IPackageManager pm = AppGlobals.getPackageManager();
3226                    permGids = pm.getPackageGids(app.info.packageName, app.userId);
3227                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3228                            MountServiceInternal.class);
3229                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3230                            app.info.packageName);
3231                } catch (RemoteException e) {
3232                    throw e.rethrowAsRuntimeException();
3233                }
3234
3235                /*
3236                 * Add shared application and profile GIDs so applications can share some
3237                 * resources like shared libraries and access user-wide resources
3238                 */
3239                if (ArrayUtils.isEmpty(permGids)) {
3240                    gids = new int[2];
3241                } else {
3242                    gids = new int[permGids.length + 2];
3243                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3244                }
3245                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3246                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3247            }
3248            checkTime(startTime, "startProcess: building args");
3249            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3250                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3251                        && mTopComponent != null
3252                        && app.processName.equals(mTopComponent.getPackageName())) {
3253                    uid = 0;
3254                }
3255                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3256                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3257                    uid = 0;
3258                }
3259            }
3260            int debugFlags = 0;
3261            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3262                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3263                // Also turn on CheckJNI for debuggable apps. It's quite
3264                // awkward to turn on otherwise.
3265                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3266            }
3267            // Run the app in safe mode if its manifest requests so or the
3268            // system is booted in safe mode.
3269            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3270                mSafeMode == true) {
3271                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3272            }
3273            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3274                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3275            }
3276            String jitDebugProperty = SystemProperties.get("debug.usejit");
3277            if ("true".equals(jitDebugProperty)) {
3278                debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3279            } else if (!"false".equals(jitDebugProperty)) {
3280                // If we didn't force disable by setting false, defer to the dalvik vm options.
3281                if ("true".equals(SystemProperties.get("dalvik.vm.usejit"))) {
3282                    debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3283                }
3284            }
3285            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3286            if ("true".equals(genDebugInfoProperty)) {
3287                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3288            }
3289            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3290                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3291            }
3292            if ("1".equals(SystemProperties.get("debug.assert"))) {
3293                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3294            }
3295
3296            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3297            if (requiredAbi == null) {
3298                requiredAbi = Build.SUPPORTED_ABIS[0];
3299            }
3300
3301            String instructionSet = null;
3302            if (app.info.primaryCpuAbi != null) {
3303                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3304            }
3305
3306            app.gids = gids;
3307            app.requiredAbi = requiredAbi;
3308            app.instructionSet = instructionSet;
3309
3310            // Start the process.  It will either succeed and return a result containing
3311            // the PID of the new process, or else throw a RuntimeException.
3312            boolean isActivityProcess = (entryPoint == null);
3313            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3314            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3315                    app.processName);
3316            checkTime(startTime, "startProcess: asking zygote to start proc");
3317            Process.ProcessStartResult startResult = Process.start(entryPoint,
3318                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3319                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3320                    app.info.dataDir, entryPointArgs);
3321            checkTime(startTime, "startProcess: returned from zygote!");
3322            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3323
3324            if (app.isolated) {
3325                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3326            }
3327            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3328            checkTime(startTime, "startProcess: done updating battery stats");
3329
3330            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3331                    UserHandle.getUserId(uid), startResult.pid, uid,
3332                    app.processName, hostingType,
3333                    hostingNameStr != null ? hostingNameStr : "");
3334
3335            if (app.persistent) {
3336                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3337            }
3338
3339            checkTime(startTime, "startProcess: building log message");
3340            StringBuilder buf = mStringBuilder;
3341            buf.setLength(0);
3342            buf.append("Start proc ");
3343            buf.append(startResult.pid);
3344            buf.append(':');
3345            buf.append(app.processName);
3346            buf.append('/');
3347            UserHandle.formatUid(buf, uid);
3348            if (!isActivityProcess) {
3349                buf.append(" [");
3350                buf.append(entryPoint);
3351                buf.append("]");
3352            }
3353            buf.append(" for ");
3354            buf.append(hostingType);
3355            if (hostingNameStr != null) {
3356                buf.append(" ");
3357                buf.append(hostingNameStr);
3358            }
3359            Slog.i(TAG, buf.toString());
3360            app.setPid(startResult.pid);
3361            app.usingWrapper = startResult.usingWrapper;
3362            app.removed = false;
3363            app.killed = false;
3364            app.killedByAm = false;
3365            checkTime(startTime, "startProcess: starting to update pids map");
3366            synchronized (mPidsSelfLocked) {
3367                this.mPidsSelfLocked.put(startResult.pid, app);
3368                if (isActivityProcess) {
3369                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3370                    msg.obj = app;
3371                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3372                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3373                }
3374            }
3375            checkTime(startTime, "startProcess: done updating pids map");
3376        } catch (RuntimeException e) {
3377            // XXX do better error recovery.
3378            app.setPid(0);
3379            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3380            if (app.isolated) {
3381                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3382            }
3383            Slog.e(TAG, "Failure starting process " + app.processName, e);
3384        }
3385    }
3386
3387    void updateUsageStats(ActivityRecord component, boolean resumed) {
3388        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3389                "updateUsageStats: comp=" + component + "res=" + resumed);
3390        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3391        if (resumed) {
3392            if (mUsageStatsService != null) {
3393                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3394                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3395            }
3396            synchronized (stats) {
3397                stats.noteActivityResumedLocked(component.app.uid);
3398            }
3399        } else {
3400            if (mUsageStatsService != null) {
3401                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3402                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3403            }
3404            synchronized (stats) {
3405                stats.noteActivityPausedLocked(component.app.uid);
3406            }
3407        }
3408    }
3409
3410    Intent getHomeIntent() {
3411        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3412        intent.setComponent(mTopComponent);
3413        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3414            intent.addCategory(Intent.CATEGORY_HOME);
3415        }
3416        return intent;
3417    }
3418
3419    boolean startHomeActivityLocked(int userId, String reason) {
3420        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3421                && mTopAction == null) {
3422            // We are running in factory test mode, but unable to find
3423            // the factory test app, so just sit around displaying the
3424            // error message and don't try to start anything.
3425            return false;
3426        }
3427        Intent intent = getHomeIntent();
3428        ActivityInfo aInfo =
3429            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3430        if (aInfo != null) {
3431            intent.setComponent(new ComponentName(
3432                    aInfo.applicationInfo.packageName, aInfo.name));
3433            // Don't do this if the home app is currently being
3434            // instrumented.
3435            aInfo = new ActivityInfo(aInfo);
3436            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3437            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3438                    aInfo.applicationInfo.uid, true);
3439            if (app == null || app.instrumentationClass == null) {
3440                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3441                mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3442            }
3443        }
3444
3445        return true;
3446    }
3447
3448    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3449        ActivityInfo ai = null;
3450        ComponentName comp = intent.getComponent();
3451        try {
3452            if (comp != null) {
3453                // Factory test.
3454                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3455            } else {
3456                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3457                        intent,
3458                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3459                        flags, userId);
3460
3461                if (info != null) {
3462                    ai = info.activityInfo;
3463                }
3464            }
3465        } catch (RemoteException e) {
3466            // ignore
3467        }
3468
3469        return ai;
3470    }
3471
3472    /**
3473     * Starts the "new version setup screen" if appropriate.
3474     */
3475    void startSetupActivityLocked() {
3476        // Only do this once per boot.
3477        if (mCheckedForSetup) {
3478            return;
3479        }
3480
3481        // We will show this screen if the current one is a different
3482        // version than the last one shown, and we are not running in
3483        // low-level factory test mode.
3484        final ContentResolver resolver = mContext.getContentResolver();
3485        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3486                Settings.Global.getInt(resolver,
3487                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3488            mCheckedForSetup = true;
3489
3490            // See if we should be showing the platform update setup UI.
3491            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3492            List<ResolveInfo> ris = mContext.getPackageManager()
3493                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3494
3495            // We don't allow third party apps to replace this.
3496            ResolveInfo ri = null;
3497            for (int i=0; ris != null && i<ris.size(); i++) {
3498                if ((ris.get(i).activityInfo.applicationInfo.flags
3499                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3500                    ri = ris.get(i);
3501                    break;
3502                }
3503            }
3504
3505            if (ri != null) {
3506                String vers = ri.activityInfo.metaData != null
3507                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3508                        : null;
3509                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3510                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3511                            Intent.METADATA_SETUP_VERSION);
3512                }
3513                String lastVers = Settings.Secure.getString(
3514                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3515                if (vers != null && !vers.equals(lastVers)) {
3516                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3517                    intent.setComponent(new ComponentName(
3518                            ri.activityInfo.packageName, ri.activityInfo.name));
3519                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3520                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3521                            null);
3522                }
3523            }
3524        }
3525    }
3526
3527    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3528        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3529    }
3530
3531    void enforceNotIsolatedCaller(String caller) {
3532        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3533            throw new SecurityException("Isolated process not allowed to call " + caller);
3534        }
3535    }
3536
3537    void enforceShellRestriction(String restriction, int userHandle) {
3538        if (Binder.getCallingUid() == Process.SHELL_UID) {
3539            if (userHandle < 0
3540                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3541                throw new SecurityException("Shell does not have permission to access user "
3542                        + userHandle);
3543            }
3544        }
3545    }
3546
3547    @Override
3548    public int getFrontActivityScreenCompatMode() {
3549        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3550        synchronized (this) {
3551            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3552        }
3553    }
3554
3555    @Override
3556    public void setFrontActivityScreenCompatMode(int mode) {
3557        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3558                "setFrontActivityScreenCompatMode");
3559        synchronized (this) {
3560            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3561        }
3562    }
3563
3564    @Override
3565    public int getPackageScreenCompatMode(String packageName) {
3566        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3567        synchronized (this) {
3568            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3569        }
3570    }
3571
3572    @Override
3573    public void setPackageScreenCompatMode(String packageName, int mode) {
3574        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3575                "setPackageScreenCompatMode");
3576        synchronized (this) {
3577            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3578        }
3579    }
3580
3581    @Override
3582    public boolean getPackageAskScreenCompat(String packageName) {
3583        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3584        synchronized (this) {
3585            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3586        }
3587    }
3588
3589    @Override
3590    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3591        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3592                "setPackageAskScreenCompat");
3593        synchronized (this) {
3594            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3595        }
3596    }
3597
3598    private boolean hasUsageStatsPermission(String callingPackage) {
3599        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3600                Binder.getCallingUid(), callingPackage);
3601        if (mode == AppOpsManager.MODE_DEFAULT) {
3602            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3603                    == PackageManager.PERMISSION_GRANTED;
3604        }
3605        return mode == AppOpsManager.MODE_ALLOWED;
3606    }
3607
3608    @Override
3609    public int getPackageProcessState(String packageName, String callingPackage) {
3610        if (!hasUsageStatsPermission(callingPackage)) {
3611            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3612                    "getPackageProcessState");
3613        }
3614
3615        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3616        synchronized (this) {
3617            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3618                final ProcessRecord proc = mLruProcesses.get(i);
3619                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3620                        || procState > proc.setProcState) {
3621                    boolean found = false;
3622                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3623                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3624                            procState = proc.setProcState;
3625                            found = true;
3626                        }
3627                    }
3628                    if (proc.pkgDeps != null && !found) {
3629                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3630                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3631                                procState = proc.setProcState;
3632                                break;
3633                            }
3634                        }
3635                    }
3636                }
3637            }
3638        }
3639        return procState;
3640    }
3641
3642    @Override
3643    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3644        synchronized (this) {
3645            final ProcessRecord app = getProcessRecordLocked(process, userId, true);
3646            if (app == null) {
3647                return false;
3648            }
3649            if (app.trimMemoryLevel < level && app.thread != null &&
3650                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3651                            app.trimMemoryLevel >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN)) {
3652                try {
3653                    app.thread.scheduleTrimMemory(level);
3654                    app.trimMemoryLevel = level;
3655                    return true;
3656                } catch (RemoteException e) {
3657                    // Fallthrough to failure case.
3658                }
3659            }
3660        }
3661        return false;
3662    }
3663
3664    private void dispatchProcessesChanged() {
3665        int N;
3666        synchronized (this) {
3667            N = mPendingProcessChanges.size();
3668            if (mActiveProcessChanges.length < N) {
3669                mActiveProcessChanges = new ProcessChangeItem[N];
3670            }
3671            mPendingProcessChanges.toArray(mActiveProcessChanges);
3672            mPendingProcessChanges.clear();
3673            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3674                    "*** Delivering " + N + " process changes");
3675        }
3676
3677        int i = mProcessObservers.beginBroadcast();
3678        while (i > 0) {
3679            i--;
3680            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3681            if (observer != null) {
3682                try {
3683                    for (int j=0; j<N; j++) {
3684                        ProcessChangeItem item = mActiveProcessChanges[j];
3685                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3686                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3687                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3688                                    + item.uid + ": " + item.foregroundActivities);
3689                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3690                                    item.foregroundActivities);
3691                        }
3692                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3693                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3694                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3695                                    + ": " + item.processState);
3696                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3697                        }
3698                    }
3699                } catch (RemoteException e) {
3700                }
3701            }
3702        }
3703        mProcessObservers.finishBroadcast();
3704
3705        synchronized (this) {
3706            for (int j=0; j<N; j++) {
3707                mAvailProcessChanges.add(mActiveProcessChanges[j]);
3708            }
3709        }
3710    }
3711
3712    private void dispatchProcessDied(int pid, int uid) {
3713        int i = mProcessObservers.beginBroadcast();
3714        while (i > 0) {
3715            i--;
3716            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3717            if (observer != null) {
3718                try {
3719                    observer.onProcessDied(pid, uid);
3720                } catch (RemoteException e) {
3721                }
3722            }
3723        }
3724        mProcessObservers.finishBroadcast();
3725    }
3726
3727    private void dispatchUidsChanged() {
3728        int N;
3729        synchronized (this) {
3730            N = mPendingUidChanges.size();
3731            if (mActiveUidChanges.length < N) {
3732                mActiveUidChanges = new UidRecord.ChangeItem[N];
3733            }
3734            for (int i=0; i<N; i++) {
3735                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3736                mActiveUidChanges[i] = change;
3737                change.uidRecord.pendingChange = null;
3738                change.uidRecord = null;
3739            }
3740            mPendingUidChanges.clear();
3741            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3742                    "*** Delivering " + N + " uid changes");
3743        }
3744
3745        if (mLocalPowerManager != null) {
3746            for (int j=0; j<N; j++) {
3747                UidRecord.ChangeItem item = mActiveUidChanges[j];
3748                if (item.gone) {
3749                    mLocalPowerManager.uidGone(item.uid);
3750                } else {
3751                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
3752                }
3753            }
3754        }
3755
3756        int i = mUidObservers.beginBroadcast();
3757        while (i > 0) {
3758            i--;
3759            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
3760            if (observer != null) {
3761                try {
3762                    for (int j=0; j<N; j++) {
3763                        UidRecord.ChangeItem item = mActiveUidChanges[j];
3764                        if (item.gone) {
3765                            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3766                                    "UID gone uid=" + item.uid);
3767                            observer.onUidGone(item.uid);
3768                        } else {
3769                            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3770                                    "UID CHANGED uid=" + item.uid
3771                                    + ": " + item.processState);
3772                            observer.onUidStateChanged(item.uid, item.processState);
3773                        }
3774                    }
3775                } catch (RemoteException e) {
3776                }
3777            }
3778        }
3779        mUidObservers.finishBroadcast();
3780
3781        synchronized (this) {
3782            for (int j=0; j<N; j++) {
3783                mAvailUidChanges.add(mActiveUidChanges[j]);
3784            }
3785        }
3786    }
3787
3788    @Override
3789    public final int startActivity(IApplicationThread caller, String callingPackage,
3790            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3791            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3792        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3793            resultWho, requestCode, startFlags, profilerInfo, options,
3794            UserHandle.getCallingUserId());
3795    }
3796
3797    @Override
3798    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3799            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3800            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3801        enforceNotIsolatedCaller("startActivity");
3802        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3803                false, ALLOW_FULL_ONLY, "startActivity", null);
3804        // TODO: Switch to user app stacks here.
3805        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3806                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3807                profilerInfo, null, null, options, userId, null, null);
3808    }
3809
3810    @Override
3811    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3812            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3813            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3814
3815        // This is very dangerous -- it allows you to perform a start activity (including
3816        // permission grants) as any app that may launch one of your own activities.  So
3817        // we will only allow this to be done from activities that are part of the core framework,
3818        // and then only when they are running as the system.
3819        final ActivityRecord sourceRecord;
3820        final int targetUid;
3821        final String targetPackage;
3822        synchronized (this) {
3823            if (resultTo == null) {
3824                throw new SecurityException("Must be called from an activity");
3825            }
3826            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3827            if (sourceRecord == null) {
3828                throw new SecurityException("Called with bad activity token: " + resultTo);
3829            }
3830            if (!sourceRecord.info.packageName.equals("android")) {
3831                throw new SecurityException(
3832                        "Must be called from an activity that is declared in the android package");
3833            }
3834            if (sourceRecord.app == null) {
3835                throw new SecurityException("Called without a process attached to activity");
3836            }
3837            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3838                // This is still okay, as long as this activity is running under the
3839                // uid of the original calling activity.
3840                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3841                    throw new SecurityException(
3842                            "Calling activity in uid " + sourceRecord.app.uid
3843                                    + " must be system uid or original calling uid "
3844                                    + sourceRecord.launchedFromUid);
3845                }
3846            }
3847            targetUid = sourceRecord.launchedFromUid;
3848            targetPackage = sourceRecord.launchedFromPackage;
3849        }
3850
3851        if (userId == UserHandle.USER_NULL) {
3852            userId = UserHandle.getUserId(sourceRecord.app.uid);
3853        }
3854
3855        // TODO: Switch to user app stacks here.
3856        try {
3857            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3858                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3859                    null, null, options, userId, null, null);
3860            return ret;
3861        } catch (SecurityException e) {
3862            // XXX need to figure out how to propagate to original app.
3863            // A SecurityException here is generally actually a fault of the original
3864            // calling activity (such as a fairly granting permissions), so propagate it
3865            // back to them.
3866            /*
3867            StringBuilder msg = new StringBuilder();
3868            msg.append("While launching");
3869            msg.append(intent.toString());
3870            msg.append(": ");
3871            msg.append(e.getMessage());
3872            */
3873            throw e;
3874        }
3875    }
3876
3877    @Override
3878    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3879            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3880            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3881        enforceNotIsolatedCaller("startActivityAndWait");
3882        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3883                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3884        WaitResult res = new WaitResult();
3885        // TODO: Switch to user app stacks here.
3886        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3887                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3888                options, userId, null, null);
3889        return res;
3890    }
3891
3892    @Override
3893    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3894            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3895            int startFlags, Configuration config, Bundle options, int userId) {
3896        enforceNotIsolatedCaller("startActivityWithConfig");
3897        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3898                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3899        // TODO: Switch to user app stacks here.
3900        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3901                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3902                null, null, config, options, userId, null, null);
3903        return ret;
3904    }
3905
3906    @Override
3907    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
3908            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
3909            int requestCode, int flagsMask, int flagsValues, Bundle options)
3910            throws TransactionTooLargeException {
3911        enforceNotIsolatedCaller("startActivityIntentSender");
3912        // Refuse possible leaked file descriptors
3913        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3914            throw new IllegalArgumentException("File descriptors passed in Intent");
3915        }
3916
3917        IIntentSender sender = intent.getTarget();
3918        if (!(sender instanceof PendingIntentRecord)) {
3919            throw new IllegalArgumentException("Bad PendingIntent object");
3920        }
3921
3922        PendingIntentRecord pir = (PendingIntentRecord)sender;
3923
3924        synchronized (this) {
3925            // If this is coming from the currently resumed activity, it is
3926            // effectively saying that app switches are allowed at this point.
3927            final ActivityStack stack = getFocusedStack();
3928            if (stack.mResumedActivity != null &&
3929                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3930                mAppSwitchesAllowedTime = 0;
3931            }
3932        }
3933        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3934                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3935        return ret;
3936    }
3937
3938    @Override
3939    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3940            Intent intent, String resolvedType, IVoiceInteractionSession session,
3941            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3942            Bundle options, int userId) {
3943        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3944                != PackageManager.PERMISSION_GRANTED) {
3945            String msg = "Permission Denial: startVoiceActivity() from pid="
3946                    + Binder.getCallingPid()
3947                    + ", uid=" + Binder.getCallingUid()
3948                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3949            Slog.w(TAG, msg);
3950            throw new SecurityException(msg);
3951        }
3952        if (session == null || interactor == null) {
3953            throw new NullPointerException("null session or interactor");
3954        }
3955        userId = handleIncomingUser(callingPid, callingUid, userId,
3956                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3957        // TODO: Switch to user app stacks here.
3958        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3959                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3960                null, options, userId, null, null);
3961    }
3962
3963    @Override
3964    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
3965        synchronized (this) {
3966            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
3967                if (keepAwake) {
3968                    mVoiceWakeLock.acquire();
3969                } else {
3970                    mVoiceWakeLock.release();
3971                }
3972            }
3973        }
3974    }
3975
3976    @Override
3977    public boolean startNextMatchingActivity(IBinder callingActivity,
3978            Intent intent, Bundle options) {
3979        // Refuse possible leaked file descriptors
3980        if (intent != null && intent.hasFileDescriptors() == true) {
3981            throw new IllegalArgumentException("File descriptors passed in Intent");
3982        }
3983
3984        synchronized (this) {
3985            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3986            if (r == null) {
3987                ActivityOptions.abort(options);
3988                return false;
3989            }
3990            if (r.app == null || r.app.thread == null) {
3991                // The caller is not running...  d'oh!
3992                ActivityOptions.abort(options);
3993                return false;
3994            }
3995            intent = new Intent(intent);
3996            // The caller is not allowed to change the data.
3997            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3998            // And we are resetting to find the next component...
3999            intent.setComponent(null);
4000
4001            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4002
4003            ActivityInfo aInfo = null;
4004            try {
4005                List<ResolveInfo> resolves =
4006                    AppGlobals.getPackageManager().queryIntentActivities(
4007                            intent, r.resolvedType,
4008                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4009                            UserHandle.getCallingUserId());
4010
4011                // Look for the original activity in the list...
4012                final int N = resolves != null ? resolves.size() : 0;
4013                for (int i=0; i<N; i++) {
4014                    ResolveInfo rInfo = resolves.get(i);
4015                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4016                            && rInfo.activityInfo.name.equals(r.info.name)) {
4017                        // We found the current one...  the next matching is
4018                        // after it.
4019                        i++;
4020                        if (i<N) {
4021                            aInfo = resolves.get(i).activityInfo;
4022                        }
4023                        if (debug) {
4024                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4025                                    + "/" + r.info.name);
4026                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
4027                                    + "/" + aInfo.name);
4028                        }
4029                        break;
4030                    }
4031                }
4032            } catch (RemoteException e) {
4033            }
4034
4035            if (aInfo == null) {
4036                // Nobody who is next!
4037                ActivityOptions.abort(options);
4038                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4039                return false;
4040            }
4041
4042            intent.setComponent(new ComponentName(
4043                    aInfo.applicationInfo.packageName, aInfo.name));
4044            intent.setFlags(intent.getFlags()&~(
4045                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4046                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4047                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4048                    Intent.FLAG_ACTIVITY_NEW_TASK));
4049
4050            // Okay now we need to start the new activity, replacing the
4051            // currently running activity.  This is a little tricky because
4052            // we want to start the new one as if the current one is finished,
4053            // but not finish the current one first so that there is no flicker.
4054            // And thus...
4055            final boolean wasFinishing = r.finishing;
4056            r.finishing = true;
4057
4058            // Propagate reply information over to the new activity.
4059            final ActivityRecord resultTo = r.resultTo;
4060            final String resultWho = r.resultWho;
4061            final int requestCode = r.requestCode;
4062            r.resultTo = null;
4063            if (resultTo != null) {
4064                resultTo.removeResultsLocked(r, resultWho, requestCode);
4065            }
4066
4067            final long origId = Binder.clearCallingIdentity();
4068            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
4069                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
4070                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
4071                    -1, r.launchedFromUid, 0, options, false, null, null, null);
4072            Binder.restoreCallingIdentity(origId);
4073
4074            r.finishing = wasFinishing;
4075            if (res != ActivityManager.START_SUCCESS) {
4076                return false;
4077            }
4078            return true;
4079        }
4080    }
4081
4082    @Override
4083    public final int startActivityFromRecents(int taskId, Bundle options) {
4084        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4085            String msg = "Permission Denial: startActivityFromRecents called without " +
4086                    START_TASKS_FROM_RECENTS;
4087            Slog.w(TAG, msg);
4088            throw new SecurityException(msg);
4089        }
4090        return startActivityFromRecentsInner(taskId, options);
4091    }
4092
4093    final int startActivityFromRecentsInner(int taskId, Bundle options) {
4094        final TaskRecord task;
4095        final int callingUid;
4096        final String callingPackage;
4097        final Intent intent;
4098        final int userId;
4099        synchronized (this) {
4100            task = mRecentTasks.taskForIdLocked(taskId);
4101            if (task == null) {
4102                throw new IllegalArgumentException("Task " + taskId + " not found.");
4103            }
4104            if (task.getRootActivity() != null) {
4105                moveTaskToFrontLocked(task.taskId, 0, null);
4106                return ActivityManager.START_TASK_TO_FRONT;
4107            }
4108            callingUid = task.mCallingUid;
4109            callingPackage = task.mCallingPackage;
4110            intent = task.intent;
4111            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4112            userId = task.userId;
4113        }
4114        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4115                options, userId, null, task);
4116    }
4117
4118    final int startActivityInPackage(int uid, String callingPackage,
4119            Intent intent, String resolvedType, IBinder resultTo,
4120            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
4121            IActivityContainer container, TaskRecord inTask) {
4122
4123        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4124                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4125
4126        // TODO: Switch to user app stacks here.
4127        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
4128                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4129                null, null, null, options, userId, container, inTask);
4130        return ret;
4131    }
4132
4133    @Override
4134    public final int startActivities(IApplicationThread caller, String callingPackage,
4135            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
4136            int userId) {
4137        enforceNotIsolatedCaller("startActivities");
4138        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4139                false, ALLOW_FULL_ONLY, "startActivity", null);
4140        // TODO: Switch to user app stacks here.
4141        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
4142                resolvedTypes, resultTo, options, userId);
4143        return ret;
4144    }
4145
4146    final int startActivitiesInPackage(int uid, String callingPackage,
4147            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4148            Bundle options, int userId) {
4149
4150        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4151                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4152        // TODO: Switch to user app stacks here.
4153        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4154                resultTo, options, userId);
4155        return ret;
4156    }
4157
4158    @Override
4159    public void reportActivityFullyDrawn(IBinder token) {
4160        synchronized (this) {
4161            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4162            if (r == null) {
4163                return;
4164            }
4165            r.reportFullyDrawnLocked();
4166        }
4167    }
4168
4169    @Override
4170    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4171        synchronized (this) {
4172            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4173            if (r == null) {
4174                return;
4175            }
4176            if (r.task != null && r.task.mResizeable) {
4177                // Fixed screen orientation isn't supported with resizeable activities.
4178                return;
4179            }
4180            final long origId = Binder.clearCallingIdentity();
4181            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4182            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4183                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4184            if (config != null) {
4185                r.frozenBeforeDestroy = true;
4186                if (!updateConfigurationLocked(config, r, false, false)) {
4187                    mStackSupervisor.resumeTopActivitiesLocked();
4188                }
4189            }
4190            Binder.restoreCallingIdentity(origId);
4191        }
4192    }
4193
4194    @Override
4195    public int getRequestedOrientation(IBinder token) {
4196        synchronized (this) {
4197            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4198            if (r == null) {
4199                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4200            }
4201            return mWindowManager.getAppOrientation(r.appToken);
4202        }
4203    }
4204
4205    /**
4206     * This is the internal entry point for handling Activity.finish().
4207     *
4208     * @param token The Binder token referencing the Activity we want to finish.
4209     * @param resultCode Result code, if any, from this Activity.
4210     * @param resultData Result data (Intent), if any, from this Activity.
4211     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4212     *            the root Activity in the task.
4213     *
4214     * @return Returns true if the activity successfully finished, or false if it is still running.
4215     */
4216    @Override
4217    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4218            boolean finishTask) {
4219        // Refuse possible leaked file descriptors
4220        if (resultData != null && resultData.hasFileDescriptors() == true) {
4221            throw new IllegalArgumentException("File descriptors passed in Intent");
4222        }
4223
4224        synchronized(this) {
4225            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4226            if (r == null) {
4227                return true;
4228            }
4229            // Keep track of the root activity of the task before we finish it
4230            TaskRecord tr = r.task;
4231            ActivityRecord rootR = tr.getRootActivity();
4232            if (rootR == null) {
4233                Slog.w(TAG, "Finishing task with all activities already finished");
4234            }
4235            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4236            // finish.
4237            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4238                    mStackSupervisor.isLastLockedTask(tr)) {
4239                Slog.i(TAG, "Not finishing task in lock task mode");
4240                mStackSupervisor.showLockTaskToast();
4241                return false;
4242            }
4243            if (mController != null) {
4244                // Find the first activity that is not finishing.
4245                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4246                if (next != null) {
4247                    // ask watcher if this is allowed
4248                    boolean resumeOK = true;
4249                    try {
4250                        resumeOK = mController.activityResuming(next.packageName);
4251                    } catch (RemoteException e) {
4252                        mController = null;
4253                        Watchdog.getInstance().setActivityController(null);
4254                    }
4255
4256                    if (!resumeOK) {
4257                        Slog.i(TAG, "Not finishing activity because controller resumed");
4258                        return false;
4259                    }
4260                }
4261            }
4262            final long origId = Binder.clearCallingIdentity();
4263            try {
4264                boolean res;
4265                if (finishTask && r == rootR) {
4266                    // If requested, remove the task that is associated to this activity only if it
4267                    // was the root activity in the task. The result code and data is ignored
4268                    // because we don't support returning them across task boundaries.
4269                    res = removeTaskByIdLocked(tr.taskId, false);
4270                    if (!res) {
4271                        Slog.i(TAG, "Removing task failed to finish activity");
4272                    }
4273                } else {
4274                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4275                            resultData, "app-request", true);
4276                    if (!res) {
4277                        Slog.i(TAG, "Failed to finish by app-request");
4278                    }
4279                }
4280                return res;
4281            } finally {
4282                Binder.restoreCallingIdentity(origId);
4283            }
4284        }
4285    }
4286
4287    @Override
4288    public final void finishHeavyWeightApp() {
4289        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4290                != PackageManager.PERMISSION_GRANTED) {
4291            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4292                    + Binder.getCallingPid()
4293                    + ", uid=" + Binder.getCallingUid()
4294                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4295            Slog.w(TAG, msg);
4296            throw new SecurityException(msg);
4297        }
4298
4299        synchronized(this) {
4300            if (mHeavyWeightProcess == null) {
4301                return;
4302            }
4303
4304            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4305            for (int i = 0; i < activities.size(); i++) {
4306                ActivityRecord r = activities.get(i);
4307                if (!r.finishing && r.isInStackLocked()) {
4308                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4309                            null, "finish-heavy", true);
4310                }
4311            }
4312
4313            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4314                    mHeavyWeightProcess.userId, 0));
4315            mHeavyWeightProcess = null;
4316        }
4317    }
4318
4319    @Override
4320    public void crashApplication(int uid, int initialPid, String packageName,
4321            String message) {
4322        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4323                != PackageManager.PERMISSION_GRANTED) {
4324            String msg = "Permission Denial: crashApplication() from pid="
4325                    + Binder.getCallingPid()
4326                    + ", uid=" + Binder.getCallingUid()
4327                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4328            Slog.w(TAG, msg);
4329            throw new SecurityException(msg);
4330        }
4331
4332        synchronized(this) {
4333            ProcessRecord proc = null;
4334
4335            // Figure out which process to kill.  We don't trust that initialPid
4336            // still has any relation to current pids, so must scan through the
4337            // list.
4338            synchronized (mPidsSelfLocked) {
4339                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4340                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4341                    if (p.uid != uid) {
4342                        continue;
4343                    }
4344                    if (p.pid == initialPid) {
4345                        proc = p;
4346                        break;
4347                    }
4348                    if (p.pkgList.containsKey(packageName)) {
4349                        proc = p;
4350                    }
4351                }
4352            }
4353
4354            if (proc == null) {
4355                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4356                        + " initialPid=" + initialPid
4357                        + " packageName=" + packageName);
4358                return;
4359            }
4360
4361            if (proc.thread != null) {
4362                if (proc.pid == Process.myPid()) {
4363                    Log.w(TAG, "crashApplication: trying to crash self!");
4364                    return;
4365                }
4366                long ident = Binder.clearCallingIdentity();
4367                try {
4368                    proc.thread.scheduleCrash(message);
4369                } catch (RemoteException e) {
4370                }
4371                Binder.restoreCallingIdentity(ident);
4372            }
4373        }
4374    }
4375
4376    @Override
4377    public final void finishSubActivity(IBinder token, String resultWho,
4378            int requestCode) {
4379        synchronized(this) {
4380            final long origId = Binder.clearCallingIdentity();
4381            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4382            if (r != null) {
4383                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4384            }
4385            Binder.restoreCallingIdentity(origId);
4386        }
4387    }
4388
4389    @Override
4390    public boolean finishActivityAffinity(IBinder token) {
4391        synchronized(this) {
4392            final long origId = Binder.clearCallingIdentity();
4393            try {
4394                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4395                if (r == null) {
4396                    return false;
4397                }
4398
4399                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4400                // can finish.
4401                final TaskRecord task = r.task;
4402                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4403                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4404                    mStackSupervisor.showLockTaskToast();
4405                    return false;
4406                }
4407                return task.stack.finishActivityAffinityLocked(r);
4408            } finally {
4409                Binder.restoreCallingIdentity(origId);
4410            }
4411        }
4412    }
4413
4414    @Override
4415    public void finishVoiceTask(IVoiceInteractionSession session) {
4416        synchronized(this) {
4417            final long origId = Binder.clearCallingIdentity();
4418            try {
4419                mStackSupervisor.finishVoiceTask(session);
4420            } finally {
4421                Binder.restoreCallingIdentity(origId);
4422            }
4423        }
4424
4425    }
4426
4427    @Override
4428    public boolean releaseActivityInstance(IBinder token) {
4429        synchronized(this) {
4430            final long origId = Binder.clearCallingIdentity();
4431            try {
4432                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4433                if (r == null) {
4434                    return false;
4435                }
4436                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4437            } finally {
4438                Binder.restoreCallingIdentity(origId);
4439            }
4440        }
4441    }
4442
4443    @Override
4444    public void releaseSomeActivities(IApplicationThread appInt) {
4445        synchronized(this) {
4446            final long origId = Binder.clearCallingIdentity();
4447            try {
4448                ProcessRecord app = getRecordForAppLocked(appInt);
4449                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4450            } finally {
4451                Binder.restoreCallingIdentity(origId);
4452            }
4453        }
4454    }
4455
4456    @Override
4457    public boolean willActivityBeVisible(IBinder token) {
4458        synchronized(this) {
4459            ActivityStack stack = ActivityRecord.getStackLocked(token);
4460            if (stack != null) {
4461                return stack.willActivityBeVisibleLocked(token);
4462            }
4463            return false;
4464        }
4465    }
4466
4467    @Override
4468    public void overridePendingTransition(IBinder token, String packageName,
4469            int enterAnim, int exitAnim) {
4470        synchronized(this) {
4471            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4472            if (self == null) {
4473                return;
4474            }
4475
4476            final long origId = Binder.clearCallingIdentity();
4477
4478            if (self.state == ActivityState.RESUMED
4479                    || self.state == ActivityState.PAUSING) {
4480                mWindowManager.overridePendingAppTransition(packageName,
4481                        enterAnim, exitAnim, null);
4482            }
4483
4484            Binder.restoreCallingIdentity(origId);
4485        }
4486    }
4487
4488    /**
4489     * Main function for removing an existing process from the activity manager
4490     * as a result of that process going away.  Clears out all connections
4491     * to the process.
4492     */
4493    private final void handleAppDiedLocked(ProcessRecord app,
4494            boolean restarting, boolean allowRestart) {
4495        int pid = app.pid;
4496        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4497        if (!kept && !restarting) {
4498            removeLruProcessLocked(app);
4499            if (pid > 0) {
4500                ProcessList.remove(pid);
4501            }
4502        }
4503
4504        if (mProfileProc == app) {
4505            clearProfilerLocked();
4506        }
4507
4508        // Remove this application's activities from active lists.
4509        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4510
4511        app.activities.clear();
4512
4513        if (app.instrumentationClass != null) {
4514            Slog.w(TAG, "Crash of app " + app.processName
4515                  + " running instrumentation " + app.instrumentationClass);
4516            Bundle info = new Bundle();
4517            info.putString("shortMsg", "Process crashed.");
4518            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4519        }
4520
4521        if (!restarting && hasVisibleActivities && !mStackSupervisor.resumeTopActivitiesLocked()) {
4522            // If there was nothing to resume, and we are not already
4523            // restarting this process, but there is a visible activity that
4524            // is hosted by the process...  then make sure all visible
4525            // activities are running, taking care of restarting this
4526            // process.
4527            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4528        }
4529    }
4530
4531    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4532        IBinder threadBinder = thread.asBinder();
4533        // Find the application record.
4534        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4535            ProcessRecord rec = mLruProcesses.get(i);
4536            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4537                return i;
4538            }
4539        }
4540        return -1;
4541    }
4542
4543    final ProcessRecord getRecordForAppLocked(
4544            IApplicationThread thread) {
4545        if (thread == null) {
4546            return null;
4547        }
4548
4549        int appIndex = getLRURecordIndexForAppLocked(thread);
4550        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4551    }
4552
4553    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4554        // If there are no longer any background processes running,
4555        // and the app that died was not running instrumentation,
4556        // then tell everyone we are now low on memory.
4557        boolean haveBg = false;
4558        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4559            ProcessRecord rec = mLruProcesses.get(i);
4560            if (rec.thread != null
4561                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4562                haveBg = true;
4563                break;
4564            }
4565        }
4566
4567        if (!haveBg) {
4568            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4569            if (doReport) {
4570                long now = SystemClock.uptimeMillis();
4571                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4572                    doReport = false;
4573                } else {
4574                    mLastMemUsageReportTime = now;
4575                }
4576            }
4577            final ArrayList<ProcessMemInfo> memInfos
4578                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4579            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4580            long now = SystemClock.uptimeMillis();
4581            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4582                ProcessRecord rec = mLruProcesses.get(i);
4583                if (rec == dyingProc || rec.thread == null) {
4584                    continue;
4585                }
4586                if (doReport) {
4587                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4588                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4589                }
4590                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4591                    // The low memory report is overriding any current
4592                    // state for a GC request.  Make sure to do
4593                    // heavy/important/visible/foreground processes first.
4594                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4595                        rec.lastRequestedGc = 0;
4596                    } else {
4597                        rec.lastRequestedGc = rec.lastLowMemory;
4598                    }
4599                    rec.reportLowMemory = true;
4600                    rec.lastLowMemory = now;
4601                    mProcessesToGc.remove(rec);
4602                    addProcessToGcListLocked(rec);
4603                }
4604            }
4605            if (doReport) {
4606                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4607                mHandler.sendMessage(msg);
4608            }
4609            scheduleAppGcsLocked();
4610        }
4611    }
4612
4613    final void appDiedLocked(ProcessRecord app) {
4614       appDiedLocked(app, app.pid, app.thread, false);
4615    }
4616
4617    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4618            boolean fromBinderDied) {
4619        // First check if this ProcessRecord is actually active for the pid.
4620        synchronized (mPidsSelfLocked) {
4621            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4622            if (curProc != app) {
4623                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4624                return;
4625            }
4626        }
4627
4628        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4629        synchronized (stats) {
4630            stats.noteProcessDiedLocked(app.info.uid, pid);
4631        }
4632
4633        if (!app.killed) {
4634            if (!fromBinderDied) {
4635                Process.killProcessQuiet(pid);
4636            }
4637            killProcessGroup(app.info.uid, pid);
4638            app.killed = true;
4639        }
4640
4641        // Clean up already done if the process has been re-started.
4642        if (app.pid == pid && app.thread != null &&
4643                app.thread.asBinder() == thread.asBinder()) {
4644            boolean doLowMem = app.instrumentationClass == null;
4645            boolean doOomAdj = doLowMem;
4646            if (!app.killedByAm) {
4647                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4648                        + ") has died");
4649                mAllowLowerMemLevel = true;
4650            } else {
4651                // Note that we always want to do oom adj to update our state with the
4652                // new number of procs.
4653                mAllowLowerMemLevel = false;
4654                doLowMem = false;
4655            }
4656            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4657            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4658                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
4659            handleAppDiedLocked(app, false, true);
4660
4661            if (doOomAdj) {
4662                updateOomAdjLocked();
4663            }
4664            if (doLowMem) {
4665                doLowMemReportIfNeededLocked(app);
4666            }
4667        } else if (app.pid != pid) {
4668            // A new process has already been started.
4669            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4670                    + ") has died and restarted (pid " + app.pid + ").");
4671            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4672        } else if (DEBUG_PROCESSES) {
4673            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
4674                    + thread.asBinder());
4675        }
4676    }
4677
4678    /**
4679     * If a stack trace dump file is configured, dump process stack traces.
4680     * @param clearTraces causes the dump file to be erased prior to the new
4681     *    traces being written, if true; when false, the new traces will be
4682     *    appended to any existing file content.
4683     * @param firstPids of dalvik VM processes to dump stack traces for first
4684     * @param lastPids of dalvik VM processes to dump stack traces for last
4685     * @param nativeProcs optional list of native process names to dump stack crawls
4686     * @return file containing stack traces, or null if no dump file is configured
4687     */
4688    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4689            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4690        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4691        if (tracesPath == null || tracesPath.length() == 0) {
4692            return null;
4693        }
4694
4695        File tracesFile = new File(tracesPath);
4696        try {
4697            File tracesDir = tracesFile.getParentFile();
4698            if (!tracesDir.exists()) {
4699                tracesDir.mkdirs();
4700                if (!SELinux.restorecon(tracesDir)) {
4701                    return null;
4702                }
4703            }
4704            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4705
4706            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4707            tracesFile.createNewFile();
4708            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4709        } catch (IOException e) {
4710            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4711            return null;
4712        }
4713
4714        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4715        return tracesFile;
4716    }
4717
4718    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4719            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4720        // Use a FileObserver to detect when traces finish writing.
4721        // The order of traces is considered important to maintain for legibility.
4722        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4723            @Override
4724            public synchronized void onEvent(int event, String path) { notify(); }
4725        };
4726
4727        try {
4728            observer.startWatching();
4729
4730            // First collect all of the stacks of the most important pids.
4731            if (firstPids != null) {
4732                try {
4733                    int num = firstPids.size();
4734                    for (int i = 0; i < num; i++) {
4735                        synchronized (observer) {
4736                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4737                            observer.wait(200);  // Wait for write-close, give up after 200msec
4738                        }
4739                    }
4740                } catch (InterruptedException e) {
4741                    Slog.wtf(TAG, e);
4742                }
4743            }
4744
4745            // Next collect the stacks of the native pids
4746            if (nativeProcs != null) {
4747                int[] pids = Process.getPidsForCommands(nativeProcs);
4748                if (pids != null) {
4749                    for (int pid : pids) {
4750                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4751                    }
4752                }
4753            }
4754
4755            // Lastly, measure CPU usage.
4756            if (processCpuTracker != null) {
4757                processCpuTracker.init();
4758                System.gc();
4759                processCpuTracker.update();
4760                try {
4761                    synchronized (processCpuTracker) {
4762                        processCpuTracker.wait(500); // measure over 1/2 second.
4763                    }
4764                } catch (InterruptedException e) {
4765                }
4766                processCpuTracker.update();
4767
4768                // We'll take the stack crawls of just the top apps using CPU.
4769                final int N = processCpuTracker.countWorkingStats();
4770                int numProcs = 0;
4771                for (int i=0; i<N && numProcs<5; i++) {
4772                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4773                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4774                        numProcs++;
4775                        try {
4776                            synchronized (observer) {
4777                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4778                                observer.wait(200);  // Wait for write-close, give up after 200msec
4779                            }
4780                        } catch (InterruptedException e) {
4781                            Slog.wtf(TAG, e);
4782                        }
4783
4784                    }
4785                }
4786            }
4787        } finally {
4788            observer.stopWatching();
4789        }
4790    }
4791
4792    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4793        if (true || IS_USER_BUILD) {
4794            return;
4795        }
4796        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4797        if (tracesPath == null || tracesPath.length() == 0) {
4798            return;
4799        }
4800
4801        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4802        StrictMode.allowThreadDiskWrites();
4803        try {
4804            final File tracesFile = new File(tracesPath);
4805            final File tracesDir = tracesFile.getParentFile();
4806            final File tracesTmp = new File(tracesDir, "__tmp__");
4807            try {
4808                if (!tracesDir.exists()) {
4809                    tracesDir.mkdirs();
4810                    if (!SELinux.restorecon(tracesDir.getPath())) {
4811                        return;
4812                    }
4813                }
4814                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4815
4816                if (tracesFile.exists()) {
4817                    tracesTmp.delete();
4818                    tracesFile.renameTo(tracesTmp);
4819                }
4820                StringBuilder sb = new StringBuilder();
4821                Time tobj = new Time();
4822                tobj.set(System.currentTimeMillis());
4823                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4824                sb.append(": ");
4825                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4826                sb.append(" since ");
4827                sb.append(msg);
4828                FileOutputStream fos = new FileOutputStream(tracesFile);
4829                fos.write(sb.toString().getBytes());
4830                if (app == null) {
4831                    fos.write("\n*** No application process!".getBytes());
4832                }
4833                fos.close();
4834                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4835            } catch (IOException e) {
4836                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4837                return;
4838            }
4839
4840            if (app != null) {
4841                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4842                firstPids.add(app.pid);
4843                dumpStackTraces(tracesPath, firstPids, null, null, null);
4844            }
4845
4846            File lastTracesFile = null;
4847            File curTracesFile = null;
4848            for (int i=9; i>=0; i--) {
4849                String name = String.format(Locale.US, "slow%02d.txt", i);
4850                curTracesFile = new File(tracesDir, name);
4851                if (curTracesFile.exists()) {
4852                    if (lastTracesFile != null) {
4853                        curTracesFile.renameTo(lastTracesFile);
4854                    } else {
4855                        curTracesFile.delete();
4856                    }
4857                }
4858                lastTracesFile = curTracesFile;
4859            }
4860            tracesFile.renameTo(curTracesFile);
4861            if (tracesTmp.exists()) {
4862                tracesTmp.renameTo(tracesFile);
4863            }
4864        } finally {
4865            StrictMode.setThreadPolicy(oldPolicy);
4866        }
4867    }
4868
4869    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4870            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4871        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4872        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4873
4874        if (mController != null) {
4875            try {
4876                // 0 == continue, -1 = kill process immediately
4877                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4878                if (res < 0 && app.pid != MY_PID) {
4879                    app.kill("anr", true);
4880                }
4881            } catch (RemoteException e) {
4882                mController = null;
4883                Watchdog.getInstance().setActivityController(null);
4884            }
4885        }
4886
4887        long anrTime = SystemClock.uptimeMillis();
4888        if (MONITOR_CPU_USAGE) {
4889            updateCpuStatsNow();
4890        }
4891
4892        synchronized (this) {
4893            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4894            if (mShuttingDown) {
4895                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4896                return;
4897            } else if (app.notResponding) {
4898                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4899                return;
4900            } else if (app.crashing) {
4901                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4902                return;
4903            }
4904
4905            // In case we come through here for the same app before completing
4906            // this one, mark as anring now so we will bail out.
4907            app.notResponding = true;
4908
4909            // Log the ANR to the event log.
4910            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4911                    app.processName, app.info.flags, annotation);
4912
4913            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4914            firstPids.add(app.pid);
4915
4916            int parentPid = app.pid;
4917            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4918            if (parentPid != app.pid) firstPids.add(parentPid);
4919
4920            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4921
4922            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4923                ProcessRecord r = mLruProcesses.get(i);
4924                if (r != null && r.thread != null) {
4925                    int pid = r.pid;
4926                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4927                        if (r.persistent) {
4928                            firstPids.add(pid);
4929                        } else {
4930                            lastPids.put(pid, Boolean.TRUE);
4931                        }
4932                    }
4933                }
4934            }
4935        }
4936
4937        // Log the ANR to the main log.
4938        StringBuilder info = new StringBuilder();
4939        info.setLength(0);
4940        info.append("ANR in ").append(app.processName);
4941        if (activity != null && activity.shortComponentName != null) {
4942            info.append(" (").append(activity.shortComponentName).append(")");
4943        }
4944        info.append("\n");
4945        info.append("PID: ").append(app.pid).append("\n");
4946        if (annotation != null) {
4947            info.append("Reason: ").append(annotation).append("\n");
4948        }
4949        if (parent != null && parent != activity) {
4950            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4951        }
4952
4953        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4954
4955        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4956                NATIVE_STACKS_OF_INTEREST);
4957
4958        String cpuInfo = null;
4959        if (MONITOR_CPU_USAGE) {
4960            updateCpuStatsNow();
4961            synchronized (mProcessCpuTracker) {
4962                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4963            }
4964            info.append(processCpuTracker.printCurrentLoad());
4965            info.append(cpuInfo);
4966        }
4967
4968        info.append(processCpuTracker.printCurrentState(anrTime));
4969
4970        Slog.e(TAG, info.toString());
4971        if (tracesFile == null) {
4972            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4973            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4974        }
4975
4976        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4977                cpuInfo, tracesFile, null);
4978
4979        if (mController != null) {
4980            try {
4981                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4982                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4983                if (res != 0) {
4984                    if (res < 0 && app.pid != MY_PID) {
4985                        app.kill("anr", true);
4986                    } else {
4987                        synchronized (this) {
4988                            mServices.scheduleServiceTimeoutLocked(app);
4989                        }
4990                    }
4991                    return;
4992                }
4993            } catch (RemoteException e) {
4994                mController = null;
4995                Watchdog.getInstance().setActivityController(null);
4996            }
4997        }
4998
4999        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5000        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5001                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5002
5003        synchronized (this) {
5004            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5005
5006            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5007                app.kill("bg anr", true);
5008                return;
5009            }
5010
5011            // Set the app's notResponding state, and look up the errorReportReceiver
5012            makeAppNotRespondingLocked(app,
5013                    activity != null ? activity.shortComponentName : null,
5014                    annotation != null ? "ANR " + annotation : "ANR",
5015                    info.toString());
5016
5017            // Bring up the infamous App Not Responding dialog
5018            Message msg = Message.obtain();
5019            HashMap<String, Object> map = new HashMap<String, Object>();
5020            msg.what = SHOW_NOT_RESPONDING_MSG;
5021            msg.obj = map;
5022            msg.arg1 = aboveSystem ? 1 : 0;
5023            map.put("app", app);
5024            if (activity != null) {
5025                map.put("activity", activity);
5026            }
5027
5028            mUiHandler.sendMessage(msg);
5029        }
5030    }
5031
5032    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5033        if (!mLaunchWarningShown) {
5034            mLaunchWarningShown = true;
5035            mUiHandler.post(new Runnable() {
5036                @Override
5037                public void run() {
5038                    synchronized (ActivityManagerService.this) {
5039                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5040                        d.show();
5041                        mUiHandler.postDelayed(new Runnable() {
5042                            @Override
5043                            public void run() {
5044                                synchronized (ActivityManagerService.this) {
5045                                    d.dismiss();
5046                                    mLaunchWarningShown = false;
5047                                }
5048                            }
5049                        }, 4000);
5050                    }
5051                }
5052            });
5053        }
5054    }
5055
5056    @Override
5057    public boolean clearApplicationUserData(final String packageName,
5058            final IPackageDataObserver observer, int userId) {
5059        enforceNotIsolatedCaller("clearApplicationUserData");
5060        if (packageName != null && packageName.equals(mDeviceOwnerName)) {
5061            throw new SecurityException("Clearing DeviceOwner data is forbidden.");
5062        }
5063        int uid = Binder.getCallingUid();
5064        int pid = Binder.getCallingPid();
5065        userId = handleIncomingUser(pid, uid,
5066                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5067        long callingId = Binder.clearCallingIdentity();
5068        try {
5069            IPackageManager pm = AppGlobals.getPackageManager();
5070            int pkgUid = -1;
5071            synchronized(this) {
5072                try {
5073                    pkgUid = pm.getPackageUid(packageName, userId);
5074                } catch (RemoteException e) {
5075                }
5076                if (pkgUid == -1) {
5077                    Slog.w(TAG, "Invalid packageName: " + packageName);
5078                    if (observer != null) {
5079                        try {
5080                            observer.onRemoveCompleted(packageName, false);
5081                        } catch (RemoteException e) {
5082                            Slog.i(TAG, "Observer no longer exists.");
5083                        }
5084                    }
5085                    return false;
5086                }
5087                if (uid == pkgUid || checkComponentPermission(
5088                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5089                        pid, uid, -1, true)
5090                        == PackageManager.PERMISSION_GRANTED) {
5091                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5092                } else {
5093                    throw new SecurityException("PID " + pid + " does not have permission "
5094                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5095                                    + " of package " + packageName);
5096                }
5097
5098                // Remove all tasks match the cleared application package and user
5099                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5100                    final TaskRecord tr = mRecentTasks.get(i);
5101                    final String taskPackageName =
5102                            tr.getBaseIntent().getComponent().getPackageName();
5103                    if (tr.userId != userId) continue;
5104                    if (!taskPackageName.equals(packageName)) continue;
5105                    removeTaskByIdLocked(tr.taskId, false);
5106                }
5107            }
5108
5109            try {
5110                // Clear application user data
5111                pm.clearApplicationUserData(packageName, observer, userId);
5112
5113                synchronized(this) {
5114                    // Remove all permissions granted from/to this package
5115                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5116                }
5117
5118                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5119                        Uri.fromParts("package", packageName, null));
5120                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5121                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5122                        null, null, 0, null, null, null, null, false, false, userId);
5123            } catch (RemoteException e) {
5124            }
5125        } finally {
5126            Binder.restoreCallingIdentity(callingId);
5127        }
5128        return true;
5129    }
5130
5131    @Override
5132    public void killBackgroundProcesses(final String packageName, int userId) {
5133        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5134                != PackageManager.PERMISSION_GRANTED &&
5135                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5136                        != PackageManager.PERMISSION_GRANTED) {
5137            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5138                    + Binder.getCallingPid()
5139                    + ", uid=" + Binder.getCallingUid()
5140                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5141            Slog.w(TAG, msg);
5142            throw new SecurityException(msg);
5143        }
5144
5145        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5146                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5147        long callingId = Binder.clearCallingIdentity();
5148        try {
5149            IPackageManager pm = AppGlobals.getPackageManager();
5150            synchronized(this) {
5151                int appId = -1;
5152                try {
5153                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5154                } catch (RemoteException e) {
5155                }
5156                if (appId == -1) {
5157                    Slog.w(TAG, "Invalid packageName: " + packageName);
5158                    return;
5159                }
5160                killPackageProcessesLocked(packageName, appId, userId,
5161                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5162            }
5163        } finally {
5164            Binder.restoreCallingIdentity(callingId);
5165        }
5166    }
5167
5168    @Override
5169    public void killAllBackgroundProcesses() {
5170        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5171                != PackageManager.PERMISSION_GRANTED) {
5172            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5173                    + Binder.getCallingPid()
5174                    + ", uid=" + Binder.getCallingUid()
5175                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5176            Slog.w(TAG, msg);
5177            throw new SecurityException(msg);
5178        }
5179
5180        long callingId = Binder.clearCallingIdentity();
5181        try {
5182            synchronized(this) {
5183                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5184                final int NP = mProcessNames.getMap().size();
5185                for (int ip=0; ip<NP; ip++) {
5186                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5187                    final int NA = apps.size();
5188                    for (int ia=0; ia<NA; ia++) {
5189                        ProcessRecord app = apps.valueAt(ia);
5190                        if (app.persistent) {
5191                            // we don't kill persistent processes
5192                            continue;
5193                        }
5194                        if (app.removed) {
5195                            procs.add(app);
5196                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5197                            app.removed = true;
5198                            procs.add(app);
5199                        }
5200                    }
5201                }
5202
5203                int N = procs.size();
5204                for (int i=0; i<N; i++) {
5205                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5206                }
5207                mAllowLowerMemLevel = true;
5208                updateOomAdjLocked();
5209                doLowMemReportIfNeededLocked(null);
5210            }
5211        } finally {
5212            Binder.restoreCallingIdentity(callingId);
5213        }
5214    }
5215
5216    @Override
5217    public void forceStopPackage(final String packageName, int userId) {
5218        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5219                != PackageManager.PERMISSION_GRANTED) {
5220            String msg = "Permission Denial: forceStopPackage() from pid="
5221                    + Binder.getCallingPid()
5222                    + ", uid=" + Binder.getCallingUid()
5223                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5224            Slog.w(TAG, msg);
5225            throw new SecurityException(msg);
5226        }
5227        final int callingPid = Binder.getCallingPid();
5228        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5229                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5230        long callingId = Binder.clearCallingIdentity();
5231        try {
5232            IPackageManager pm = AppGlobals.getPackageManager();
5233            synchronized(this) {
5234                int[] users = userId == UserHandle.USER_ALL
5235                        ? getUsersLocked() : new int[] { userId };
5236                for (int user : users) {
5237                    int pkgUid = -1;
5238                    try {
5239                        pkgUid = pm.getPackageUid(packageName, user);
5240                    } catch (RemoteException e) {
5241                    }
5242                    if (pkgUid == -1) {
5243                        Slog.w(TAG, "Invalid packageName: " + packageName);
5244                        continue;
5245                    }
5246                    try {
5247                        pm.setPackageStoppedState(packageName, true, user);
5248                    } catch (RemoteException e) {
5249                    } catch (IllegalArgumentException e) {
5250                        Slog.w(TAG, "Failed trying to unstop package "
5251                                + packageName + ": " + e);
5252                    }
5253                    if (isUserRunningLocked(user, false)) {
5254                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5255                    }
5256                }
5257            }
5258        } finally {
5259            Binder.restoreCallingIdentity(callingId);
5260        }
5261    }
5262
5263    @Override
5264    public void addPackageDependency(String packageName) {
5265        synchronized (this) {
5266            int callingPid = Binder.getCallingPid();
5267            if (callingPid == Process.myPid()) {
5268                //  Yeah, um, no.
5269                return;
5270            }
5271            ProcessRecord proc;
5272            synchronized (mPidsSelfLocked) {
5273                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5274            }
5275            if (proc != null) {
5276                if (proc.pkgDeps == null) {
5277                    proc.pkgDeps = new ArraySet<String>(1);
5278                }
5279                proc.pkgDeps.add(packageName);
5280            }
5281        }
5282    }
5283
5284    /*
5285     * The pkg name and app id have to be specified.
5286     */
5287    @Override
5288    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5289        if (pkg == null) {
5290            return;
5291        }
5292        // Make sure the uid is valid.
5293        if (appid < 0) {
5294            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5295            return;
5296        }
5297        int callerUid = Binder.getCallingUid();
5298        // Only the system server can kill an application
5299        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5300            // Post an aysnc message to kill the application
5301            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5302            msg.arg1 = appid;
5303            msg.arg2 = 0;
5304            Bundle bundle = new Bundle();
5305            bundle.putString("pkg", pkg);
5306            bundle.putString("reason", reason);
5307            msg.obj = bundle;
5308            mHandler.sendMessage(msg);
5309        } else {
5310            throw new SecurityException(callerUid + " cannot kill pkg: " +
5311                    pkg);
5312        }
5313    }
5314
5315    @Override
5316    public void closeSystemDialogs(String reason) {
5317        enforceNotIsolatedCaller("closeSystemDialogs");
5318
5319        final int pid = Binder.getCallingPid();
5320        final int uid = Binder.getCallingUid();
5321        final long origId = Binder.clearCallingIdentity();
5322        try {
5323            synchronized (this) {
5324                // Only allow this from foreground processes, so that background
5325                // applications can't abuse it to prevent system UI from being shown.
5326                if (uid >= Process.FIRST_APPLICATION_UID) {
5327                    ProcessRecord proc;
5328                    synchronized (mPidsSelfLocked) {
5329                        proc = mPidsSelfLocked.get(pid);
5330                    }
5331                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5332                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5333                                + " from background process " + proc);
5334                        return;
5335                    }
5336                }
5337                closeSystemDialogsLocked(reason);
5338            }
5339        } finally {
5340            Binder.restoreCallingIdentity(origId);
5341        }
5342    }
5343
5344    void closeSystemDialogsLocked(String reason) {
5345        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5346        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5347                | Intent.FLAG_RECEIVER_FOREGROUND);
5348        if (reason != null) {
5349            intent.putExtra("reason", reason);
5350        }
5351        mWindowManager.closeSystemDialogs(reason);
5352
5353        mStackSupervisor.closeSystemDialogsLocked();
5354
5355        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5356                AppOpsManager.OP_NONE, null, false, false,
5357                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5358    }
5359
5360    @Override
5361    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5362        enforceNotIsolatedCaller("getProcessMemoryInfo");
5363        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5364        for (int i=pids.length-1; i>=0; i--) {
5365            ProcessRecord proc;
5366            int oomAdj;
5367            synchronized (this) {
5368                synchronized (mPidsSelfLocked) {
5369                    proc = mPidsSelfLocked.get(pids[i]);
5370                    oomAdj = proc != null ? proc.setAdj : 0;
5371                }
5372            }
5373            infos[i] = new Debug.MemoryInfo();
5374            Debug.getMemoryInfo(pids[i], infos[i]);
5375            if (proc != null) {
5376                synchronized (this) {
5377                    if (proc.thread != null && proc.setAdj == oomAdj) {
5378                        // Record this for posterity if the process has been stable.
5379                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5380                                infos[i].getTotalUss(), false, proc.pkgList);
5381                    }
5382                }
5383            }
5384        }
5385        return infos;
5386    }
5387
5388    @Override
5389    public long[] getProcessPss(int[] pids) {
5390        enforceNotIsolatedCaller("getProcessPss");
5391        long[] pss = new long[pids.length];
5392        for (int i=pids.length-1; i>=0; i--) {
5393            ProcessRecord proc;
5394            int oomAdj;
5395            synchronized (this) {
5396                synchronized (mPidsSelfLocked) {
5397                    proc = mPidsSelfLocked.get(pids[i]);
5398                    oomAdj = proc != null ? proc.setAdj : 0;
5399                }
5400            }
5401            long[] tmpUss = new long[1];
5402            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5403            if (proc != null) {
5404                synchronized (this) {
5405                    if (proc.thread != null && proc.setAdj == oomAdj) {
5406                        // Record this for posterity if the process has been stable.
5407                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5408                    }
5409                }
5410            }
5411        }
5412        return pss;
5413    }
5414
5415    @Override
5416    public void killApplicationProcess(String processName, int uid) {
5417        if (processName == null) {
5418            return;
5419        }
5420
5421        int callerUid = Binder.getCallingUid();
5422        // Only the system server can kill an application
5423        if (callerUid == Process.SYSTEM_UID) {
5424            synchronized (this) {
5425                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5426                if (app != null && app.thread != null) {
5427                    try {
5428                        app.thread.scheduleSuicide();
5429                    } catch (RemoteException e) {
5430                        // If the other end already died, then our work here is done.
5431                    }
5432                } else {
5433                    Slog.w(TAG, "Process/uid not found attempting kill of "
5434                            + processName + " / " + uid);
5435                }
5436            }
5437        } else {
5438            throw new SecurityException(callerUid + " cannot kill app process: " +
5439                    processName);
5440        }
5441    }
5442
5443    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5444        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5445                false, true, false, false, UserHandle.getUserId(uid), reason);
5446        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5447                Uri.fromParts("package", packageName, null));
5448        if (!mProcessesReady) {
5449            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5450                    | Intent.FLAG_RECEIVER_FOREGROUND);
5451        }
5452        intent.putExtra(Intent.EXTRA_UID, uid);
5453        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5454        broadcastIntentLocked(null, null, intent,
5455                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5456                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5457    }
5458
5459    private void forceStopUserLocked(int userId, String reason) {
5460        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5461        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5462        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5463                | Intent.FLAG_RECEIVER_FOREGROUND);
5464        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5465        broadcastIntentLocked(null, null, intent,
5466                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5467                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5468    }
5469
5470    private final boolean killPackageProcessesLocked(String packageName, int appId,
5471            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5472            boolean doit, boolean evenPersistent, String reason) {
5473        ArrayList<ProcessRecord> procs = new ArrayList<>();
5474
5475        // Remove all processes this package may have touched: all with the
5476        // same UID (except for the system or root user), and all whose name
5477        // matches the package name.
5478        final int NP = mProcessNames.getMap().size();
5479        for (int ip=0; ip<NP; ip++) {
5480            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5481            final int NA = apps.size();
5482            for (int ia=0; ia<NA; ia++) {
5483                ProcessRecord app = apps.valueAt(ia);
5484                if (app.persistent && !evenPersistent) {
5485                    // we don't kill persistent processes
5486                    continue;
5487                }
5488                if (app.removed) {
5489                    if (doit) {
5490                        procs.add(app);
5491                    }
5492                    continue;
5493                }
5494
5495                // Skip process if it doesn't meet our oom adj requirement.
5496                if (app.setAdj < minOomAdj) {
5497                    continue;
5498                }
5499
5500                // If no package is specified, we call all processes under the
5501                // give user id.
5502                if (packageName == null) {
5503                    if (app.userId != userId) {
5504                        continue;
5505                    }
5506                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5507                        continue;
5508                    }
5509                // Package has been specified, we want to hit all processes
5510                // that match it.  We need to qualify this by the processes
5511                // that are running under the specified app and user ID.
5512                } else {
5513                    final boolean isDep = app.pkgDeps != null
5514                            && app.pkgDeps.contains(packageName);
5515                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5516                        continue;
5517                    }
5518                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5519                        continue;
5520                    }
5521                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5522                        continue;
5523                    }
5524                }
5525
5526                // Process has passed all conditions, kill it!
5527                if (!doit) {
5528                    return true;
5529                }
5530                app.removed = true;
5531                procs.add(app);
5532            }
5533        }
5534
5535        int N = procs.size();
5536        for (int i=0; i<N; i++) {
5537            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5538        }
5539        updateOomAdjLocked();
5540        return N > 0;
5541    }
5542
5543    private void cleanupDisabledPackageComponentsLocked(
5544            String packageName, int userId, String[] changedClasses) {
5545
5546        Set<String> disabledClasses = null;
5547        boolean packageDisabled = false;
5548        IPackageManager pm = AppGlobals.getPackageManager();
5549
5550        if (changedClasses == null) {
5551            // Nothing changed...
5552            return;
5553        }
5554
5555        // Determine enable/disable state of the package and its components.
5556        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5557        for (int i = changedClasses.length - 1; i >= 0; i--) {
5558            final String changedClass = changedClasses[i];
5559
5560            if (changedClass.equals(packageName)) {
5561                try {
5562                    // Entire package setting changed
5563                    enabled = pm.getApplicationEnabledSetting(packageName,
5564                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5565                } catch (Exception e) {
5566                    // No such package/component; probably racing with uninstall.  In any
5567                    // event it means we have nothing further to do here.
5568                    return;
5569                }
5570                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5571                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5572                if (packageDisabled) {
5573                    // Entire package is disabled.
5574                    // No need to continue to check component states.
5575                    disabledClasses = null;
5576                    break;
5577                }
5578            } else {
5579                try {
5580                    enabled = pm.getComponentEnabledSetting(
5581                            new ComponentName(packageName, changedClass),
5582                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5583                } catch (Exception e) {
5584                    // As above, probably racing with uninstall.
5585                    return;
5586                }
5587                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5588                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5589                    if (disabledClasses == null) {
5590                        disabledClasses = new ArraySet<>(changedClasses.length);
5591                    }
5592                    disabledClasses.add(changedClass);
5593                }
5594            }
5595        }
5596
5597        if (!packageDisabled && disabledClasses == null) {
5598            // Nothing to do here...
5599            return;
5600        }
5601
5602        // Clean-up disabled activities.
5603        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5604                packageName, disabledClasses, true, false, userId) && mBooted) {
5605            mStackSupervisor.resumeTopActivitiesLocked();
5606            mStackSupervisor.scheduleIdleLocked();
5607        }
5608
5609        // Clean-up disabled tasks
5610        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5611
5612        // Clean-up disabled services.
5613        mServices.bringDownDisabledPackageServicesLocked(
5614                packageName, disabledClasses, userId, false, true);
5615
5616        // Clean-up disabled providers.
5617        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5618        mProviderMap.collectPackageProvidersLocked(
5619                packageName, disabledClasses, true, false, userId, providers);
5620        for (int i = providers.size() - 1; i >= 0; i--) {
5621            removeDyingProviderLocked(null, providers.get(i), true);
5622        }
5623
5624        // Clean-up disabled broadcast receivers.
5625        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5626            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5627                    packageName, disabledClasses, userId, true);
5628        }
5629
5630    }
5631
5632    private final boolean forceStopPackageLocked(String packageName, int appId,
5633            boolean callerWillRestart, boolean purgeCache, boolean doit,
5634            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5635        int i;
5636
5637        if (userId == UserHandle.USER_ALL && packageName == null) {
5638            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5639        }
5640
5641        if (appId < 0 && packageName != null) {
5642            try {
5643                appId = UserHandle.getAppId(
5644                        AppGlobals.getPackageManager().getPackageUid(packageName, 0));
5645            } catch (RemoteException e) {
5646            }
5647        }
5648
5649        if (doit) {
5650            if (packageName != null) {
5651                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5652                        + " user=" + userId + ": " + reason);
5653            } else {
5654                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5655            }
5656
5657            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5658            for (int ip = pmap.size() - 1; ip >= 0; ip--) {
5659                SparseArray<Long> ba = pmap.valueAt(ip);
5660                for (i = ba.size() - 1; i >= 0; i--) {
5661                    boolean remove = false;
5662                    final int entUid = ba.keyAt(i);
5663                    if (packageName != null) {
5664                        if (userId == UserHandle.USER_ALL) {
5665                            if (UserHandle.getAppId(entUid) == appId) {
5666                                remove = true;
5667                            }
5668                        } else {
5669                            if (entUid == UserHandle.getUid(userId, appId)) {
5670                                remove = true;
5671                            }
5672                        }
5673                    } else if (UserHandle.getUserId(entUid) == userId) {
5674                        remove = true;
5675                    }
5676                    if (remove) {
5677                        ba.removeAt(i);
5678                    }
5679                }
5680                if (ba.size() == 0) {
5681                    pmap.removeAt(ip);
5682                }
5683            }
5684        }
5685
5686        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5687                -100, callerWillRestart, true, doit, evenPersistent,
5688                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5689
5690        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5691                packageName, null, doit, evenPersistent, userId)) {
5692            if (!doit) {
5693                return true;
5694            }
5695            didSomething = true;
5696        }
5697
5698        if (mServices.bringDownDisabledPackageServicesLocked(
5699                packageName, null, userId, evenPersistent, doit)) {
5700            if (!doit) {
5701                return true;
5702            }
5703            didSomething = true;
5704        }
5705
5706        if (packageName == null) {
5707            // Remove all sticky broadcasts from this user.
5708            mStickyBroadcasts.remove(userId);
5709        }
5710
5711        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5712        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5713                userId, providers)) {
5714            if (!doit) {
5715                return true;
5716            }
5717            didSomething = true;
5718        }
5719        for (i = providers.size() - 1; i >= 0; i--) {
5720            removeDyingProviderLocked(null, providers.get(i), true);
5721        }
5722
5723        // Remove transient permissions granted from/to this package/user
5724        removeUriPermissionsForPackageLocked(packageName, userId, false);
5725
5726        if (doit) {
5727            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
5728                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5729                        packageName, null, userId, doit);
5730            }
5731        }
5732
5733        if (packageName == null || uninstalling) {
5734            // Remove pending intents.  For now we only do this when force
5735            // stopping users, because we have some problems when doing this
5736            // for packages -- app widgets are not currently cleaned up for
5737            // such packages, so they can be left with bad pending intents.
5738            if (mIntentSenderRecords.size() > 0) {
5739                Iterator<WeakReference<PendingIntentRecord>> it
5740                        = mIntentSenderRecords.values().iterator();
5741                while (it.hasNext()) {
5742                    WeakReference<PendingIntentRecord> wpir = it.next();
5743                    if (wpir == null) {
5744                        it.remove();
5745                        continue;
5746                    }
5747                    PendingIntentRecord pir = wpir.get();
5748                    if (pir == null) {
5749                        it.remove();
5750                        continue;
5751                    }
5752                    if (packageName == null) {
5753                        // Stopping user, remove all objects for the user.
5754                        if (pir.key.userId != userId) {
5755                            // Not the same user, skip it.
5756                            continue;
5757                        }
5758                    } else {
5759                        if (UserHandle.getAppId(pir.uid) != appId) {
5760                            // Different app id, skip it.
5761                            continue;
5762                        }
5763                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5764                            // Different user, skip it.
5765                            continue;
5766                        }
5767                        if (!pir.key.packageName.equals(packageName)) {
5768                            // Different package, skip it.
5769                            continue;
5770                        }
5771                    }
5772                    if (!doit) {
5773                        return true;
5774                    }
5775                    didSomething = true;
5776                    it.remove();
5777                    pir.canceled = true;
5778                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5779                        pir.key.activity.pendingResults.remove(pir.ref);
5780                    }
5781                }
5782            }
5783        }
5784
5785        if (doit) {
5786            if (purgeCache && packageName != null) {
5787                AttributeCache ac = AttributeCache.instance();
5788                if (ac != null) {
5789                    ac.removePackage(packageName);
5790                }
5791            }
5792            if (mBooted) {
5793                mStackSupervisor.resumeTopActivitiesLocked();
5794                mStackSupervisor.scheduleIdleLocked();
5795            }
5796        }
5797
5798        return didSomething;
5799    }
5800
5801    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
5802        ProcessRecord old = mProcessNames.remove(name, uid);
5803        if (old != null) {
5804            old.uidRecord.numProcs--;
5805            if (old.uidRecord.numProcs == 0) {
5806                // No more processes using this uid, tell clients it is gone.
5807                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5808                        "No more processes in " + old.uidRecord);
5809                enqueueUidChangeLocked(old.uidRecord, true);
5810                mActiveUids.remove(uid);
5811            }
5812            old.uidRecord = null;
5813        }
5814        mIsolatedProcesses.remove(uid);
5815        return old;
5816    }
5817
5818    private final void addProcessNameLocked(ProcessRecord proc) {
5819        // We shouldn't already have a process under this name, but just in case we
5820        // need to clean up whatever may be there now.
5821        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
5822        if (old != null) {
5823            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
5824        }
5825        UidRecord uidRec = mActiveUids.get(proc.uid);
5826        if (uidRec == null) {
5827            uidRec = new UidRecord(proc.uid);
5828            // This is the first appearance of the uid, report it now!
5829            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5830                    "Creating new process uid: " + uidRec);
5831            mActiveUids.put(proc.uid, uidRec);
5832            enqueueUidChangeLocked(uidRec, false);
5833        }
5834        proc.uidRecord = uidRec;
5835        uidRec.numProcs++;
5836        mProcessNames.put(proc.processName, proc.uid, proc);
5837        if (proc.isolated) {
5838            mIsolatedProcesses.put(proc.uid, proc);
5839        }
5840    }
5841
5842    private final boolean removeProcessLocked(ProcessRecord app,
5843            boolean callerWillRestart, boolean allowRestart, String reason) {
5844        final String name = app.processName;
5845        final int uid = app.uid;
5846        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
5847            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
5848
5849        removeProcessNameLocked(name, uid);
5850        if (mHeavyWeightProcess == app) {
5851            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5852                    mHeavyWeightProcess.userId, 0));
5853            mHeavyWeightProcess = null;
5854        }
5855        boolean needRestart = false;
5856        if (app.pid > 0 && app.pid != MY_PID) {
5857            int pid = app.pid;
5858            synchronized (mPidsSelfLocked) {
5859                mPidsSelfLocked.remove(pid);
5860                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5861            }
5862            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5863            if (app.isolated) {
5864                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5865            }
5866            boolean willRestart = false;
5867            if (app.persistent && !app.isolated) {
5868                if (!callerWillRestart) {
5869                    willRestart = true;
5870                } else {
5871                    needRestart = true;
5872                }
5873            }
5874            app.kill(reason, true);
5875            handleAppDiedLocked(app, willRestart, allowRestart);
5876            if (willRestart) {
5877                removeLruProcessLocked(app);
5878                addAppLocked(app.info, false, null /* ABI override */);
5879            }
5880        } else {
5881            mRemovedProcesses.add(app);
5882        }
5883
5884        return needRestart;
5885    }
5886
5887    private final void processStartTimedOutLocked(ProcessRecord app) {
5888        final int pid = app.pid;
5889        boolean gone = false;
5890        synchronized (mPidsSelfLocked) {
5891            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5892            if (knownApp != null && knownApp.thread == null) {
5893                mPidsSelfLocked.remove(pid);
5894                gone = true;
5895            }
5896        }
5897
5898        if (gone) {
5899            Slog.w(TAG, "Process " + app + " failed to attach");
5900            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5901                    pid, app.uid, app.processName);
5902            removeProcessNameLocked(app.processName, app.uid);
5903            if (mHeavyWeightProcess == app) {
5904                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5905                        mHeavyWeightProcess.userId, 0));
5906                mHeavyWeightProcess = null;
5907            }
5908            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5909            if (app.isolated) {
5910                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5911            }
5912            // Take care of any launching providers waiting for this process.
5913            checkAppInLaunchingProvidersLocked(app, true);
5914            // Take care of any services that are waiting for the process.
5915            mServices.processStartTimedOutLocked(app);
5916            app.kill("start timeout", true);
5917            removeLruProcessLocked(app);
5918            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5919                Slog.w(TAG, "Unattached app died before backup, skipping");
5920                try {
5921                    IBackupManager bm = IBackupManager.Stub.asInterface(
5922                            ServiceManager.getService(Context.BACKUP_SERVICE));
5923                    bm.agentDisconnected(app.info.packageName);
5924                } catch (RemoteException e) {
5925                    // Can't happen; the backup manager is local
5926                }
5927            }
5928            if (isPendingBroadcastProcessLocked(pid)) {
5929                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5930                skipPendingBroadcastLocked(pid);
5931            }
5932        } else {
5933            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5934        }
5935    }
5936
5937    private final boolean attachApplicationLocked(IApplicationThread thread,
5938            int pid) {
5939
5940        // Find the application record that is being attached...  either via
5941        // the pid if we are running in multiple processes, or just pull the
5942        // next app record if we are emulating process with anonymous threads.
5943        ProcessRecord app;
5944        if (pid != MY_PID && pid >= 0) {
5945            synchronized (mPidsSelfLocked) {
5946                app = mPidsSelfLocked.get(pid);
5947            }
5948        } else {
5949            app = null;
5950        }
5951
5952        if (app == null) {
5953            Slog.w(TAG, "No pending application record for pid " + pid
5954                    + " (IApplicationThread " + thread + "); dropping process");
5955            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5956            if (pid > 0 && pid != MY_PID) {
5957                Process.killProcessQuiet(pid);
5958                //TODO: killProcessGroup(app.info.uid, pid);
5959            } else {
5960                try {
5961                    thread.scheduleExit();
5962                } catch (Exception e) {
5963                    // Ignore exceptions.
5964                }
5965            }
5966            return false;
5967        }
5968
5969        // If this application record is still attached to a previous
5970        // process, clean it up now.
5971        if (app.thread != null) {
5972            handleAppDiedLocked(app, true, true);
5973        }
5974
5975        // Tell the process all about itself.
5976
5977        if (DEBUG_ALL) Slog.v(
5978                TAG, "Binding process pid " + pid + " to record " + app);
5979
5980        final String processName = app.processName;
5981        try {
5982            AppDeathRecipient adr = new AppDeathRecipient(
5983                    app, pid, thread);
5984            thread.asBinder().linkToDeath(adr, 0);
5985            app.deathRecipient = adr;
5986        } catch (RemoteException e) {
5987            app.resetPackageList(mProcessStats);
5988            startProcessLocked(app, "link fail", processName);
5989            return false;
5990        }
5991
5992        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5993
5994        app.makeActive(thread, mProcessStats);
5995        app.curAdj = app.setAdj = -100;
5996        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5997        app.forcingToForeground = null;
5998        updateProcessForegroundLocked(app, false, false);
5999        app.hasShownUi = false;
6000        app.debugging = false;
6001        app.cached = false;
6002        app.killedByAm = false;
6003
6004        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6005
6006        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6007        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6008
6009        if (!normalMode) {
6010            Slog.i(TAG, "Launching preboot mode app: " + app);
6011        }
6012
6013        if (DEBUG_ALL) Slog.v(
6014            TAG, "New app record " + app
6015            + " thread=" + thread.asBinder() + " pid=" + pid);
6016        try {
6017            int testMode = IApplicationThread.DEBUG_OFF;
6018            if (mDebugApp != null && mDebugApp.equals(processName)) {
6019                testMode = mWaitForDebugger
6020                    ? IApplicationThread.DEBUG_WAIT
6021                    : IApplicationThread.DEBUG_ON;
6022                app.debugging = true;
6023                if (mDebugTransient) {
6024                    mDebugApp = mOrigDebugApp;
6025                    mWaitForDebugger = mOrigWaitForDebugger;
6026                }
6027            }
6028            String profileFile = app.instrumentationProfileFile;
6029            ParcelFileDescriptor profileFd = null;
6030            int samplingInterval = 0;
6031            boolean profileAutoStop = false;
6032            if (mProfileApp != null && mProfileApp.equals(processName)) {
6033                mProfileProc = app;
6034                profileFile = mProfileFile;
6035                profileFd = mProfileFd;
6036                samplingInterval = mSamplingInterval;
6037                profileAutoStop = mAutoStopProfiler;
6038            }
6039            boolean enableOpenGlTrace = false;
6040            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6041                enableOpenGlTrace = true;
6042                mOpenGlTraceApp = null;
6043            }
6044            boolean enableTrackAllocation = false;
6045            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6046                enableTrackAllocation = true;
6047                mTrackAllocationApp = null;
6048            }
6049
6050            // If the app is being launched for restore or full backup, set it up specially
6051            boolean isRestrictedBackupMode = false;
6052            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6053                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6054                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6055                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6056            }
6057
6058            ensurePackageDexOpt(app.instrumentationInfo != null
6059                    ? app.instrumentationInfo.packageName
6060                    : app.info.packageName);
6061            if (app.instrumentationClass != null) {
6062                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6063            }
6064            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6065                    + processName + " with config " + mConfiguration);
6066            ApplicationInfo appInfo = app.instrumentationInfo != null
6067                    ? app.instrumentationInfo : app.info;
6068            app.compat = compatibilityInfoForPackageLocked(appInfo);
6069            if (profileFd != null) {
6070                profileFd = profileFd.dup();
6071            }
6072            ProfilerInfo profilerInfo = profileFile == null ? null
6073                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6074            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6075                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6076                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6077                    enableTrackAllocation, isRestrictedBackupMode || !normalMode, app.persistent,
6078                    new Configuration(mConfiguration), app.compat,
6079                    getCommonServicesLocked(app.isolated),
6080                    mCoreSettingsObserver.getCoreSettingsLocked());
6081            updateLruProcessLocked(app, false, null);
6082            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6083        } catch (Exception e) {
6084            // todo: Yikes!  What should we do?  For now we will try to
6085            // start another process, but that could easily get us in
6086            // an infinite loop of restarting processes...
6087            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6088
6089            app.resetPackageList(mProcessStats);
6090            app.unlinkDeathRecipient();
6091            startProcessLocked(app, "bind fail", processName);
6092            return false;
6093        }
6094
6095        // Remove this record from the list of starting applications.
6096        mPersistentStartingProcesses.remove(app);
6097        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6098                "Attach application locked removing on hold: " + app);
6099        mProcessesOnHold.remove(app);
6100
6101        boolean badApp = false;
6102        boolean didSomething = false;
6103
6104        // See if the top visible activity is waiting to run in this process...
6105        if (normalMode) {
6106            try {
6107                if (mStackSupervisor.attachApplicationLocked(app)) {
6108                    didSomething = true;
6109                }
6110            } catch (Exception e) {
6111                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6112                badApp = true;
6113            }
6114        }
6115
6116        // Find any services that should be running in this process...
6117        if (!badApp) {
6118            try {
6119                didSomething |= mServices.attachApplicationLocked(app, processName);
6120            } catch (Exception e) {
6121                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6122                badApp = true;
6123            }
6124        }
6125
6126        // Check if a next-broadcast receiver is in this process...
6127        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6128            try {
6129                didSomething |= sendPendingBroadcastsLocked(app);
6130            } catch (Exception e) {
6131                // If the app died trying to launch the receiver we declare it 'bad'
6132                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6133                badApp = true;
6134            }
6135        }
6136
6137        // Check whether the next backup agent is in this process...
6138        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6139            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6140                    "New app is backup target, launching agent for " + app);
6141            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6142            try {
6143                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6144                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6145                        mBackupTarget.backupMode);
6146            } catch (Exception e) {
6147                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6148                badApp = true;
6149            }
6150        }
6151
6152        if (badApp) {
6153            app.kill("error during init", true);
6154            handleAppDiedLocked(app, false, true);
6155            return false;
6156        }
6157
6158        if (!didSomething) {
6159            updateOomAdjLocked();
6160        }
6161
6162        return true;
6163    }
6164
6165    @Override
6166    public final void attachApplication(IApplicationThread thread) {
6167        synchronized (this) {
6168            int callingPid = Binder.getCallingPid();
6169            final long origId = Binder.clearCallingIdentity();
6170            attachApplicationLocked(thread, callingPid);
6171            Binder.restoreCallingIdentity(origId);
6172        }
6173    }
6174
6175    @Override
6176    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6177        final long origId = Binder.clearCallingIdentity();
6178        synchronized (this) {
6179            ActivityStack stack = ActivityRecord.getStackLocked(token);
6180            if (stack != null) {
6181                ActivityRecord r =
6182                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6183                if (stopProfiling) {
6184                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6185                        try {
6186                            mProfileFd.close();
6187                        } catch (IOException e) {
6188                        }
6189                        clearProfilerLocked();
6190                    }
6191                }
6192            }
6193        }
6194        Binder.restoreCallingIdentity(origId);
6195    }
6196
6197    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6198        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6199                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6200    }
6201
6202    void enableScreenAfterBoot() {
6203        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6204                SystemClock.uptimeMillis());
6205        mWindowManager.enableScreenAfterBoot();
6206
6207        synchronized (this) {
6208            updateEventDispatchingLocked();
6209        }
6210    }
6211
6212    @Override
6213    public void showBootMessage(final CharSequence msg, final boolean always) {
6214        if (Binder.getCallingUid() != Process.myUid()) {
6215            // These days only the core system can call this, so apps can't get in
6216            // the way of what we show about running them.
6217        }
6218        mWindowManager.showBootMessage(msg, always);
6219    }
6220
6221    @Override
6222    public void keyguardWaitingForActivityDrawn() {
6223        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6224        final long token = Binder.clearCallingIdentity();
6225        try {
6226            synchronized (this) {
6227                if (DEBUG_LOCKSCREEN) logLockScreen("");
6228                mWindowManager.keyguardWaitingForActivityDrawn();
6229                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6230                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6231                    updateSleepIfNeededLocked();
6232                }
6233            }
6234        } finally {
6235            Binder.restoreCallingIdentity(token);
6236        }
6237    }
6238
6239    @Override
6240    public void keyguardGoingAway(boolean disableWindowAnimations,
6241            boolean keyguardGoingToNotificationShade) {
6242        enforceNotIsolatedCaller("keyguardGoingAway");
6243        final long token = Binder.clearCallingIdentity();
6244        try {
6245            synchronized (this) {
6246                if (DEBUG_LOCKSCREEN) logLockScreen("");
6247                mWindowManager.keyguardGoingAway(disableWindowAnimations,
6248                        keyguardGoingToNotificationShade);
6249                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6250                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6251                    updateSleepIfNeededLocked();
6252                }
6253            }
6254        } finally {
6255            Binder.restoreCallingIdentity(token);
6256        }
6257    }
6258
6259    final void finishBooting() {
6260        synchronized (this) {
6261            if (!mBootAnimationComplete) {
6262                mCallFinishBooting = true;
6263                return;
6264            }
6265            mCallFinishBooting = false;
6266        }
6267
6268        ArraySet<String> completedIsas = new ArraySet<String>();
6269        for (String abi : Build.SUPPORTED_ABIS) {
6270            Process.establishZygoteConnectionForAbi(abi);
6271            final String instructionSet = VMRuntime.getInstructionSet(abi);
6272            if (!completedIsas.contains(instructionSet)) {
6273                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6274                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6275                }
6276                completedIsas.add(instructionSet);
6277            }
6278        }
6279
6280        IntentFilter pkgFilter = new IntentFilter();
6281        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6282        pkgFilter.addDataScheme("package");
6283        mContext.registerReceiver(new BroadcastReceiver() {
6284            @Override
6285            public void onReceive(Context context, Intent intent) {
6286                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6287                if (pkgs != null) {
6288                    for (String pkg : pkgs) {
6289                        synchronized (ActivityManagerService.this) {
6290                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6291                                    0, "query restart")) {
6292                                setResultCode(Activity.RESULT_OK);
6293                                return;
6294                            }
6295                        }
6296                    }
6297                }
6298            }
6299        }, pkgFilter);
6300
6301        IntentFilter dumpheapFilter = new IntentFilter();
6302        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6303        mContext.registerReceiver(new BroadcastReceiver() {
6304            @Override
6305            public void onReceive(Context context, Intent intent) {
6306                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6307                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6308                } else {
6309                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6310                }
6311            }
6312        }, dumpheapFilter);
6313
6314        // Let system services know.
6315        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6316
6317        synchronized (this) {
6318            // Ensure that any processes we had put on hold are now started
6319            // up.
6320            final int NP = mProcessesOnHold.size();
6321            if (NP > 0) {
6322                ArrayList<ProcessRecord> procs =
6323                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6324                for (int ip=0; ip<NP; ip++) {
6325                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6326                            + procs.get(ip));
6327                    startProcessLocked(procs.get(ip), "on-hold", null);
6328                }
6329            }
6330
6331            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6332                // Start looking for apps that are abusing wake locks.
6333                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6334                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6335                // Tell anyone interested that we are done booting!
6336                SystemProperties.set("sys.boot_completed", "1");
6337
6338                // And trigger dev.bootcomplete if we are not showing encryption progress
6339                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6340                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6341                    SystemProperties.set("dev.bootcomplete", "1");
6342                }
6343                for (int i=0; i<mStartedUsers.size(); i++) {
6344                    UserState uss = mStartedUsers.valueAt(i);
6345                    if (uss.mState == UserState.STATE_BOOTING) {
6346                        uss.mState = UserState.STATE_RUNNING;
6347                        final int userId = mStartedUsers.keyAt(i);
6348                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6349                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6350                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6351                        broadcastIntentLocked(null, null, intent, null,
6352                                new IIntentReceiver.Stub() {
6353                                    @Override
6354                                    public void performReceive(Intent intent, int resultCode,
6355                                            String data, Bundle extras, boolean ordered,
6356                                            boolean sticky, int sendingUser) {
6357                                        synchronized (ActivityManagerService.this) {
6358                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6359                                                    true, false);
6360                                        }
6361                                    }
6362                                },
6363                                0, null, null,
6364                                new String[] {android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
6365                                AppOpsManager.OP_NONE, null, true, false,
6366                                MY_PID, Process.SYSTEM_UID, userId);
6367                    }
6368                }
6369                scheduleStartProfilesLocked();
6370            }
6371        }
6372    }
6373
6374    @Override
6375    public void bootAnimationComplete() {
6376        final boolean callFinishBooting;
6377        synchronized (this) {
6378            callFinishBooting = mCallFinishBooting;
6379            mBootAnimationComplete = true;
6380        }
6381        if (callFinishBooting) {
6382            finishBooting();
6383        }
6384    }
6385
6386    final void ensureBootCompleted() {
6387        boolean booting;
6388        boolean enableScreen;
6389        synchronized (this) {
6390            booting = mBooting;
6391            mBooting = false;
6392            enableScreen = !mBooted;
6393            mBooted = true;
6394        }
6395
6396        if (booting) {
6397            finishBooting();
6398        }
6399
6400        if (enableScreen) {
6401            enableScreenAfterBoot();
6402        }
6403    }
6404
6405    @Override
6406    public final void activityResumed(IBinder token) {
6407        final long origId = Binder.clearCallingIdentity();
6408        synchronized(this) {
6409            ActivityStack stack = ActivityRecord.getStackLocked(token);
6410            if (stack != null) {
6411                ActivityRecord.activityResumedLocked(token);
6412            }
6413        }
6414        Binder.restoreCallingIdentity(origId);
6415    }
6416
6417    @Override
6418    public final void activityPaused(IBinder token) {
6419        final long origId = Binder.clearCallingIdentity();
6420        synchronized(this) {
6421            ActivityStack stack = ActivityRecord.getStackLocked(token);
6422            if (stack != null) {
6423                stack.activityPausedLocked(token, false);
6424            }
6425        }
6426        Binder.restoreCallingIdentity(origId);
6427    }
6428
6429    @Override
6430    public final void activityStopped(IBinder token, Bundle icicle,
6431            PersistableBundle persistentState, CharSequence description) {
6432        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6433
6434        // Refuse possible leaked file descriptors
6435        if (icicle != null && icicle.hasFileDescriptors()) {
6436            throw new IllegalArgumentException("File descriptors passed in Bundle");
6437        }
6438
6439        final long origId = Binder.clearCallingIdentity();
6440
6441        synchronized (this) {
6442            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6443            if (r != null) {
6444                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6445            }
6446        }
6447
6448        trimApplications();
6449
6450        Binder.restoreCallingIdentity(origId);
6451    }
6452
6453    @Override
6454    public final void activityDestroyed(IBinder token) {
6455        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6456        synchronized (this) {
6457            ActivityStack stack = ActivityRecord.getStackLocked(token);
6458            if (stack != null) {
6459                stack.activityDestroyedLocked(token, "activityDestroyed");
6460            }
6461        }
6462    }
6463
6464    @Override
6465    public final void backgroundResourcesReleased(IBinder token) {
6466        final long origId = Binder.clearCallingIdentity();
6467        try {
6468            synchronized (this) {
6469                ActivityStack stack = ActivityRecord.getStackLocked(token);
6470                if (stack != null) {
6471                    stack.backgroundResourcesReleased();
6472                }
6473            }
6474        } finally {
6475            Binder.restoreCallingIdentity(origId);
6476        }
6477    }
6478
6479    @Override
6480    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6481        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6482    }
6483
6484    @Override
6485    public final void notifyEnterAnimationComplete(IBinder token) {
6486        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6487    }
6488
6489    @Override
6490    public String getCallingPackage(IBinder token) {
6491        synchronized (this) {
6492            ActivityRecord r = getCallingRecordLocked(token);
6493            return r != null ? r.info.packageName : null;
6494        }
6495    }
6496
6497    @Override
6498    public ComponentName getCallingActivity(IBinder token) {
6499        synchronized (this) {
6500            ActivityRecord r = getCallingRecordLocked(token);
6501            return r != null ? r.intent.getComponent() : null;
6502        }
6503    }
6504
6505    private ActivityRecord getCallingRecordLocked(IBinder token) {
6506        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6507        if (r == null) {
6508            return null;
6509        }
6510        return r.resultTo;
6511    }
6512
6513    @Override
6514    public ComponentName getActivityClassForToken(IBinder token) {
6515        synchronized(this) {
6516            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6517            if (r == null) {
6518                return null;
6519            }
6520            return r.intent.getComponent();
6521        }
6522    }
6523
6524    @Override
6525    public String getPackageForToken(IBinder token) {
6526        synchronized(this) {
6527            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6528            if (r == null) {
6529                return null;
6530            }
6531            return r.packageName;
6532        }
6533    }
6534
6535    @Override
6536    public IIntentSender getIntentSender(int type,
6537            String packageName, IBinder token, String resultWho,
6538            int requestCode, Intent[] intents, String[] resolvedTypes,
6539            int flags, Bundle options, int userId) {
6540        enforceNotIsolatedCaller("getIntentSender");
6541        // Refuse possible leaked file descriptors
6542        if (intents != null) {
6543            if (intents.length < 1) {
6544                throw new IllegalArgumentException("Intents array length must be >= 1");
6545            }
6546            for (int i=0; i<intents.length; i++) {
6547                Intent intent = intents[i];
6548                if (intent != null) {
6549                    if (intent.hasFileDescriptors()) {
6550                        throw new IllegalArgumentException("File descriptors passed in Intent");
6551                    }
6552                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6553                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6554                        throw new IllegalArgumentException(
6555                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6556                    }
6557                    intents[i] = new Intent(intent);
6558                }
6559            }
6560            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6561                throw new IllegalArgumentException(
6562                        "Intent array length does not match resolvedTypes length");
6563            }
6564        }
6565        if (options != null) {
6566            if (options.hasFileDescriptors()) {
6567                throw new IllegalArgumentException("File descriptors passed in options");
6568            }
6569        }
6570
6571        synchronized(this) {
6572            int callingUid = Binder.getCallingUid();
6573            int origUserId = userId;
6574            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6575                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6576                    ALLOW_NON_FULL, "getIntentSender", null);
6577            if (origUserId == UserHandle.USER_CURRENT) {
6578                // We don't want to evaluate this until the pending intent is
6579                // actually executed.  However, we do want to always do the
6580                // security checking for it above.
6581                userId = UserHandle.USER_CURRENT;
6582            }
6583            try {
6584                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6585                    int uid = AppGlobals.getPackageManager()
6586                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6587                    if (!UserHandle.isSameApp(callingUid, uid)) {
6588                        String msg = "Permission Denial: getIntentSender() from pid="
6589                            + Binder.getCallingPid()
6590                            + ", uid=" + Binder.getCallingUid()
6591                            + ", (need uid=" + uid + ")"
6592                            + " is not allowed to send as package " + packageName;
6593                        Slog.w(TAG, msg);
6594                        throw new SecurityException(msg);
6595                    }
6596                }
6597
6598                return getIntentSenderLocked(type, packageName, callingUid, userId,
6599                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6600
6601            } catch (RemoteException e) {
6602                throw new SecurityException(e);
6603            }
6604        }
6605    }
6606
6607    IIntentSender getIntentSenderLocked(int type, String packageName,
6608            int callingUid, int userId, IBinder token, String resultWho,
6609            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6610            Bundle options) {
6611        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6612        ActivityRecord activity = null;
6613        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6614            activity = ActivityRecord.isInStackLocked(token);
6615            if (activity == null) {
6616                return null;
6617            }
6618            if (activity.finishing) {
6619                return null;
6620            }
6621        }
6622
6623        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6624        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6625        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6626        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6627                |PendingIntent.FLAG_UPDATE_CURRENT);
6628
6629        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6630                type, packageName, activity, resultWho,
6631                requestCode, intents, resolvedTypes, flags, options, userId);
6632        WeakReference<PendingIntentRecord> ref;
6633        ref = mIntentSenderRecords.get(key);
6634        PendingIntentRecord rec = ref != null ? ref.get() : null;
6635        if (rec != null) {
6636            if (!cancelCurrent) {
6637                if (updateCurrent) {
6638                    if (rec.key.requestIntent != null) {
6639                        rec.key.requestIntent.replaceExtras(intents != null ?
6640                                intents[intents.length - 1] : null);
6641                    }
6642                    if (intents != null) {
6643                        intents[intents.length-1] = rec.key.requestIntent;
6644                        rec.key.allIntents = intents;
6645                        rec.key.allResolvedTypes = resolvedTypes;
6646                    } else {
6647                        rec.key.allIntents = null;
6648                        rec.key.allResolvedTypes = null;
6649                    }
6650                }
6651                return rec;
6652            }
6653            rec.canceled = true;
6654            mIntentSenderRecords.remove(key);
6655        }
6656        if (noCreate) {
6657            return rec;
6658        }
6659        rec = new PendingIntentRecord(this, key, callingUid);
6660        mIntentSenderRecords.put(key, rec.ref);
6661        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6662            if (activity.pendingResults == null) {
6663                activity.pendingResults
6664                        = new HashSet<WeakReference<PendingIntentRecord>>();
6665            }
6666            activity.pendingResults.add(rec.ref);
6667        }
6668        return rec;
6669    }
6670
6671    @Override
6672    public void cancelIntentSender(IIntentSender sender) {
6673        if (!(sender instanceof PendingIntentRecord)) {
6674            return;
6675        }
6676        synchronized(this) {
6677            PendingIntentRecord rec = (PendingIntentRecord)sender;
6678            try {
6679                int uid = AppGlobals.getPackageManager()
6680                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6681                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6682                    String msg = "Permission Denial: cancelIntentSender() from pid="
6683                        + Binder.getCallingPid()
6684                        + ", uid=" + Binder.getCallingUid()
6685                        + " is not allowed to cancel packges "
6686                        + rec.key.packageName;
6687                    Slog.w(TAG, msg);
6688                    throw new SecurityException(msg);
6689                }
6690            } catch (RemoteException e) {
6691                throw new SecurityException(e);
6692            }
6693            cancelIntentSenderLocked(rec, true);
6694        }
6695    }
6696
6697    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6698        rec.canceled = true;
6699        mIntentSenderRecords.remove(rec.key);
6700        if (cleanActivity && rec.key.activity != null) {
6701            rec.key.activity.pendingResults.remove(rec.ref);
6702        }
6703    }
6704
6705    @Override
6706    public String getPackageForIntentSender(IIntentSender pendingResult) {
6707        if (!(pendingResult instanceof PendingIntentRecord)) {
6708            return null;
6709        }
6710        try {
6711            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6712            return res.key.packageName;
6713        } catch (ClassCastException e) {
6714        }
6715        return null;
6716    }
6717
6718    @Override
6719    public int getUidForIntentSender(IIntentSender sender) {
6720        if (sender instanceof PendingIntentRecord) {
6721            try {
6722                PendingIntentRecord res = (PendingIntentRecord)sender;
6723                return res.uid;
6724            } catch (ClassCastException e) {
6725            }
6726        }
6727        return -1;
6728    }
6729
6730    @Override
6731    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6732        if (!(pendingResult instanceof PendingIntentRecord)) {
6733            return false;
6734        }
6735        try {
6736            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6737            if (res.key.allIntents == null) {
6738                return false;
6739            }
6740            for (int i=0; i<res.key.allIntents.length; i++) {
6741                Intent intent = res.key.allIntents[i];
6742                if (intent.getPackage() != null && intent.getComponent() != null) {
6743                    return false;
6744                }
6745            }
6746            return true;
6747        } catch (ClassCastException e) {
6748        }
6749        return false;
6750    }
6751
6752    @Override
6753    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6754        if (!(pendingResult instanceof PendingIntentRecord)) {
6755            return false;
6756        }
6757        try {
6758            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6759            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6760                return true;
6761            }
6762            return false;
6763        } catch (ClassCastException e) {
6764        }
6765        return false;
6766    }
6767
6768    @Override
6769    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6770        if (!(pendingResult instanceof PendingIntentRecord)) {
6771            return null;
6772        }
6773        try {
6774            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6775            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6776        } catch (ClassCastException e) {
6777        }
6778        return null;
6779    }
6780
6781    @Override
6782    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6783        if (!(pendingResult instanceof PendingIntentRecord)) {
6784            return null;
6785        }
6786        try {
6787            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6788            synchronized (this) {
6789                return getTagForIntentSenderLocked(res, prefix);
6790            }
6791        } catch (ClassCastException e) {
6792        }
6793        return null;
6794    }
6795
6796    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
6797        final Intent intent = res.key.requestIntent;
6798        if (intent != null) {
6799            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6800                    || res.lastTagPrefix.equals(prefix))) {
6801                return res.lastTag;
6802            }
6803            res.lastTagPrefix = prefix;
6804            final StringBuilder sb = new StringBuilder(128);
6805            if (prefix != null) {
6806                sb.append(prefix);
6807            }
6808            if (intent.getAction() != null) {
6809                sb.append(intent.getAction());
6810            } else if (intent.getComponent() != null) {
6811                intent.getComponent().appendShortString(sb);
6812            } else {
6813                sb.append("?");
6814            }
6815            return res.lastTag = sb.toString();
6816        }
6817        return null;
6818    }
6819
6820    @Override
6821    public void setProcessLimit(int max) {
6822        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6823                "setProcessLimit()");
6824        synchronized (this) {
6825            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6826            mProcessLimitOverride = max;
6827        }
6828        trimApplications();
6829    }
6830
6831    @Override
6832    public int getProcessLimit() {
6833        synchronized (this) {
6834            return mProcessLimitOverride;
6835        }
6836    }
6837
6838    void foregroundTokenDied(ForegroundToken token) {
6839        synchronized (ActivityManagerService.this) {
6840            synchronized (mPidsSelfLocked) {
6841                ForegroundToken cur
6842                    = mForegroundProcesses.get(token.pid);
6843                if (cur != token) {
6844                    return;
6845                }
6846                mForegroundProcesses.remove(token.pid);
6847                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6848                if (pr == null) {
6849                    return;
6850                }
6851                pr.forcingToForeground = null;
6852                updateProcessForegroundLocked(pr, false, false);
6853            }
6854            updateOomAdjLocked();
6855        }
6856    }
6857
6858    @Override
6859    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6860        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6861                "setProcessForeground()");
6862        synchronized(this) {
6863            boolean changed = false;
6864
6865            synchronized (mPidsSelfLocked) {
6866                ProcessRecord pr = mPidsSelfLocked.get(pid);
6867                if (pr == null && isForeground) {
6868                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6869                    return;
6870                }
6871                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6872                if (oldToken != null) {
6873                    oldToken.token.unlinkToDeath(oldToken, 0);
6874                    mForegroundProcesses.remove(pid);
6875                    if (pr != null) {
6876                        pr.forcingToForeground = null;
6877                    }
6878                    changed = true;
6879                }
6880                if (isForeground && token != null) {
6881                    ForegroundToken newToken = new ForegroundToken() {
6882                        @Override
6883                        public void binderDied() {
6884                            foregroundTokenDied(this);
6885                        }
6886                    };
6887                    newToken.pid = pid;
6888                    newToken.token = token;
6889                    try {
6890                        token.linkToDeath(newToken, 0);
6891                        mForegroundProcesses.put(pid, newToken);
6892                        pr.forcingToForeground = token;
6893                        changed = true;
6894                    } catch (RemoteException e) {
6895                        // If the process died while doing this, we will later
6896                        // do the cleanup with the process death link.
6897                    }
6898                }
6899            }
6900
6901            if (changed) {
6902                updateOomAdjLocked();
6903            }
6904        }
6905    }
6906
6907    // =========================================================
6908    // PROCESS INFO
6909    // =========================================================
6910
6911    static class ProcessInfoService extends IProcessInfoService.Stub {
6912        final ActivityManagerService mActivityManagerService;
6913        ProcessInfoService(ActivityManagerService activityManagerService) {
6914            mActivityManagerService = activityManagerService;
6915        }
6916
6917        @Override
6918        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
6919            mActivityManagerService.getProcessStatesForPIDs(/*in*/ pids, /*out*/ states);
6920        }
6921    }
6922
6923    /**
6924     * For each PID in the given input array, write the current process state
6925     * for that process into the output array, or -1 to indicate that no
6926     * process with the given PID exists.
6927     */
6928    public void getProcessStatesForPIDs(/*in*/ int[] pids, /*out*/ int[] states) {
6929        if (pids == null) {
6930            throw new NullPointerException("pids");
6931        } else if (states == null) {
6932            throw new NullPointerException("states");
6933        } else if (pids.length != states.length) {
6934            throw new IllegalArgumentException("input and output arrays have different lengths!");
6935        }
6936
6937        synchronized (mPidsSelfLocked) {
6938            for (int i = 0; i < pids.length; i++) {
6939                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
6940                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
6941                        pr.curProcState;
6942            }
6943        }
6944    }
6945
6946    // =========================================================
6947    // PERMISSIONS
6948    // =========================================================
6949
6950    static class PermissionController extends IPermissionController.Stub {
6951        ActivityManagerService mActivityManagerService;
6952        PermissionController(ActivityManagerService activityManagerService) {
6953            mActivityManagerService = activityManagerService;
6954        }
6955
6956        @Override
6957        public boolean checkPermission(String permission, int pid, int uid) {
6958            return mActivityManagerService.checkPermission(permission, pid,
6959                    uid) == PackageManager.PERMISSION_GRANTED;
6960        }
6961
6962        @Override
6963        public String[] getPackagesForUid(int uid) {
6964            return mActivityManagerService.mContext.getPackageManager()
6965                    .getPackagesForUid(uid);
6966        }
6967
6968        @Override
6969        public boolean isRuntimePermission(String permission) {
6970            try {
6971                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
6972                        .getPermissionInfo(permission, 0);
6973                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
6974            } catch (NameNotFoundException nnfe) {
6975                Slog.e(TAG, "No such permission: "+ permission, nnfe);
6976            }
6977            return false;
6978        }
6979    }
6980
6981    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6982        @Override
6983        public int checkComponentPermission(String permission, int pid, int uid,
6984                int owningUid, boolean exported) {
6985            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6986                    owningUid, exported);
6987        }
6988
6989        @Override
6990        public Object getAMSLock() {
6991            return ActivityManagerService.this;
6992        }
6993    }
6994
6995    /**
6996     * This can be called with or without the global lock held.
6997     */
6998    int checkComponentPermission(String permission, int pid, int uid,
6999            int owningUid, boolean exported) {
7000        if (pid == MY_PID) {
7001            return PackageManager.PERMISSION_GRANTED;
7002        }
7003        return ActivityManager.checkComponentPermission(permission, uid,
7004                owningUid, exported);
7005    }
7006
7007    /**
7008     * As the only public entry point for permissions checking, this method
7009     * can enforce the semantic that requesting a check on a null global
7010     * permission is automatically denied.  (Internally a null permission
7011     * string is used when calling {@link #checkComponentPermission} in cases
7012     * when only uid-based security is needed.)
7013     *
7014     * This can be called with or without the global lock held.
7015     */
7016    @Override
7017    public int checkPermission(String permission, int pid, int uid) {
7018        if (permission == null) {
7019            return PackageManager.PERMISSION_DENIED;
7020        }
7021        return checkComponentPermission(permission, pid, uid, -1, true);
7022    }
7023
7024    @Override
7025    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7026        if (permission == null) {
7027            return PackageManager.PERMISSION_DENIED;
7028        }
7029
7030        // We might be performing an operation on behalf of an indirect binder
7031        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7032        // client identity accordingly before proceeding.
7033        Identity tlsIdentity = sCallerIdentity.get();
7034        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7035            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7036                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7037            uid = tlsIdentity.uid;
7038            pid = tlsIdentity.pid;
7039        }
7040
7041        return checkComponentPermission(permission, pid, uid, -1, true);
7042    }
7043
7044    /**
7045     * Binder IPC calls go through the public entry point.
7046     * This can be called with or without the global lock held.
7047     */
7048    int checkCallingPermission(String permission) {
7049        return checkPermission(permission,
7050                Binder.getCallingPid(),
7051                UserHandle.getAppId(Binder.getCallingUid()));
7052    }
7053
7054    /**
7055     * This can be called with or without the global lock held.
7056     */
7057    void enforceCallingPermission(String permission, String func) {
7058        if (checkCallingPermission(permission)
7059                == PackageManager.PERMISSION_GRANTED) {
7060            return;
7061        }
7062
7063        String msg = "Permission Denial: " + func + " from pid="
7064                + Binder.getCallingPid()
7065                + ", uid=" + Binder.getCallingUid()
7066                + " requires " + permission;
7067        Slog.w(TAG, msg);
7068        throw new SecurityException(msg);
7069    }
7070
7071    /**
7072     * Determine if UID is holding permissions required to access {@link Uri} in
7073     * the given {@link ProviderInfo}. Final permission checking is always done
7074     * in {@link ContentProvider}.
7075     */
7076    private final boolean checkHoldingPermissionsLocked(
7077            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7078        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7079                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7080        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7081            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7082                    != PERMISSION_GRANTED) {
7083                return false;
7084            }
7085        }
7086        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7087    }
7088
7089    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7090            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7091        if (pi.applicationInfo.uid == uid) {
7092            return true;
7093        } else if (!pi.exported) {
7094            return false;
7095        }
7096
7097        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7098        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7099        try {
7100            // check if target holds top-level <provider> permissions
7101            if (!readMet && pi.readPermission != null && considerUidPermissions
7102                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7103                readMet = true;
7104            }
7105            if (!writeMet && pi.writePermission != null && considerUidPermissions
7106                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7107                writeMet = true;
7108            }
7109
7110            // track if unprotected read/write is allowed; any denied
7111            // <path-permission> below removes this ability
7112            boolean allowDefaultRead = pi.readPermission == null;
7113            boolean allowDefaultWrite = pi.writePermission == null;
7114
7115            // check if target holds any <path-permission> that match uri
7116            final PathPermission[] pps = pi.pathPermissions;
7117            if (pps != null) {
7118                final String path = grantUri.uri.getPath();
7119                int i = pps.length;
7120                while (i > 0 && (!readMet || !writeMet)) {
7121                    i--;
7122                    PathPermission pp = pps[i];
7123                    if (pp.match(path)) {
7124                        if (!readMet) {
7125                            final String pprperm = pp.getReadPermission();
7126                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7127                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7128                                    + ": match=" + pp.match(path)
7129                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7130                            if (pprperm != null) {
7131                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7132                                        == PERMISSION_GRANTED) {
7133                                    readMet = true;
7134                                } else {
7135                                    allowDefaultRead = false;
7136                                }
7137                            }
7138                        }
7139                        if (!writeMet) {
7140                            final String ppwperm = pp.getWritePermission();
7141                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7142                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7143                                    + ": match=" + pp.match(path)
7144                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7145                            if (ppwperm != null) {
7146                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7147                                        == PERMISSION_GRANTED) {
7148                                    writeMet = true;
7149                                } else {
7150                                    allowDefaultWrite = false;
7151                                }
7152                            }
7153                        }
7154                    }
7155                }
7156            }
7157
7158            // grant unprotected <provider> read/write, if not blocked by
7159            // <path-permission> above
7160            if (allowDefaultRead) readMet = true;
7161            if (allowDefaultWrite) writeMet = true;
7162
7163        } catch (RemoteException e) {
7164            return false;
7165        }
7166
7167        return readMet && writeMet;
7168    }
7169
7170    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7171        ProviderInfo pi = null;
7172        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7173        if (cpr != null) {
7174            pi = cpr.info;
7175        } else {
7176            try {
7177                pi = AppGlobals.getPackageManager().resolveContentProvider(
7178                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7179            } catch (RemoteException ex) {
7180            }
7181        }
7182        return pi;
7183    }
7184
7185    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7186        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7187        if (targetUris != null) {
7188            return targetUris.get(grantUri);
7189        }
7190        return null;
7191    }
7192
7193    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7194            String targetPkg, int targetUid, GrantUri grantUri) {
7195        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7196        if (targetUris == null) {
7197            targetUris = Maps.newArrayMap();
7198            mGrantedUriPermissions.put(targetUid, targetUris);
7199        }
7200
7201        UriPermission perm = targetUris.get(grantUri);
7202        if (perm == null) {
7203            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7204            targetUris.put(grantUri, perm);
7205        }
7206
7207        return perm;
7208    }
7209
7210    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7211            final int modeFlags) {
7212        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7213        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7214                : UriPermission.STRENGTH_OWNED;
7215
7216        // Root gets to do everything.
7217        if (uid == 0) {
7218            return true;
7219        }
7220
7221        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7222        if (perms == null) return false;
7223
7224        // First look for exact match
7225        final UriPermission exactPerm = perms.get(grantUri);
7226        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7227            return true;
7228        }
7229
7230        // No exact match, look for prefixes
7231        final int N = perms.size();
7232        for (int i = 0; i < N; i++) {
7233            final UriPermission perm = perms.valueAt(i);
7234            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7235                    && perm.getStrength(modeFlags) >= minStrength) {
7236                return true;
7237            }
7238        }
7239
7240        return false;
7241    }
7242
7243    /**
7244     * @param uri This uri must NOT contain an embedded userId.
7245     * @param userId The userId in which the uri is to be resolved.
7246     */
7247    @Override
7248    public int checkUriPermission(Uri uri, int pid, int uid,
7249            final int modeFlags, int userId, IBinder callerToken) {
7250        enforceNotIsolatedCaller("checkUriPermission");
7251
7252        // Another redirected-binder-call permissions check as in
7253        // {@link checkPermissionWithToken}.
7254        Identity tlsIdentity = sCallerIdentity.get();
7255        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7256            uid = tlsIdentity.uid;
7257            pid = tlsIdentity.pid;
7258        }
7259
7260        // Our own process gets to do everything.
7261        if (pid == MY_PID) {
7262            return PackageManager.PERMISSION_GRANTED;
7263        }
7264        synchronized (this) {
7265            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7266                    ? PackageManager.PERMISSION_GRANTED
7267                    : PackageManager.PERMISSION_DENIED;
7268        }
7269    }
7270
7271    /**
7272     * Check if the targetPkg can be granted permission to access uri by
7273     * the callingUid using the given modeFlags.  Throws a security exception
7274     * if callingUid is not allowed to do this.  Returns the uid of the target
7275     * if the URI permission grant should be performed; returns -1 if it is not
7276     * needed (for example targetPkg already has permission to access the URI).
7277     * If you already know the uid of the target, you can supply it in
7278     * lastTargetUid else set that to -1.
7279     */
7280    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7281            final int modeFlags, int lastTargetUid) {
7282        if (!Intent.isAccessUriMode(modeFlags)) {
7283            return -1;
7284        }
7285
7286        if (targetPkg != null) {
7287            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7288                    "Checking grant " + targetPkg + " permission to " + grantUri);
7289        }
7290
7291        final IPackageManager pm = AppGlobals.getPackageManager();
7292
7293        // If this is not a content: uri, we can't do anything with it.
7294        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7295            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7296                    "Can't grant URI permission for non-content URI: " + grantUri);
7297            return -1;
7298        }
7299
7300        final String authority = grantUri.uri.getAuthority();
7301        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7302        if (pi == null) {
7303            Slog.w(TAG, "No content provider found for permission check: " +
7304                    grantUri.uri.toSafeString());
7305            return -1;
7306        }
7307
7308        int targetUid = lastTargetUid;
7309        if (targetUid < 0 && targetPkg != null) {
7310            try {
7311                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7312                if (targetUid < 0) {
7313                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7314                            "Can't grant URI permission no uid for: " + targetPkg);
7315                    return -1;
7316                }
7317            } catch (RemoteException ex) {
7318                return -1;
7319            }
7320        }
7321
7322        if (targetUid >= 0) {
7323            // First...  does the target actually need this permission?
7324            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7325                // No need to grant the target this permission.
7326                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7327                        "Target " + targetPkg + " already has full permission to " + grantUri);
7328                return -1;
7329            }
7330        } else {
7331            // First...  there is no target package, so can anyone access it?
7332            boolean allowed = pi.exported;
7333            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7334                if (pi.readPermission != null) {
7335                    allowed = false;
7336                }
7337            }
7338            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7339                if (pi.writePermission != null) {
7340                    allowed = false;
7341                }
7342            }
7343            if (allowed) {
7344                return -1;
7345            }
7346        }
7347
7348        /* There is a special cross user grant if:
7349         * - The target is on another user.
7350         * - Apps on the current user can access the uri without any uid permissions.
7351         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7352         * grant uri permissions.
7353         */
7354        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7355                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7356                modeFlags, false /*without considering the uid permissions*/);
7357
7358        // Second...  is the provider allowing granting of URI permissions?
7359        if (!specialCrossUserGrant) {
7360            if (!pi.grantUriPermissions) {
7361                throw new SecurityException("Provider " + pi.packageName
7362                        + "/" + pi.name
7363                        + " does not allow granting of Uri permissions (uri "
7364                        + grantUri + ")");
7365            }
7366            if (pi.uriPermissionPatterns != null) {
7367                final int N = pi.uriPermissionPatterns.length;
7368                boolean allowed = false;
7369                for (int i=0; i<N; i++) {
7370                    if (pi.uriPermissionPatterns[i] != null
7371                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7372                        allowed = true;
7373                        break;
7374                    }
7375                }
7376                if (!allowed) {
7377                    throw new SecurityException("Provider " + pi.packageName
7378                            + "/" + pi.name
7379                            + " does not allow granting of permission to path of Uri "
7380                            + grantUri);
7381                }
7382            }
7383        }
7384
7385        // Third...  does the caller itself have permission to access
7386        // this uri?
7387        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7388            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7389                // Require they hold a strong enough Uri permission
7390                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7391                    throw new SecurityException("Uid " + callingUid
7392                            + " does not have permission to uri " + grantUri);
7393                }
7394            }
7395        }
7396        return targetUid;
7397    }
7398
7399    /**
7400     * @param uri This uri must NOT contain an embedded userId.
7401     * @param userId The userId in which the uri is to be resolved.
7402     */
7403    @Override
7404    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7405            final int modeFlags, int userId) {
7406        enforceNotIsolatedCaller("checkGrantUriPermission");
7407        synchronized(this) {
7408            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7409                    new GrantUri(userId, uri, false), modeFlags, -1);
7410        }
7411    }
7412
7413    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7414            final int modeFlags, UriPermissionOwner owner) {
7415        if (!Intent.isAccessUriMode(modeFlags)) {
7416            return;
7417        }
7418
7419        // So here we are: the caller has the assumed permission
7420        // to the uri, and the target doesn't.  Let's now give this to
7421        // the target.
7422
7423        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7424                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7425
7426        final String authority = grantUri.uri.getAuthority();
7427        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7428        if (pi == null) {
7429            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7430            return;
7431        }
7432
7433        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7434            grantUri.prefix = true;
7435        }
7436        final UriPermission perm = findOrCreateUriPermissionLocked(
7437                pi.packageName, targetPkg, targetUid, grantUri);
7438        perm.grantModes(modeFlags, owner);
7439    }
7440
7441    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7442            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7443        if (targetPkg == null) {
7444            throw new NullPointerException("targetPkg");
7445        }
7446        int targetUid;
7447        final IPackageManager pm = AppGlobals.getPackageManager();
7448        try {
7449            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7450        } catch (RemoteException ex) {
7451            return;
7452        }
7453
7454        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7455                targetUid);
7456        if (targetUid < 0) {
7457            return;
7458        }
7459
7460        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7461                owner);
7462    }
7463
7464    static class NeededUriGrants extends ArrayList<GrantUri> {
7465        final String targetPkg;
7466        final int targetUid;
7467        final int flags;
7468
7469        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7470            this.targetPkg = targetPkg;
7471            this.targetUid = targetUid;
7472            this.flags = flags;
7473        }
7474    }
7475
7476    /**
7477     * Like checkGrantUriPermissionLocked, but takes an Intent.
7478     */
7479    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7480            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7481        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7482                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7483                + " clip=" + (intent != null ? intent.getClipData() : null)
7484                + " from " + intent + "; flags=0x"
7485                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7486
7487        if (targetPkg == null) {
7488            throw new NullPointerException("targetPkg");
7489        }
7490
7491        if (intent == null) {
7492            return null;
7493        }
7494        Uri data = intent.getData();
7495        ClipData clip = intent.getClipData();
7496        if (data == null && clip == null) {
7497            return null;
7498        }
7499        // Default userId for uris in the intent (if they don't specify it themselves)
7500        int contentUserHint = intent.getContentUserHint();
7501        if (contentUserHint == UserHandle.USER_CURRENT) {
7502            contentUserHint = UserHandle.getUserId(callingUid);
7503        }
7504        final IPackageManager pm = AppGlobals.getPackageManager();
7505        int targetUid;
7506        if (needed != null) {
7507            targetUid = needed.targetUid;
7508        } else {
7509            try {
7510                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7511            } catch (RemoteException ex) {
7512                return null;
7513            }
7514            if (targetUid < 0) {
7515                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7516                        "Can't grant URI permission no uid for: " + targetPkg
7517                        + " on user " + targetUserId);
7518                return null;
7519            }
7520        }
7521        if (data != null) {
7522            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7523            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7524                    targetUid);
7525            if (targetUid > 0) {
7526                if (needed == null) {
7527                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7528                }
7529                needed.add(grantUri);
7530            }
7531        }
7532        if (clip != null) {
7533            for (int i=0; i<clip.getItemCount(); i++) {
7534                Uri uri = clip.getItemAt(i).getUri();
7535                if (uri != null) {
7536                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7537                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7538                            targetUid);
7539                    if (targetUid > 0) {
7540                        if (needed == null) {
7541                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7542                        }
7543                        needed.add(grantUri);
7544                    }
7545                } else {
7546                    Intent clipIntent = clip.getItemAt(i).getIntent();
7547                    if (clipIntent != null) {
7548                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7549                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7550                        if (newNeeded != null) {
7551                            needed = newNeeded;
7552                        }
7553                    }
7554                }
7555            }
7556        }
7557
7558        return needed;
7559    }
7560
7561    /**
7562     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7563     */
7564    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7565            UriPermissionOwner owner) {
7566        if (needed != null) {
7567            for (int i=0; i<needed.size(); i++) {
7568                GrantUri grantUri = needed.get(i);
7569                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7570                        grantUri, needed.flags, owner);
7571            }
7572        }
7573    }
7574
7575    void grantUriPermissionFromIntentLocked(int callingUid,
7576            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7577        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7578                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7579        if (needed == null) {
7580            return;
7581        }
7582
7583        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7584    }
7585
7586    /**
7587     * @param uri This uri must NOT contain an embedded userId.
7588     * @param userId The userId in which the uri is to be resolved.
7589     */
7590    @Override
7591    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7592            final int modeFlags, int userId) {
7593        enforceNotIsolatedCaller("grantUriPermission");
7594        GrantUri grantUri = new GrantUri(userId, uri, false);
7595        synchronized(this) {
7596            final ProcessRecord r = getRecordForAppLocked(caller);
7597            if (r == null) {
7598                throw new SecurityException("Unable to find app for caller "
7599                        + caller
7600                        + " when granting permission to uri " + grantUri);
7601            }
7602            if (targetPkg == null) {
7603                throw new IllegalArgumentException("null target");
7604            }
7605            if (grantUri == null) {
7606                throw new IllegalArgumentException("null uri");
7607            }
7608
7609            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7610                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7611                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7612                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7613
7614            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7615                    UserHandle.getUserId(r.uid));
7616        }
7617    }
7618
7619    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7620        if (perm.modeFlags == 0) {
7621            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7622                    perm.targetUid);
7623            if (perms != null) {
7624                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7625                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7626
7627                perms.remove(perm.uri);
7628                if (perms.isEmpty()) {
7629                    mGrantedUriPermissions.remove(perm.targetUid);
7630                }
7631            }
7632        }
7633    }
7634
7635    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7636        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7637                "Revoking all granted permissions to " + grantUri);
7638
7639        final IPackageManager pm = AppGlobals.getPackageManager();
7640        final String authority = grantUri.uri.getAuthority();
7641        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7642        if (pi == null) {
7643            Slog.w(TAG, "No content provider found for permission revoke: "
7644                    + grantUri.toSafeString());
7645            return;
7646        }
7647
7648        // Does the caller have this permission on the URI?
7649        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7650            // If they don't have direct access to the URI, then revoke any
7651            // ownerless URI permissions that have been granted to them.
7652            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7653            if (perms != null) {
7654                boolean persistChanged = false;
7655                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7656                    final UriPermission perm = it.next();
7657                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7658                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7659                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7660                                "Revoking non-owned " + perm.targetUid
7661                                + " permission to " + perm.uri);
7662                        persistChanged |= perm.revokeModes(
7663                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7664                        if (perm.modeFlags == 0) {
7665                            it.remove();
7666                        }
7667                    }
7668                }
7669                if (perms.isEmpty()) {
7670                    mGrantedUriPermissions.remove(callingUid);
7671                }
7672                if (persistChanged) {
7673                    schedulePersistUriGrants();
7674                }
7675            }
7676            return;
7677        }
7678
7679        boolean persistChanged = false;
7680
7681        // Go through all of the permissions and remove any that match.
7682        int N = mGrantedUriPermissions.size();
7683        for (int i = 0; i < N; i++) {
7684            final int targetUid = mGrantedUriPermissions.keyAt(i);
7685            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7686
7687            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7688                final UriPermission perm = it.next();
7689                if (perm.uri.sourceUserId == grantUri.sourceUserId
7690                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7691                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7692                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7693                    persistChanged |= perm.revokeModes(
7694                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7695                    if (perm.modeFlags == 0) {
7696                        it.remove();
7697                    }
7698                }
7699            }
7700
7701            if (perms.isEmpty()) {
7702                mGrantedUriPermissions.remove(targetUid);
7703                N--;
7704                i--;
7705            }
7706        }
7707
7708        if (persistChanged) {
7709            schedulePersistUriGrants();
7710        }
7711    }
7712
7713    /**
7714     * @param uri This uri must NOT contain an embedded userId.
7715     * @param userId The userId in which the uri is to be resolved.
7716     */
7717    @Override
7718    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7719            int userId) {
7720        enforceNotIsolatedCaller("revokeUriPermission");
7721        synchronized(this) {
7722            final ProcessRecord r = getRecordForAppLocked(caller);
7723            if (r == null) {
7724                throw new SecurityException("Unable to find app for caller "
7725                        + caller
7726                        + " when revoking permission to uri " + uri);
7727            }
7728            if (uri == null) {
7729                Slog.w(TAG, "revokeUriPermission: null uri");
7730                return;
7731            }
7732
7733            if (!Intent.isAccessUriMode(modeFlags)) {
7734                return;
7735            }
7736
7737            final String authority = uri.getAuthority();
7738            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7739            if (pi == null) {
7740                Slog.w(TAG, "No content provider found for permission revoke: "
7741                        + uri.toSafeString());
7742                return;
7743            }
7744
7745            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7746        }
7747    }
7748
7749    /**
7750     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7751     * given package.
7752     *
7753     * @param packageName Package name to match, or {@code null} to apply to all
7754     *            packages.
7755     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7756     *            to all users.
7757     * @param persistable If persistable grants should be removed.
7758     */
7759    private void removeUriPermissionsForPackageLocked(
7760            String packageName, int userHandle, boolean persistable) {
7761        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7762            throw new IllegalArgumentException("Must narrow by either package or user");
7763        }
7764
7765        boolean persistChanged = false;
7766
7767        int N = mGrantedUriPermissions.size();
7768        for (int i = 0; i < N; i++) {
7769            final int targetUid = mGrantedUriPermissions.keyAt(i);
7770            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7771
7772            // Only inspect grants matching user
7773            if (userHandle == UserHandle.USER_ALL
7774                    || userHandle == UserHandle.getUserId(targetUid)) {
7775                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7776                    final UriPermission perm = it.next();
7777
7778                    // Only inspect grants matching package
7779                    if (packageName == null || perm.sourcePkg.equals(packageName)
7780                            || perm.targetPkg.equals(packageName)) {
7781                        persistChanged |= perm.revokeModes(persistable
7782                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7783
7784                        // Only remove when no modes remain; any persisted grants
7785                        // will keep this alive.
7786                        if (perm.modeFlags == 0) {
7787                            it.remove();
7788                        }
7789                    }
7790                }
7791
7792                if (perms.isEmpty()) {
7793                    mGrantedUriPermissions.remove(targetUid);
7794                    N--;
7795                    i--;
7796                }
7797            }
7798        }
7799
7800        if (persistChanged) {
7801            schedulePersistUriGrants();
7802        }
7803    }
7804
7805    @Override
7806    public IBinder newUriPermissionOwner(String name) {
7807        enforceNotIsolatedCaller("newUriPermissionOwner");
7808        synchronized(this) {
7809            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7810            return owner.getExternalTokenLocked();
7811        }
7812    }
7813
7814    /**
7815     * @param uri This uri must NOT contain an embedded userId.
7816     * @param sourceUserId The userId in which the uri is to be resolved.
7817     * @param targetUserId The userId of the app that receives the grant.
7818     */
7819    @Override
7820    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7821            final int modeFlags, int sourceUserId, int targetUserId) {
7822        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7823                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7824        synchronized(this) {
7825            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7826            if (owner == null) {
7827                throw new IllegalArgumentException("Unknown owner: " + token);
7828            }
7829            if (fromUid != Binder.getCallingUid()) {
7830                if (Binder.getCallingUid() != Process.myUid()) {
7831                    // Only system code can grant URI permissions on behalf
7832                    // of other users.
7833                    throw new SecurityException("nice try");
7834                }
7835            }
7836            if (targetPkg == null) {
7837                throw new IllegalArgumentException("null target");
7838            }
7839            if (uri == null) {
7840                throw new IllegalArgumentException("null uri");
7841            }
7842
7843            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7844                    modeFlags, owner, targetUserId);
7845        }
7846    }
7847
7848    /**
7849     * @param uri This uri must NOT contain an embedded userId.
7850     * @param userId The userId in which the uri is to be resolved.
7851     */
7852    @Override
7853    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7854        synchronized(this) {
7855            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7856            if (owner == null) {
7857                throw new IllegalArgumentException("Unknown owner: " + token);
7858            }
7859
7860            if (uri == null) {
7861                owner.removeUriPermissionsLocked(mode);
7862            } else {
7863                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7864            }
7865        }
7866    }
7867
7868    private void schedulePersistUriGrants() {
7869        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7870            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7871                    10 * DateUtils.SECOND_IN_MILLIS);
7872        }
7873    }
7874
7875    private void writeGrantedUriPermissions() {
7876        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
7877
7878        // Snapshot permissions so we can persist without lock
7879        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7880        synchronized (this) {
7881            final int size = mGrantedUriPermissions.size();
7882            for (int i = 0; i < size; i++) {
7883                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7884                for (UriPermission perm : perms.values()) {
7885                    if (perm.persistedModeFlags != 0) {
7886                        persist.add(perm.snapshot());
7887                    }
7888                }
7889            }
7890        }
7891
7892        FileOutputStream fos = null;
7893        try {
7894            fos = mGrantFile.startWrite();
7895
7896            XmlSerializer out = new FastXmlSerializer();
7897            out.setOutput(fos, StandardCharsets.UTF_8.name());
7898            out.startDocument(null, true);
7899            out.startTag(null, TAG_URI_GRANTS);
7900            for (UriPermission.Snapshot perm : persist) {
7901                out.startTag(null, TAG_URI_GRANT);
7902                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7903                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7904                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7905                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7906                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7907                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7908                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7909                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7910                out.endTag(null, TAG_URI_GRANT);
7911            }
7912            out.endTag(null, TAG_URI_GRANTS);
7913            out.endDocument();
7914
7915            mGrantFile.finishWrite(fos);
7916        } catch (IOException e) {
7917            if (fos != null) {
7918                mGrantFile.failWrite(fos);
7919            }
7920        }
7921    }
7922
7923    private void readGrantedUriPermissionsLocked() {
7924        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
7925
7926        final long now = System.currentTimeMillis();
7927
7928        FileInputStream fis = null;
7929        try {
7930            fis = mGrantFile.openRead();
7931            final XmlPullParser in = Xml.newPullParser();
7932            in.setInput(fis, StandardCharsets.UTF_8.name());
7933
7934            int type;
7935            while ((type = in.next()) != END_DOCUMENT) {
7936                final String tag = in.getName();
7937                if (type == START_TAG) {
7938                    if (TAG_URI_GRANT.equals(tag)) {
7939                        final int sourceUserId;
7940                        final int targetUserId;
7941                        final int userHandle = readIntAttribute(in,
7942                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7943                        if (userHandle != UserHandle.USER_NULL) {
7944                            // For backwards compatibility.
7945                            sourceUserId = userHandle;
7946                            targetUserId = userHandle;
7947                        } else {
7948                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7949                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7950                        }
7951                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7952                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7953                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7954                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7955                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7956                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7957
7958                        // Sanity check that provider still belongs to source package
7959                        final ProviderInfo pi = getProviderInfoLocked(
7960                                uri.getAuthority(), sourceUserId);
7961                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7962                            int targetUid = -1;
7963                            try {
7964                                targetUid = AppGlobals.getPackageManager()
7965                                        .getPackageUid(targetPkg, targetUserId);
7966                            } catch (RemoteException e) {
7967                            }
7968                            if (targetUid != -1) {
7969                                final UriPermission perm = findOrCreateUriPermissionLocked(
7970                                        sourcePkg, targetPkg, targetUid,
7971                                        new GrantUri(sourceUserId, uri, prefix));
7972                                perm.initPersistedModes(modeFlags, createdTime);
7973                            }
7974                        } else {
7975                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7976                                    + " but instead found " + pi);
7977                        }
7978                    }
7979                }
7980            }
7981        } catch (FileNotFoundException e) {
7982            // Missing grants is okay
7983        } catch (IOException e) {
7984            Slog.wtf(TAG, "Failed reading Uri grants", e);
7985        } catch (XmlPullParserException e) {
7986            Slog.wtf(TAG, "Failed reading Uri grants", e);
7987        } finally {
7988            IoUtils.closeQuietly(fis);
7989        }
7990    }
7991
7992    /**
7993     * @param uri This uri must NOT contain an embedded userId.
7994     * @param userId The userId in which the uri is to be resolved.
7995     */
7996    @Override
7997    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7998        enforceNotIsolatedCaller("takePersistableUriPermission");
7999
8000        Preconditions.checkFlagsArgument(modeFlags,
8001                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8002
8003        synchronized (this) {
8004            final int callingUid = Binder.getCallingUid();
8005            boolean persistChanged = false;
8006            GrantUri grantUri = new GrantUri(userId, uri, false);
8007
8008            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8009                    new GrantUri(userId, uri, false));
8010            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8011                    new GrantUri(userId, uri, true));
8012
8013            final boolean exactValid = (exactPerm != null)
8014                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8015            final boolean prefixValid = (prefixPerm != null)
8016                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8017
8018            if (!(exactValid || prefixValid)) {
8019                throw new SecurityException("No persistable permission grants found for UID "
8020                        + callingUid + " and Uri " + grantUri.toSafeString());
8021            }
8022
8023            if (exactValid) {
8024                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8025            }
8026            if (prefixValid) {
8027                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8028            }
8029
8030            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8031
8032            if (persistChanged) {
8033                schedulePersistUriGrants();
8034            }
8035        }
8036    }
8037
8038    /**
8039     * @param uri This uri must NOT contain an embedded userId.
8040     * @param userId The userId in which the uri is to be resolved.
8041     */
8042    @Override
8043    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8044        enforceNotIsolatedCaller("releasePersistableUriPermission");
8045
8046        Preconditions.checkFlagsArgument(modeFlags,
8047                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8048
8049        synchronized (this) {
8050            final int callingUid = Binder.getCallingUid();
8051            boolean persistChanged = false;
8052
8053            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8054                    new GrantUri(userId, uri, false));
8055            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8056                    new GrantUri(userId, uri, true));
8057            if (exactPerm == null && prefixPerm == null) {
8058                throw new SecurityException("No permission grants found for UID " + callingUid
8059                        + " and Uri " + uri.toSafeString());
8060            }
8061
8062            if (exactPerm != null) {
8063                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8064                removeUriPermissionIfNeededLocked(exactPerm);
8065            }
8066            if (prefixPerm != null) {
8067                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8068                removeUriPermissionIfNeededLocked(prefixPerm);
8069            }
8070
8071            if (persistChanged) {
8072                schedulePersistUriGrants();
8073            }
8074        }
8075    }
8076
8077    /**
8078     * Prune any older {@link UriPermission} for the given UID until outstanding
8079     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8080     *
8081     * @return if any mutations occured that require persisting.
8082     */
8083    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8084        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8085        if (perms == null) return false;
8086        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8087
8088        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8089        for (UriPermission perm : perms.values()) {
8090            if (perm.persistedModeFlags != 0) {
8091                persisted.add(perm);
8092            }
8093        }
8094
8095        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8096        if (trimCount <= 0) return false;
8097
8098        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8099        for (int i = 0; i < trimCount; i++) {
8100            final UriPermission perm = persisted.get(i);
8101
8102            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8103                    "Trimming grant created at " + perm.persistedCreateTime);
8104
8105            perm.releasePersistableModes(~0);
8106            removeUriPermissionIfNeededLocked(perm);
8107        }
8108
8109        return true;
8110    }
8111
8112    @Override
8113    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8114            String packageName, boolean incoming) {
8115        enforceNotIsolatedCaller("getPersistedUriPermissions");
8116        Preconditions.checkNotNull(packageName, "packageName");
8117
8118        final int callingUid = Binder.getCallingUid();
8119        final IPackageManager pm = AppGlobals.getPackageManager();
8120        try {
8121            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8122            if (packageUid != callingUid) {
8123                throw new SecurityException(
8124                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8125            }
8126        } catch (RemoteException e) {
8127            throw new SecurityException("Failed to verify package name ownership");
8128        }
8129
8130        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8131        synchronized (this) {
8132            if (incoming) {
8133                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8134                        callingUid);
8135                if (perms == null) {
8136                    Slog.w(TAG, "No permission grants found for " + packageName);
8137                } else {
8138                    for (UriPermission perm : perms.values()) {
8139                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8140                            result.add(perm.buildPersistedPublicApiObject());
8141                        }
8142                    }
8143                }
8144            } else {
8145                final int size = mGrantedUriPermissions.size();
8146                for (int i = 0; i < size; i++) {
8147                    final ArrayMap<GrantUri, UriPermission> perms =
8148                            mGrantedUriPermissions.valueAt(i);
8149                    for (UriPermission perm : perms.values()) {
8150                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8151                            result.add(perm.buildPersistedPublicApiObject());
8152                        }
8153                    }
8154                }
8155            }
8156        }
8157        return new ParceledListSlice<android.content.UriPermission>(result);
8158    }
8159
8160    @Override
8161    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8162        synchronized (this) {
8163            ProcessRecord app =
8164                who != null ? getRecordForAppLocked(who) : null;
8165            if (app == null) return;
8166
8167            Message msg = Message.obtain();
8168            msg.what = WAIT_FOR_DEBUGGER_MSG;
8169            msg.obj = app;
8170            msg.arg1 = waiting ? 1 : 0;
8171            mUiHandler.sendMessage(msg);
8172        }
8173    }
8174
8175    @Override
8176    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8177        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8178        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8179        outInfo.availMem = Process.getFreeMemory();
8180        outInfo.totalMem = Process.getTotalMemory();
8181        outInfo.threshold = homeAppMem;
8182        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8183        outInfo.hiddenAppThreshold = cachedAppMem;
8184        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8185                ProcessList.SERVICE_ADJ);
8186        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8187                ProcessList.VISIBLE_APP_ADJ);
8188        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8189                ProcessList.FOREGROUND_APP_ADJ);
8190    }
8191
8192    // =========================================================
8193    // TASK MANAGEMENT
8194    // =========================================================
8195
8196    @Override
8197    public List<IAppTask> getAppTasks(String callingPackage) {
8198        int callingUid = Binder.getCallingUid();
8199        long ident = Binder.clearCallingIdentity();
8200
8201        synchronized(this) {
8202            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8203            try {
8204                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8205
8206                final int N = mRecentTasks.size();
8207                for (int i = 0; i < N; i++) {
8208                    TaskRecord tr = mRecentTasks.get(i);
8209                    // Skip tasks that do not match the caller.  We don't need to verify
8210                    // callingPackage, because we are also limiting to callingUid and know
8211                    // that will limit to the correct security sandbox.
8212                    if (tr.effectiveUid != callingUid) {
8213                        continue;
8214                    }
8215                    Intent intent = tr.getBaseIntent();
8216                    if (intent == null ||
8217                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8218                        continue;
8219                    }
8220                    ActivityManager.RecentTaskInfo taskInfo =
8221                            createRecentTaskInfoFromTaskRecord(tr);
8222                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8223                    list.add(taskImpl);
8224                }
8225            } finally {
8226                Binder.restoreCallingIdentity(ident);
8227            }
8228            return list;
8229        }
8230    }
8231
8232    @Override
8233    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8234        final int callingUid = Binder.getCallingUid();
8235        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8236
8237        synchronized(this) {
8238            if (DEBUG_ALL) Slog.v(
8239                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8240
8241            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8242                    callingUid);
8243
8244            // TODO: Improve with MRU list from all ActivityStacks.
8245            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8246        }
8247
8248        return list;
8249    }
8250
8251    /**
8252     * Creates a new RecentTaskInfo from a TaskRecord.
8253     */
8254    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8255        // Update the task description to reflect any changes in the task stack
8256        tr.updateTaskDescription();
8257
8258        // Compose the recent task info
8259        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8260        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8261        rti.persistentId = tr.taskId;
8262        rti.baseIntent = new Intent(tr.getBaseIntent());
8263        rti.origActivity = tr.origActivity;
8264        rti.description = tr.lastDescription;
8265        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8266        rti.userId = tr.userId;
8267        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8268        rti.firstActiveTime = tr.firstActiveTime;
8269        rti.lastActiveTime = tr.lastActiveTime;
8270        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8271        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8272        rti.numActivities = 0;
8273
8274        ActivityRecord base = null;
8275        ActivityRecord top = null;
8276        ActivityRecord tmp;
8277
8278        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8279            tmp = tr.mActivities.get(i);
8280            if (tmp.finishing) {
8281                continue;
8282            }
8283            base = tmp;
8284            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8285                top = base;
8286            }
8287            rti.numActivities++;
8288        }
8289
8290        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8291        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8292
8293        return rti;
8294    }
8295
8296    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8297        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8298                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8299        if (!allowed) {
8300            if (checkPermission(android.Manifest.permission.GET_TASKS,
8301                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8302                // Temporary compatibility: some existing apps on the system image may
8303                // still be requesting the old permission and not switched to the new
8304                // one; if so, we'll still allow them full access.  This means we need
8305                // to see if they are holding the old permission and are a system app.
8306                try {
8307                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8308                        allowed = true;
8309                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8310                                + " is using old GET_TASKS but privileged; allowing");
8311                    }
8312                } catch (RemoteException e) {
8313                }
8314            }
8315        }
8316        if (!allowed) {
8317            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8318                    + " does not hold REAL_GET_TASKS; limiting output");
8319        }
8320        return allowed;
8321    }
8322
8323    @Override
8324    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8325        final int callingUid = Binder.getCallingUid();
8326        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8327                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8328
8329        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8330        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8331        synchronized (this) {
8332            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8333                    callingUid);
8334            final boolean detailed = checkCallingPermission(
8335                    android.Manifest.permission.GET_DETAILED_TASKS)
8336                    == PackageManager.PERMISSION_GRANTED;
8337
8338            final int recentsCount = mRecentTasks.size();
8339            ArrayList<ActivityManager.RecentTaskInfo> res =
8340                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8341
8342            final Set<Integer> includedUsers;
8343            if (includeProfiles) {
8344                includedUsers = getProfileIdsLocked(userId);
8345            } else {
8346                includedUsers = new HashSet<>();
8347            }
8348            includedUsers.add(Integer.valueOf(userId));
8349
8350            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8351                TaskRecord tr = mRecentTasks.get(i);
8352                // Only add calling user or related users recent tasks
8353                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8354                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8355                    continue;
8356                }
8357
8358                // Return the entry if desired by the caller.  We always return
8359                // the first entry, because callers always expect this to be the
8360                // foreground app.  We may filter others if the caller has
8361                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8362                // we should exclude the entry.
8363
8364                if (i == 0
8365                        || withExcluded
8366                        || (tr.intent == null)
8367                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8368                                == 0)) {
8369                    if (!allowed) {
8370                        // If the caller doesn't have the GET_TASKS permission, then only
8371                        // allow them to see a small subset of tasks -- their own and home.
8372                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8373                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8374                            continue;
8375                        }
8376                    }
8377                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8378                        if (tr.stack != null && tr.stack.isHomeStack()) {
8379                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8380                                    "Skipping, home stack task: " + tr);
8381                            continue;
8382                        }
8383                    }
8384                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8385                        // Don't include auto remove tasks that are finished or finishing.
8386                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8387                                "Skipping, auto-remove without activity: " + tr);
8388                        continue;
8389                    }
8390                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8391                            && !tr.isAvailable) {
8392                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8393                                "Skipping, unavail real act: " + tr);
8394                        continue;
8395                    }
8396
8397                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8398                    if (!detailed) {
8399                        rti.baseIntent.replaceExtras((Bundle)null);
8400                    }
8401
8402                    res.add(rti);
8403                    maxNum--;
8404                }
8405            }
8406            return res;
8407        }
8408    }
8409
8410    @Override
8411    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8412        synchronized (this) {
8413            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8414                    "getTaskThumbnail()");
8415            TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id, false);
8416            if (tr != null) {
8417                return tr.getTaskThumbnailLocked();
8418            }
8419        }
8420        return null;
8421    }
8422
8423    @Override
8424    public int addAppTask(IBinder activityToken, Intent intent,
8425            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8426        final int callingUid = Binder.getCallingUid();
8427        final long callingIdent = Binder.clearCallingIdentity();
8428
8429        try {
8430            synchronized (this) {
8431                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8432                if (r == null) {
8433                    throw new IllegalArgumentException("Activity does not exist; token="
8434                            + activityToken);
8435                }
8436                ComponentName comp = intent.getComponent();
8437                if (comp == null) {
8438                    throw new IllegalArgumentException("Intent " + intent
8439                            + " must specify explicit component");
8440                }
8441                if (thumbnail.getWidth() != mThumbnailWidth
8442                        || thumbnail.getHeight() != mThumbnailHeight) {
8443                    throw new IllegalArgumentException("Bad thumbnail size: got "
8444                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8445                            + mThumbnailWidth + "x" + mThumbnailHeight);
8446                }
8447                if (intent.getSelector() != null) {
8448                    intent.setSelector(null);
8449                }
8450                if (intent.getSourceBounds() != null) {
8451                    intent.setSourceBounds(null);
8452                }
8453                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8454                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8455                        // The caller has added this as an auto-remove task...  that makes no
8456                        // sense, so turn off auto-remove.
8457                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8458                    }
8459                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8460                    // Must be a new task.
8461                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8462                }
8463                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8464                    mLastAddedTaskActivity = null;
8465                }
8466                ActivityInfo ainfo = mLastAddedTaskActivity;
8467                if (ainfo == null) {
8468                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8469                            comp, 0, UserHandle.getUserId(callingUid));
8470                    if (ainfo.applicationInfo.uid != callingUid) {
8471                        throw new SecurityException(
8472                                "Can't add task for another application: target uid="
8473                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8474                    }
8475                }
8476
8477                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8478                        intent, description);
8479
8480                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
8481                if (trimIdx >= 0) {
8482                    // If this would have caused a trim, then we'll abort because that
8483                    // means it would be added at the end of the list but then just removed.
8484                    return INVALID_TASK_ID;
8485                }
8486
8487                final int N = mRecentTasks.size();
8488                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8489                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8490                    tr.removedFromRecents();
8491                }
8492
8493                task.inRecents = true;
8494                mRecentTasks.add(task);
8495                r.task.stack.addTask(task, false, false);
8496
8497                task.setLastThumbnail(thumbnail);
8498                task.freeLastThumbnail();
8499
8500                return task.taskId;
8501            }
8502        } finally {
8503            Binder.restoreCallingIdentity(callingIdent);
8504        }
8505    }
8506
8507    @Override
8508    public Point getAppTaskThumbnailSize() {
8509        synchronized (this) {
8510            return new Point(mThumbnailWidth,  mThumbnailHeight);
8511        }
8512    }
8513
8514    @Override
8515    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8516        synchronized (this) {
8517            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8518            if (r != null) {
8519                r.setTaskDescription(td);
8520                r.task.updateTaskDescription();
8521            }
8522        }
8523    }
8524
8525    @Override
8526    public void setTaskResizeable(int taskId, boolean resizeable) {
8527        synchronized (this) {
8528            TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8529            if (task == null) {
8530                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
8531                return;
8532            }
8533            if (task.mResizeable != resizeable) {
8534                task.mResizeable = resizeable;
8535                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8536                mStackSupervisor.resumeTopActivitiesLocked();
8537            }
8538        }
8539    }
8540
8541    @Override
8542    public void resizeTask(int taskId, Rect bounds) {
8543        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8544                "resizeTask()");
8545        long ident = Binder.clearCallingIdentity();
8546        try {
8547            synchronized (this) {
8548                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8549                if (task == null) {
8550                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
8551                    return;
8552                }
8553                mStackSupervisor.resizeTaskLocked(task, bounds);
8554            }
8555        } finally {
8556            Binder.restoreCallingIdentity(ident);
8557        }
8558    }
8559
8560    @Override
8561    public Bitmap getTaskDescriptionIcon(String filename) {
8562        if (!FileUtils.isValidExtFilename(filename)
8563                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8564            throw new IllegalArgumentException("Bad filename: " + filename);
8565        }
8566        return mTaskPersister.getTaskDescriptionIcon(filename);
8567    }
8568
8569    @Override
8570    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8571            throws RemoteException {
8572        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8573                opts.getCustomInPlaceResId() == 0) {
8574            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8575                    "with valid animation");
8576        }
8577        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8578        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8579                opts.getCustomInPlaceResId());
8580        mWindowManager.executeAppTransition();
8581    }
8582
8583    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8584        mRecentTasks.remove(tr);
8585        tr.removedFromRecents();
8586        ComponentName component = tr.getBaseIntent().getComponent();
8587        if (component == null) {
8588            Slog.w(TAG, "No component for base intent of task: " + tr);
8589            return;
8590        }
8591
8592        // Find any running services associated with this app and stop if needed.
8593        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8594
8595        if (!killProcess) {
8596            return;
8597        }
8598
8599        // Determine if the process(es) for this task should be killed.
8600        final String pkg = component.getPackageName();
8601        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
8602        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8603        for (int i = 0; i < pmap.size(); i++) {
8604
8605            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8606            for (int j = 0; j < uids.size(); j++) {
8607                ProcessRecord proc = uids.valueAt(j);
8608                if (proc.userId != tr.userId) {
8609                    // Don't kill process for a different user.
8610                    continue;
8611                }
8612                if (proc == mHomeProcess) {
8613                    // Don't kill the home process along with tasks from the same package.
8614                    continue;
8615                }
8616                if (!proc.pkgList.containsKey(pkg)) {
8617                    // Don't kill process that is not associated with this task.
8618                    continue;
8619                }
8620
8621                for (int k = 0; k < proc.activities.size(); k++) {
8622                    TaskRecord otherTask = proc.activities.get(k).task;
8623                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8624                        // Don't kill process(es) that has an activity in a different task that is
8625                        // also in recents.
8626                        return;
8627                    }
8628                }
8629
8630                if (proc.foregroundServices) {
8631                    // Don't kill process(es) with foreground service.
8632                    return;
8633                }
8634
8635                // Add process to kill list.
8636                procsToKill.add(proc);
8637            }
8638        }
8639
8640        // Kill the running processes.
8641        for (int i = 0; i < procsToKill.size(); i++) {
8642            ProcessRecord pr = procsToKill.get(i);
8643            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
8644                    && pr.curReceiver == null) {
8645                pr.kill("remove task", true);
8646            } else {
8647                // We delay killing processes that are not in the background or running a receiver.
8648                pr.waitingToKill = "remove task";
8649            }
8650        }
8651    }
8652
8653    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8654        // Remove all tasks with activities in the specified package from the list of recent tasks
8655        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8656            TaskRecord tr = mRecentTasks.get(i);
8657            if (tr.userId != userId) continue;
8658
8659            ComponentName cn = tr.intent.getComponent();
8660            if (cn != null && cn.getPackageName().equals(packageName)) {
8661                // If the package name matches, remove the task.
8662                removeTaskByIdLocked(tr.taskId, true);
8663            }
8664        }
8665    }
8666
8667    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
8668            int userId) {
8669
8670        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8671            TaskRecord tr = mRecentTasks.get(i);
8672            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
8673                continue;
8674            }
8675
8676            ComponentName cn = tr.intent.getComponent();
8677            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
8678                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
8679            if (sameComponent) {
8680                removeTaskByIdLocked(tr.taskId, false);
8681            }
8682        }
8683    }
8684
8685    /**
8686     * Removes the task with the specified task id.
8687     *
8688     * @param taskId Identifier of the task to be removed.
8689     * @param killProcess Kill any process associated with the task if possible.
8690     * @return Returns true if the given task was found and removed.
8691     */
8692    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8693        TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8694        if (tr != null) {
8695            tr.removeTaskActivitiesLocked();
8696            cleanUpRemovedTaskLocked(tr, killProcess);
8697            if (tr.isPersistable) {
8698                notifyTaskPersisterLocked(null, true);
8699            }
8700            return true;
8701        }
8702        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8703        return false;
8704    }
8705
8706    @Override
8707    public boolean removeTask(int taskId) {
8708        synchronized (this) {
8709            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8710                    "removeTask()");
8711            long ident = Binder.clearCallingIdentity();
8712            try {
8713                return removeTaskByIdLocked(taskId, true);
8714            } finally {
8715                Binder.restoreCallingIdentity(ident);
8716            }
8717        }
8718    }
8719
8720    /**
8721     * TODO: Add mController hook
8722     */
8723    @Override
8724    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8725        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
8726
8727        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
8728        synchronized(this) {
8729            moveTaskToFrontLocked(taskId, flags, options);
8730        }
8731    }
8732
8733    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8734        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8735                Binder.getCallingUid(), -1, -1, "Task to front")) {
8736            ActivityOptions.abort(options);
8737            return;
8738        }
8739        final long origId = Binder.clearCallingIdentity();
8740        try {
8741            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8742            if (task == null) {
8743                Slog.d(TAG, "Could not find task for id: "+ taskId);
8744                return;
8745            }
8746            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8747                mStackSupervisor.showLockTaskToast();
8748                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8749                return;
8750            }
8751            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8752            if (prev != null && prev.isRecentsActivity()) {
8753                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8754            }
8755            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
8756        } finally {
8757            Binder.restoreCallingIdentity(origId);
8758        }
8759        ActivityOptions.abort(options);
8760    }
8761
8762    /**
8763     * Moves an activity, and all of the other activities within the same task, to the bottom
8764     * of the history stack.  The activity's order within the task is unchanged.
8765     *
8766     * @param token A reference to the activity we wish to move
8767     * @param nonRoot If false then this only works if the activity is the root
8768     *                of a task; if true it will work for any activity in a task.
8769     * @return Returns true if the move completed, false if not.
8770     */
8771    @Override
8772    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8773        enforceNotIsolatedCaller("moveActivityTaskToBack");
8774        synchronized(this) {
8775            final long origId = Binder.clearCallingIdentity();
8776            try {
8777                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8778                final TaskRecord task = mRecentTasks.taskForIdLocked(taskId);
8779                if (task != null) {
8780                    if (mStackSupervisor.isLockedTask(task)) {
8781                        mStackSupervisor.showLockTaskToast();
8782                        return false;
8783                    }
8784                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
8785                }
8786            } finally {
8787                Binder.restoreCallingIdentity(origId);
8788            }
8789        }
8790        return false;
8791    }
8792
8793    @Override
8794    public void moveTaskBackwards(int task) {
8795        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8796                "moveTaskBackwards()");
8797
8798        synchronized(this) {
8799            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8800                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8801                return;
8802            }
8803            final long origId = Binder.clearCallingIdentity();
8804            moveTaskBackwardsLocked(task);
8805            Binder.restoreCallingIdentity(origId);
8806        }
8807    }
8808
8809    private final void moveTaskBackwardsLocked(int task) {
8810        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8811    }
8812
8813    @Override
8814    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
8815            IActivityContainerCallback callback) throws RemoteException {
8816        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8817                "createActivityContainer()");
8818        synchronized (this) {
8819            if (parentActivityToken == null) {
8820                throw new IllegalArgumentException("parent token must not be null");
8821            }
8822            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
8823            if (r == null) {
8824                return null;
8825            }
8826            if (callback == null) {
8827                throw new IllegalArgumentException("callback must not be null");
8828            }
8829            return mStackSupervisor.createVirtualActivityContainer(r, callback);
8830        }
8831    }
8832
8833    @Override
8834    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8835        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8836                "deleteActivityContainer()");
8837        synchronized (this) {
8838            mStackSupervisor.deleteActivityContainer(container);
8839        }
8840    }
8841
8842    @Override
8843    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
8844        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8845                "createStackOnDisplay()");
8846        synchronized (this) {
8847            final int stackId = mStackSupervisor.getNextStackId();
8848            final ActivityStack stack = mStackSupervisor.createStackOnDisplay(stackId, displayId);
8849            if (stack == null) {
8850                return null;
8851            }
8852            return stack.mActivityContainer;
8853        }
8854    }
8855
8856    @Override
8857    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
8858        synchronized (this) {
8859            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8860            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
8861                return stack.mActivityContainer.getDisplayId();
8862            }
8863            return Display.DEFAULT_DISPLAY;
8864        }
8865    }
8866
8867    @Override
8868    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8869        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8870                "moveTaskToStack()");
8871        if (stackId == HOME_STACK_ID) {
8872            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8873                    new RuntimeException("here").fillInStackTrace());
8874        }
8875        synchronized (this) {
8876            long ident = Binder.clearCallingIdentity();
8877            try {
8878                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
8879                        + " to stackId=" + stackId + " toTop=" + toTop);
8880                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop);
8881            } finally {
8882                Binder.restoreCallingIdentity(ident);
8883            }
8884        }
8885    }
8886
8887    @Override
8888    public void resizeStack(int stackId, Rect bounds) {
8889        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8890                "resizeStack()");
8891        long ident = Binder.clearCallingIdentity();
8892        try {
8893            synchronized (this) {
8894                mStackSupervisor.resizeStackLocked(stackId, bounds);
8895            }
8896        } finally {
8897            Binder.restoreCallingIdentity(ident);
8898        }
8899    }
8900
8901    @Override
8902    public List<StackInfo> getAllStackInfos() {
8903        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8904                "getAllStackInfos()");
8905        long ident = Binder.clearCallingIdentity();
8906        try {
8907            synchronized (this) {
8908                return mStackSupervisor.getAllStackInfosLocked();
8909            }
8910        } finally {
8911            Binder.restoreCallingIdentity(ident);
8912        }
8913    }
8914
8915    @Override
8916    public StackInfo getStackInfo(int stackId) {
8917        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8918                "getStackInfo()");
8919        long ident = Binder.clearCallingIdentity();
8920        try {
8921            synchronized (this) {
8922                return mStackSupervisor.getStackInfoLocked(stackId);
8923            }
8924        } finally {
8925            Binder.restoreCallingIdentity(ident);
8926        }
8927    }
8928
8929    @Override
8930    public boolean isInHomeStack(int taskId) {
8931        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8932                "getStackInfo()");
8933        long ident = Binder.clearCallingIdentity();
8934        try {
8935            synchronized (this) {
8936                TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8937                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8938            }
8939        } finally {
8940            Binder.restoreCallingIdentity(ident);
8941        }
8942    }
8943
8944    @Override
8945    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8946        synchronized(this) {
8947            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8948        }
8949    }
8950
8951    @Override
8952    public void updateDeviceOwner(String packageName) {
8953        final int callingUid = Binder.getCallingUid();
8954        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
8955            throw new SecurityException("updateDeviceOwner called from non-system process");
8956        }
8957        synchronized (this) {
8958            mDeviceOwnerName = packageName;
8959        }
8960    }
8961
8962    @Override
8963    public void updateLockTaskPackages(int userId, String[] packages) {
8964        final int callingUid = Binder.getCallingUid();
8965        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
8966            throw new SecurityException("updateLockTaskPackage called from non-system process");
8967        }
8968        synchronized (this) {
8969            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
8970                    Arrays.toString(packages));
8971            mLockTaskPackages.put(userId, packages);
8972            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
8973        }
8974    }
8975
8976
8977    void startLockTaskModeLocked(TaskRecord task) {
8978        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
8979        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
8980            return;
8981        }
8982
8983        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
8984        // is initiated by system after the pinning request was shown and locked mode is initiated
8985        // by an authorized app directly
8986        final int callingUid = Binder.getCallingUid();
8987        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
8988        long ident = Binder.clearCallingIdentity();
8989        try {
8990            final ActivityStack stack = mStackSupervisor.getFocusedStack();
8991            if (!isSystemInitiated) {
8992                task.mLockTaskUid = callingUid;
8993                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
8994                    // startLockTask() called by app and task mode is lockTaskModeDefault.
8995                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
8996                    StatusBarManagerInternal statusBarManager =
8997                            LocalServices.getService(StatusBarManagerInternal.class);
8998                    if (statusBarManager != null) {
8999                        statusBarManager.showScreenPinningRequest();
9000                    }
9001                    return;
9002                }
9003
9004                if (stack == null || task != stack.topTask()) {
9005                    throw new IllegalArgumentException("Invalid task, not in foreground");
9006                }
9007            }
9008            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9009                    "Locking fully");
9010            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9011                    ActivityManager.LOCK_TASK_MODE_PINNED :
9012                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9013                    "startLockTask", true);
9014        } finally {
9015            Binder.restoreCallingIdentity(ident);
9016        }
9017    }
9018
9019    @Override
9020    public void startLockTaskMode(int taskId) {
9021        synchronized (this) {
9022            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9023            if (task != null) {
9024                startLockTaskModeLocked(task);
9025            }
9026        }
9027    }
9028
9029    @Override
9030    public void startLockTaskMode(IBinder token) {
9031        synchronized (this) {
9032            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9033            if (r == null) {
9034                return;
9035            }
9036            final TaskRecord task = r.task;
9037            if (task != null) {
9038                startLockTaskModeLocked(task);
9039            }
9040        }
9041    }
9042
9043    @Override
9044    public void startLockTaskModeOnCurrent() throws RemoteException {
9045        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9046                "startLockTaskModeOnCurrent");
9047        long ident = Binder.clearCallingIdentity();
9048        try {
9049            synchronized (this) {
9050                ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9051                if (r != null) {
9052                    startLockTaskModeLocked(r.task);
9053                }
9054            }
9055        } finally {
9056            Binder.restoreCallingIdentity(ident);
9057        }
9058    }
9059
9060    @Override
9061    public void stopLockTaskMode() {
9062        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9063        if (lockTask == null) {
9064            // Our work here is done.
9065            return;
9066        }
9067
9068        final int callingUid = Binder.getCallingUid();
9069        final int lockTaskUid = lockTask.mLockTaskUid;
9070        // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9071        // It is possible lockTaskMode was started by the system process because
9072        // android:lockTaskMode is set to a locking value in the application manifest instead of
9073        // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9074        // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9075        if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9076                callingUid != lockTaskUid
9077                && (lockTaskUid != 0
9078                    || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9079            throw new SecurityException("Invalid uid, expected " + lockTaskUid
9080                    + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9081        }
9082
9083        long ident = Binder.clearCallingIdentity();
9084        try {
9085            Log.d(TAG, "stopLockTaskMode");
9086            // Stop lock task
9087            synchronized (this) {
9088                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9089                        "stopLockTask", true);
9090            }
9091        } finally {
9092            Binder.restoreCallingIdentity(ident);
9093        }
9094    }
9095
9096    @Override
9097    public void stopLockTaskModeOnCurrent() throws RemoteException {
9098        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9099                "stopLockTaskModeOnCurrent");
9100        long ident = Binder.clearCallingIdentity();
9101        try {
9102            stopLockTaskMode();
9103        } finally {
9104            Binder.restoreCallingIdentity(ident);
9105        }
9106    }
9107
9108    @Override
9109    public boolean isInLockTaskMode() {
9110        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9111    }
9112
9113    @Override
9114    public int getLockTaskModeState() {
9115        synchronized (this) {
9116            return mStackSupervisor.getLockTaskModeState();
9117        }
9118    }
9119
9120    @Override
9121    public void showLockTaskEscapeMessage(IBinder token) {
9122        synchronized (this) {
9123            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9124            if (r == null) {
9125                return;
9126            }
9127            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9128        }
9129    }
9130
9131    // =========================================================
9132    // CONTENT PROVIDERS
9133    // =========================================================
9134
9135    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9136        List<ProviderInfo> providers = null;
9137        try {
9138            providers = AppGlobals.getPackageManager().
9139                queryContentProviders(app.processName, app.uid,
9140                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
9141        } catch (RemoteException ex) {
9142        }
9143        if (DEBUG_MU) Slog.v(TAG_MU,
9144                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9145        int userId = app.userId;
9146        if (providers != null) {
9147            int N = providers.size();
9148            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9149            for (int i=0; i<N; i++) {
9150                ProviderInfo cpi =
9151                    (ProviderInfo)providers.get(i);
9152                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9153                        cpi.name, cpi.flags);
9154                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_OWNER) {
9155                    // This is a singleton provider, but a user besides the
9156                    // default user is asking to initialize a process it runs
9157                    // in...  well, no, it doesn't actually run in this process,
9158                    // it runs in the process of the default user.  Get rid of it.
9159                    providers.remove(i);
9160                    N--;
9161                    i--;
9162                    continue;
9163                }
9164
9165                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9166                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9167                if (cpr == null) {
9168                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9169                    mProviderMap.putProviderByClass(comp, cpr);
9170                }
9171                if (DEBUG_MU) Slog.v(TAG_MU,
9172                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9173                app.pubProviders.put(cpi.name, cpr);
9174                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9175                    // Don't add this if it is a platform component that is marked
9176                    // to run in multiple processes, because this is actually
9177                    // part of the framework so doesn't make sense to track as a
9178                    // separate apk in the process.
9179                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9180                            mProcessStats);
9181                }
9182                ensurePackageDexOpt(cpi.applicationInfo.packageName);
9183            }
9184        }
9185        return providers;
9186    }
9187
9188    /**
9189     * Check if {@link ProcessRecord} has a possible chance at accessing the
9190     * given {@link ProviderInfo}. Final permission checking is always done
9191     * in {@link ContentProvider}.
9192     */
9193    private final String checkContentProviderPermissionLocked(
9194            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9195        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9196        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9197        boolean checkedGrants = false;
9198        if (checkUser) {
9199            // Looking for cross-user grants before enforcing the typical cross-users permissions
9200            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
9201            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9202                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9203                    return null;
9204                }
9205                checkedGrants = true;
9206            }
9207            userId = handleIncomingUser(callingPid, callingUid, userId,
9208                    false, ALLOW_NON_FULL,
9209                    "checkContentProviderPermissionLocked " + cpi.authority, null);
9210            if (userId != tmpTargetUserId) {
9211                // When we actually went to determine the final targer user ID, this ended
9212                // up different than our initial check for the authority.  This is because
9213                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9214                // SELF.  So we need to re-check the grants again.
9215                checkedGrants = false;
9216            }
9217        }
9218        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9219                cpi.applicationInfo.uid, cpi.exported)
9220                == PackageManager.PERMISSION_GRANTED) {
9221            return null;
9222        }
9223        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9224                cpi.applicationInfo.uid, cpi.exported)
9225                == PackageManager.PERMISSION_GRANTED) {
9226            return null;
9227        }
9228
9229        PathPermission[] pps = cpi.pathPermissions;
9230        if (pps != null) {
9231            int i = pps.length;
9232            while (i > 0) {
9233                i--;
9234                PathPermission pp = pps[i];
9235                String pprperm = pp.getReadPermission();
9236                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9237                        cpi.applicationInfo.uid, cpi.exported)
9238                        == PackageManager.PERMISSION_GRANTED) {
9239                    return null;
9240                }
9241                String ppwperm = pp.getWritePermission();
9242                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9243                        cpi.applicationInfo.uid, cpi.exported)
9244                        == PackageManager.PERMISSION_GRANTED) {
9245                    return null;
9246                }
9247            }
9248        }
9249        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9250            return null;
9251        }
9252
9253        String msg;
9254        if (!cpi.exported) {
9255            msg = "Permission Denial: opening provider " + cpi.name
9256                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9257                    + ", uid=" + callingUid + ") that is not exported from uid "
9258                    + cpi.applicationInfo.uid;
9259        } else {
9260            msg = "Permission Denial: opening provider " + cpi.name
9261                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9262                    + ", uid=" + callingUid + ") requires "
9263                    + cpi.readPermission + " or " + cpi.writePermission;
9264        }
9265        Slog.w(TAG, msg);
9266        return msg;
9267    }
9268
9269    /**
9270     * Returns if the ContentProvider has granted a uri to callingUid
9271     */
9272    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9273        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9274        if (perms != null) {
9275            for (int i=perms.size()-1; i>=0; i--) {
9276                GrantUri grantUri = perms.keyAt(i);
9277                if (grantUri.sourceUserId == userId || !checkUser) {
9278                    if (matchesProvider(grantUri.uri, cpi)) {
9279                        return true;
9280                    }
9281                }
9282            }
9283        }
9284        return false;
9285    }
9286
9287    /**
9288     * Returns true if the uri authority is one of the authorities specified in the provider.
9289     */
9290    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9291        String uriAuth = uri.getAuthority();
9292        String cpiAuth = cpi.authority;
9293        if (cpiAuth.indexOf(';') == -1) {
9294            return cpiAuth.equals(uriAuth);
9295        }
9296        String[] cpiAuths = cpiAuth.split(";");
9297        int length = cpiAuths.length;
9298        for (int i = 0; i < length; i++) {
9299            if (cpiAuths[i].equals(uriAuth)) return true;
9300        }
9301        return false;
9302    }
9303
9304    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9305            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9306        if (r != null) {
9307            for (int i=0; i<r.conProviders.size(); i++) {
9308                ContentProviderConnection conn = r.conProviders.get(i);
9309                if (conn.provider == cpr) {
9310                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9311                            "Adding provider requested by "
9312                            + r.processName + " from process "
9313                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9314                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9315                    if (stable) {
9316                        conn.stableCount++;
9317                        conn.numStableIncs++;
9318                    } else {
9319                        conn.unstableCount++;
9320                        conn.numUnstableIncs++;
9321                    }
9322                    return conn;
9323                }
9324            }
9325            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9326            if (stable) {
9327                conn.stableCount = 1;
9328                conn.numStableIncs = 1;
9329            } else {
9330                conn.unstableCount = 1;
9331                conn.numUnstableIncs = 1;
9332            }
9333            cpr.connections.add(conn);
9334            r.conProviders.add(conn);
9335            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9336            return conn;
9337        }
9338        cpr.addExternalProcessHandleLocked(externalProcessToken);
9339        return null;
9340    }
9341
9342    boolean decProviderCountLocked(ContentProviderConnection conn,
9343            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9344        if (conn != null) {
9345            cpr = conn.provider;
9346            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9347                    "Removing provider requested by "
9348                    + conn.client.processName + " from process "
9349                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9350                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9351            if (stable) {
9352                conn.stableCount--;
9353            } else {
9354                conn.unstableCount--;
9355            }
9356            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9357                cpr.connections.remove(conn);
9358                conn.client.conProviders.remove(conn);
9359                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9360                return true;
9361            }
9362            return false;
9363        }
9364        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9365        return false;
9366    }
9367
9368    private void checkTime(long startTime, String where) {
9369        long now = SystemClock.elapsedRealtime();
9370        if ((now-startTime) > 1000) {
9371            // If we are taking more than a second, log about it.
9372            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9373        }
9374    }
9375
9376    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9377            String name, IBinder token, boolean stable, int userId) {
9378        ContentProviderRecord cpr;
9379        ContentProviderConnection conn = null;
9380        ProviderInfo cpi = null;
9381
9382        synchronized(this) {
9383            long startTime = SystemClock.elapsedRealtime();
9384
9385            ProcessRecord r = null;
9386            if (caller != null) {
9387                r = getRecordForAppLocked(caller);
9388                if (r == null) {
9389                    throw new SecurityException(
9390                            "Unable to find app for caller " + caller
9391                          + " (pid=" + Binder.getCallingPid()
9392                          + ") when getting content provider " + name);
9393                }
9394            }
9395
9396            boolean checkCrossUser = true;
9397
9398            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9399
9400            // First check if this content provider has been published...
9401            cpr = mProviderMap.getProviderByName(name, userId);
9402            // If that didn't work, check if it exists for user 0 and then
9403            // verify that it's a singleton provider before using it.
9404            if (cpr == null && userId != UserHandle.USER_OWNER) {
9405                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9406                if (cpr != null) {
9407                    cpi = cpr.info;
9408                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9409                            cpi.name, cpi.flags)
9410                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9411                        userId = UserHandle.USER_OWNER;
9412                        checkCrossUser = false;
9413                    } else {
9414                        cpr = null;
9415                        cpi = null;
9416                    }
9417                }
9418            }
9419
9420            boolean providerRunning = cpr != null;
9421            if (providerRunning) {
9422                cpi = cpr.info;
9423                String msg;
9424                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9425                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9426                        != null) {
9427                    throw new SecurityException(msg);
9428                }
9429                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9430
9431                if (r != null && cpr.canRunHere(r)) {
9432                    // This provider has been published or is in the process
9433                    // of being published...  but it is also allowed to run
9434                    // in the caller's process, so don't make a connection
9435                    // and just let the caller instantiate its own instance.
9436                    ContentProviderHolder holder = cpr.newHolder(null);
9437                    // don't give caller the provider object, it needs
9438                    // to make its own.
9439                    holder.provider = null;
9440                    return holder;
9441                }
9442
9443                final long origId = Binder.clearCallingIdentity();
9444
9445                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9446
9447                // In this case the provider instance already exists, so we can
9448                // return it right away.
9449                conn = incProviderCountLocked(r, cpr, token, stable);
9450                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9451                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9452                        // If this is a perceptible app accessing the provider,
9453                        // make sure to count it as being accessed and thus
9454                        // back up on the LRU list.  This is good because
9455                        // content providers are often expensive to start.
9456                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9457                        updateLruProcessLocked(cpr.proc, false, null);
9458                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9459                    }
9460                }
9461
9462                if (cpr.proc != null) {
9463                    if (false) {
9464                        if (cpr.name.flattenToShortString().equals(
9465                                "com.android.providers.calendar/.CalendarProvider2")) {
9466                            Slog.v(TAG, "****************** KILLING "
9467                                + cpr.name.flattenToShortString());
9468                            Process.killProcess(cpr.proc.pid);
9469                        }
9470                    }
9471                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9472                    boolean success = updateOomAdjLocked(cpr.proc);
9473                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
9474                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9475                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
9476                    // NOTE: there is still a race here where a signal could be
9477                    // pending on the process even though we managed to update its
9478                    // adj level.  Not sure what to do about this, but at least
9479                    // the race is now smaller.
9480                    if (!success) {
9481                        // Uh oh...  it looks like the provider's process
9482                        // has been killed on us.  We need to wait for a new
9483                        // process to be started, and make sure its death
9484                        // doesn't kill our process.
9485                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
9486                                + " is crashing; detaching " + r);
9487                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9488                        checkTime(startTime, "getContentProviderImpl: before appDied");
9489                        appDiedLocked(cpr.proc);
9490                        checkTime(startTime, "getContentProviderImpl: after appDied");
9491                        if (!lastRef) {
9492                            // This wasn't the last ref our process had on
9493                            // the provider...  we have now been killed, bail.
9494                            return null;
9495                        }
9496                        providerRunning = false;
9497                        conn = null;
9498                    }
9499                }
9500
9501                Binder.restoreCallingIdentity(origId);
9502            }
9503
9504            boolean singleton;
9505            if (!providerRunning) {
9506                try {
9507                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9508                    cpi = AppGlobals.getPackageManager().
9509                        resolveContentProvider(name,
9510                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9511                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9512                } catch (RemoteException ex) {
9513                }
9514                if (cpi == null) {
9515                    return null;
9516                }
9517                // If the provider is a singleton AND
9518                // (it's a call within the same user || the provider is a
9519                // privileged app)
9520                // Then allow connecting to the singleton provider
9521                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9522                        cpi.name, cpi.flags)
9523                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9524                if (singleton) {
9525                    userId = UserHandle.USER_OWNER;
9526                }
9527                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9528                checkTime(startTime, "getContentProviderImpl: got app info for user");
9529
9530                String msg;
9531                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9532                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9533                        != null) {
9534                    throw new SecurityException(msg);
9535                }
9536                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9537
9538                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9539                        && !cpi.processName.equals("system")) {
9540                    // If this content provider does not run in the system
9541                    // process, and the system is not yet ready to run other
9542                    // processes, then fail fast instead of hanging.
9543                    throw new IllegalArgumentException(
9544                            "Attempt to launch content provider before system ready");
9545                }
9546
9547                // Make sure that the user who owns this provider is running.  If not,
9548                // we don't want to allow it to run.
9549                if (!isUserRunningLocked(userId, false)) {
9550                    Slog.w(TAG, "Unable to launch app "
9551                            + cpi.applicationInfo.packageName + "/"
9552                            + cpi.applicationInfo.uid + " for provider "
9553                            + name + ": user " + userId + " is stopped");
9554                    return null;
9555                }
9556
9557                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9558                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9559                cpr = mProviderMap.getProviderByClass(comp, userId);
9560                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9561                final boolean firstClass = cpr == null;
9562                if (firstClass) {
9563                    final long ident = Binder.clearCallingIdentity();
9564                    try {
9565                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9566                        ApplicationInfo ai =
9567                            AppGlobals.getPackageManager().
9568                                getApplicationInfo(
9569                                        cpi.applicationInfo.packageName,
9570                                        STOCK_PM_FLAGS, userId);
9571                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9572                        if (ai == null) {
9573                            Slog.w(TAG, "No package info for content provider "
9574                                    + cpi.name);
9575                            return null;
9576                        }
9577                        ai = getAppInfoForUser(ai, userId);
9578                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9579                    } catch (RemoteException ex) {
9580                        // pm is in same process, this will never happen.
9581                    } finally {
9582                        Binder.restoreCallingIdentity(ident);
9583                    }
9584                }
9585
9586                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9587
9588                if (r != null && cpr.canRunHere(r)) {
9589                    // If this is a multiprocess provider, then just return its
9590                    // info and allow the caller to instantiate it.  Only do
9591                    // this if the provider is the same user as the caller's
9592                    // process, or can run as root (so can be in any process).
9593                    return cpr.newHolder(null);
9594                }
9595
9596                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
9597                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
9598                            + cpr.info.name + " callers=" + Debug.getCallers(6));
9599
9600                // This is single process, and our app is now connecting to it.
9601                // See if we are already in the process of launching this
9602                // provider.
9603                final int N = mLaunchingProviders.size();
9604                int i;
9605                for (i = 0; i < N; i++) {
9606                    if (mLaunchingProviders.get(i) == cpr) {
9607                        break;
9608                    }
9609                }
9610
9611                // If the provider is not already being launched, then get it
9612                // started.
9613                if (i >= N) {
9614                    final long origId = Binder.clearCallingIdentity();
9615
9616                    try {
9617                        // Content provider is now in use, its package can't be stopped.
9618                        try {
9619                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9620                            AppGlobals.getPackageManager().setPackageStoppedState(
9621                                    cpr.appInfo.packageName, false, userId);
9622                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9623                        } catch (RemoteException e) {
9624                        } catch (IllegalArgumentException e) {
9625                            Slog.w(TAG, "Failed trying to unstop package "
9626                                    + cpr.appInfo.packageName + ": " + e);
9627                        }
9628
9629                        // Use existing process if already started
9630                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9631                        ProcessRecord proc = getProcessRecordLocked(
9632                                cpi.processName, cpr.appInfo.uid, false);
9633                        if (proc != null && proc.thread != null) {
9634                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
9635                                    "Installing in existing process " + proc);
9636                            if (!proc.pubProviders.containsKey(cpi.name)) {
9637                                checkTime(startTime, "getContentProviderImpl: scheduling install");
9638                                proc.pubProviders.put(cpi.name, cpr);
9639                                try {
9640                                    proc.thread.scheduleInstallProvider(cpi);
9641                                } catch (RemoteException e) {
9642                                }
9643                            }
9644                        } else {
9645                            checkTime(startTime, "getContentProviderImpl: before start process");
9646                            proc = startProcessLocked(cpi.processName,
9647                                    cpr.appInfo, false, 0, "content provider",
9648                                    new ComponentName(cpi.applicationInfo.packageName,
9649                                            cpi.name), false, false, false);
9650                            checkTime(startTime, "getContentProviderImpl: after start process");
9651                            if (proc == null) {
9652                                Slog.w(TAG, "Unable to launch app "
9653                                        + cpi.applicationInfo.packageName + "/"
9654                                        + cpi.applicationInfo.uid + " for provider "
9655                                        + name + ": process is bad");
9656                                return null;
9657                            }
9658                        }
9659                        cpr.launchingApp = proc;
9660                        mLaunchingProviders.add(cpr);
9661                    } finally {
9662                        Binder.restoreCallingIdentity(origId);
9663                    }
9664                }
9665
9666                checkTime(startTime, "getContentProviderImpl: updating data structures");
9667
9668                // Make sure the provider is published (the same provider class
9669                // may be published under multiple names).
9670                if (firstClass) {
9671                    mProviderMap.putProviderByClass(comp, cpr);
9672                }
9673
9674                mProviderMap.putProviderByName(name, cpr);
9675                conn = incProviderCountLocked(r, cpr, token, stable);
9676                if (conn != null) {
9677                    conn.waiting = true;
9678                }
9679            }
9680            checkTime(startTime, "getContentProviderImpl: done!");
9681        }
9682
9683        // Wait for the provider to be published...
9684        synchronized (cpr) {
9685            while (cpr.provider == null) {
9686                if (cpr.launchingApp == null) {
9687                    Slog.w(TAG, "Unable to launch app "
9688                            + cpi.applicationInfo.packageName + "/"
9689                            + cpi.applicationInfo.uid + " for provider "
9690                            + name + ": launching app became null");
9691                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9692                            UserHandle.getUserId(cpi.applicationInfo.uid),
9693                            cpi.applicationInfo.packageName,
9694                            cpi.applicationInfo.uid, name);
9695                    return null;
9696                }
9697                try {
9698                    if (DEBUG_MU) Slog.v(TAG_MU,
9699                            "Waiting to start provider " + cpr
9700                            + " launchingApp=" + cpr.launchingApp);
9701                    if (conn != null) {
9702                        conn.waiting = true;
9703                    }
9704                    cpr.wait();
9705                } catch (InterruptedException ex) {
9706                } finally {
9707                    if (conn != null) {
9708                        conn.waiting = false;
9709                    }
9710                }
9711            }
9712        }
9713        return cpr != null ? cpr.newHolder(conn) : null;
9714    }
9715
9716    @Override
9717    public final ContentProviderHolder getContentProvider(
9718            IApplicationThread caller, String name, int userId, boolean stable) {
9719        enforceNotIsolatedCaller("getContentProvider");
9720        if (caller == null) {
9721            String msg = "null IApplicationThread when getting content provider "
9722                    + name;
9723            Slog.w(TAG, msg);
9724            throw new SecurityException(msg);
9725        }
9726        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9727        // with cross-user grant.
9728        return getContentProviderImpl(caller, name, null, stable, userId);
9729    }
9730
9731    public ContentProviderHolder getContentProviderExternal(
9732            String name, int userId, IBinder token) {
9733        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9734            "Do not have permission in call getContentProviderExternal()");
9735        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9736                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9737        return getContentProviderExternalUnchecked(name, token, userId);
9738    }
9739
9740    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9741            IBinder token, int userId) {
9742        return getContentProviderImpl(null, name, token, true, userId);
9743    }
9744
9745    /**
9746     * Drop a content provider from a ProcessRecord's bookkeeping
9747     */
9748    public void removeContentProvider(IBinder connection, boolean stable) {
9749        enforceNotIsolatedCaller("removeContentProvider");
9750        long ident = Binder.clearCallingIdentity();
9751        try {
9752            synchronized (this) {
9753                ContentProviderConnection conn;
9754                try {
9755                    conn = (ContentProviderConnection)connection;
9756                } catch (ClassCastException e) {
9757                    String msg ="removeContentProvider: " + connection
9758                            + " not a ContentProviderConnection";
9759                    Slog.w(TAG, msg);
9760                    throw new IllegalArgumentException(msg);
9761                }
9762                if (conn == null) {
9763                    throw new NullPointerException("connection is null");
9764                }
9765                if (decProviderCountLocked(conn, null, null, stable)) {
9766                    updateOomAdjLocked();
9767                }
9768            }
9769        } finally {
9770            Binder.restoreCallingIdentity(ident);
9771        }
9772    }
9773
9774    public void removeContentProviderExternal(String name, IBinder token) {
9775        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9776            "Do not have permission in call removeContentProviderExternal()");
9777        int userId = UserHandle.getCallingUserId();
9778        long ident = Binder.clearCallingIdentity();
9779        try {
9780            removeContentProviderExternalUnchecked(name, token, userId);
9781        } finally {
9782            Binder.restoreCallingIdentity(ident);
9783        }
9784    }
9785
9786    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9787        synchronized (this) {
9788            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9789            if(cpr == null) {
9790                //remove from mProvidersByClass
9791                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
9792                return;
9793            }
9794
9795            //update content provider record entry info
9796            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9797            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9798            if (localCpr.hasExternalProcessHandles()) {
9799                if (localCpr.removeExternalProcessHandleLocked(token)) {
9800                    updateOomAdjLocked();
9801                } else {
9802                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9803                            + " with no external reference for token: "
9804                            + token + ".");
9805                }
9806            } else {
9807                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9808                        + " with no external references.");
9809            }
9810        }
9811    }
9812
9813    public final void publishContentProviders(IApplicationThread caller,
9814            List<ContentProviderHolder> providers) {
9815        if (providers == null) {
9816            return;
9817        }
9818
9819        enforceNotIsolatedCaller("publishContentProviders");
9820        synchronized (this) {
9821            final ProcessRecord r = getRecordForAppLocked(caller);
9822            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9823            if (r == null) {
9824                throw new SecurityException(
9825                        "Unable to find app for caller " + caller
9826                      + " (pid=" + Binder.getCallingPid()
9827                      + ") when publishing content providers");
9828            }
9829
9830            final long origId = Binder.clearCallingIdentity();
9831
9832            final int N = providers.size();
9833            for (int i=0; i<N; i++) {
9834                ContentProviderHolder src = providers.get(i);
9835                if (src == null || src.info == null || src.provider == null) {
9836                    continue;
9837                }
9838                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9839                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9840                if (dst != null) {
9841                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9842                    mProviderMap.putProviderByClass(comp, dst);
9843                    String names[] = dst.info.authority.split(";");
9844                    for (int j = 0; j < names.length; j++) {
9845                        mProviderMap.putProviderByName(names[j], dst);
9846                    }
9847
9848                    int NL = mLaunchingProviders.size();
9849                    int j;
9850                    for (j=0; j<NL; j++) {
9851                        if (mLaunchingProviders.get(j) == dst) {
9852                            mLaunchingProviders.remove(j);
9853                            j--;
9854                            NL--;
9855                        }
9856                    }
9857                    synchronized (dst) {
9858                        dst.provider = src.provider;
9859                        dst.proc = r;
9860                        dst.notifyAll();
9861                    }
9862                    updateOomAdjLocked(r);
9863                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
9864                            src.info.authority);
9865                }
9866            }
9867
9868            Binder.restoreCallingIdentity(origId);
9869        }
9870    }
9871
9872    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9873        ContentProviderConnection conn;
9874        try {
9875            conn = (ContentProviderConnection)connection;
9876        } catch (ClassCastException e) {
9877            String msg ="refContentProvider: " + connection
9878                    + " not a ContentProviderConnection";
9879            Slog.w(TAG, msg);
9880            throw new IllegalArgumentException(msg);
9881        }
9882        if (conn == null) {
9883            throw new NullPointerException("connection is null");
9884        }
9885
9886        synchronized (this) {
9887            if (stable > 0) {
9888                conn.numStableIncs += stable;
9889            }
9890            stable = conn.stableCount + stable;
9891            if (stable < 0) {
9892                throw new IllegalStateException("stableCount < 0: " + stable);
9893            }
9894
9895            if (unstable > 0) {
9896                conn.numUnstableIncs += unstable;
9897            }
9898            unstable = conn.unstableCount + unstable;
9899            if (unstable < 0) {
9900                throw new IllegalStateException("unstableCount < 0: " + unstable);
9901            }
9902
9903            if ((stable+unstable) <= 0) {
9904                throw new IllegalStateException("ref counts can't go to zero here: stable="
9905                        + stable + " unstable=" + unstable);
9906            }
9907            conn.stableCount = stable;
9908            conn.unstableCount = unstable;
9909            return !conn.dead;
9910        }
9911    }
9912
9913    public void unstableProviderDied(IBinder connection) {
9914        ContentProviderConnection conn;
9915        try {
9916            conn = (ContentProviderConnection)connection;
9917        } catch (ClassCastException e) {
9918            String msg ="refContentProvider: " + connection
9919                    + " not a ContentProviderConnection";
9920            Slog.w(TAG, msg);
9921            throw new IllegalArgumentException(msg);
9922        }
9923        if (conn == null) {
9924            throw new NullPointerException("connection is null");
9925        }
9926
9927        // Safely retrieve the content provider associated with the connection.
9928        IContentProvider provider;
9929        synchronized (this) {
9930            provider = conn.provider.provider;
9931        }
9932
9933        if (provider == null) {
9934            // Um, yeah, we're way ahead of you.
9935            return;
9936        }
9937
9938        // Make sure the caller is being honest with us.
9939        if (provider.asBinder().pingBinder()) {
9940            // Er, no, still looks good to us.
9941            synchronized (this) {
9942                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9943                        + " says " + conn + " died, but we don't agree");
9944                return;
9945            }
9946        }
9947
9948        // Well look at that!  It's dead!
9949        synchronized (this) {
9950            if (conn.provider.provider != provider) {
9951                // But something changed...  good enough.
9952                return;
9953            }
9954
9955            ProcessRecord proc = conn.provider.proc;
9956            if (proc == null || proc.thread == null) {
9957                // Seems like the process is already cleaned up.
9958                return;
9959            }
9960
9961            // As far as we're concerned, this is just like receiving a
9962            // death notification...  just a bit prematurely.
9963            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9964                    + ") early provider death");
9965            final long ident = Binder.clearCallingIdentity();
9966            try {
9967                appDiedLocked(proc);
9968            } finally {
9969                Binder.restoreCallingIdentity(ident);
9970            }
9971        }
9972    }
9973
9974    @Override
9975    public void appNotRespondingViaProvider(IBinder connection) {
9976        enforceCallingPermission(
9977                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9978
9979        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9980        if (conn == null) {
9981            Slog.w(TAG, "ContentProviderConnection is null");
9982            return;
9983        }
9984
9985        final ProcessRecord host = conn.provider.proc;
9986        if (host == null) {
9987            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9988            return;
9989        }
9990
9991        final long token = Binder.clearCallingIdentity();
9992        try {
9993            appNotResponding(host, null, null, false, "ContentProvider not responding");
9994        } finally {
9995            Binder.restoreCallingIdentity(token);
9996        }
9997    }
9998
9999    public final void installSystemProviders() {
10000        List<ProviderInfo> providers;
10001        synchronized (this) {
10002            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10003            providers = generateApplicationProvidersLocked(app);
10004            if (providers != null) {
10005                for (int i=providers.size()-1; i>=0; i--) {
10006                    ProviderInfo pi = (ProviderInfo)providers.get(i);
10007                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10008                        Slog.w(TAG, "Not installing system proc provider " + pi.name
10009                                + ": not system .apk");
10010                        providers.remove(i);
10011                    }
10012                }
10013            }
10014        }
10015        if (providers != null) {
10016            mSystemThread.installSystemProviders(providers);
10017        }
10018
10019        mCoreSettingsObserver = new CoreSettingsObserver(this);
10020
10021        //mUsageStatsService.monitorPackages();
10022    }
10023
10024    /**
10025     * Allows apps to retrieve the MIME type of a URI.
10026     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
10027     * users, then it does not need permission to access the ContentProvider.
10028     * Either, it needs cross-user uri grants.
10029     *
10030     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
10031     *
10032     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
10033     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
10034     */
10035    public String getProviderMimeType(Uri uri, int userId) {
10036        enforceNotIsolatedCaller("getProviderMimeType");
10037        final String name = uri.getAuthority();
10038        int callingUid = Binder.getCallingUid();
10039        int callingPid = Binder.getCallingPid();
10040        long ident = 0;
10041        boolean clearedIdentity = false;
10042        userId = unsafeConvertIncomingUser(userId);
10043        if (canClearIdentity(callingPid, callingUid, userId)) {
10044            clearedIdentity = true;
10045            ident = Binder.clearCallingIdentity();
10046        }
10047        ContentProviderHolder holder = null;
10048        try {
10049            holder = getContentProviderExternalUnchecked(name, null, userId);
10050            if (holder != null) {
10051                return holder.provider.getType(uri);
10052            }
10053        } catch (RemoteException e) {
10054            Log.w(TAG, "Content provider dead retrieving " + uri, e);
10055            return null;
10056        } finally {
10057            // We need to clear the identity to call removeContentProviderExternalUnchecked
10058            if (!clearedIdentity) {
10059                ident = Binder.clearCallingIdentity();
10060            }
10061            try {
10062                if (holder != null) {
10063                    removeContentProviderExternalUnchecked(name, null, userId);
10064                }
10065            } finally {
10066                Binder.restoreCallingIdentity(ident);
10067            }
10068        }
10069
10070        return null;
10071    }
10072
10073    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
10074        if (UserHandle.getUserId(callingUid) == userId) {
10075            return true;
10076        }
10077        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
10078                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
10079                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
10080                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
10081                return true;
10082        }
10083        return false;
10084    }
10085
10086    // =========================================================
10087    // GLOBAL MANAGEMENT
10088    // =========================================================
10089
10090    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
10091            boolean isolated, int isolatedUid) {
10092        String proc = customProcess != null ? customProcess : info.processName;
10093        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10094        final int userId = UserHandle.getUserId(info.uid);
10095        int uid = info.uid;
10096        if (isolated) {
10097            if (isolatedUid == 0) {
10098                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
10099                while (true) {
10100                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
10101                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
10102                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
10103                    }
10104                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
10105                    mNextIsolatedProcessUid++;
10106                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
10107                        // No process for this uid, use it.
10108                        break;
10109                    }
10110                    stepsLeft--;
10111                    if (stepsLeft <= 0) {
10112                        return null;
10113                    }
10114                }
10115            } else {
10116                // Special case for startIsolatedProcess (internal only), where
10117                // the uid of the isolated process is specified by the caller.
10118                uid = isolatedUid;
10119            }
10120        }
10121        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
10122        if (!mBooted && !mBooting
10123                && userId == UserHandle.USER_OWNER
10124                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10125            r.persistent = true;
10126        }
10127        addProcessNameLocked(r);
10128        return r;
10129    }
10130
10131    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
10132            String abiOverride) {
10133        ProcessRecord app;
10134        if (!isolated) {
10135            app = getProcessRecordLocked(info.processName, info.uid, true);
10136        } else {
10137            app = null;
10138        }
10139
10140        if (app == null) {
10141            app = newProcessRecordLocked(info, null, isolated, 0);
10142            updateLruProcessLocked(app, false, null);
10143            updateOomAdjLocked();
10144        }
10145
10146        // This package really, really can not be stopped.
10147        try {
10148            AppGlobals.getPackageManager().setPackageStoppedState(
10149                    info.packageName, false, UserHandle.getUserId(app.uid));
10150        } catch (RemoteException e) {
10151        } catch (IllegalArgumentException e) {
10152            Slog.w(TAG, "Failed trying to unstop package "
10153                    + info.packageName + ": " + e);
10154        }
10155
10156        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10157            app.persistent = true;
10158            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10159        }
10160        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10161            mPersistentStartingProcesses.add(app);
10162            startProcessLocked(app, "added application", app.processName, abiOverride,
10163                    null /* entryPoint */, null /* entryPointArgs */);
10164        }
10165
10166        return app;
10167    }
10168
10169    public void unhandledBack() {
10170        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10171                "unhandledBack()");
10172
10173        synchronized(this) {
10174            final long origId = Binder.clearCallingIdentity();
10175            try {
10176                getFocusedStack().unhandledBackLocked();
10177            } finally {
10178                Binder.restoreCallingIdentity(origId);
10179            }
10180        }
10181    }
10182
10183    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10184        enforceNotIsolatedCaller("openContentUri");
10185        final int userId = UserHandle.getCallingUserId();
10186        String name = uri.getAuthority();
10187        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10188        ParcelFileDescriptor pfd = null;
10189        if (cph != null) {
10190            // We record the binder invoker's uid in thread-local storage before
10191            // going to the content provider to open the file.  Later, in the code
10192            // that handles all permissions checks, we look for this uid and use
10193            // that rather than the Activity Manager's own uid.  The effect is that
10194            // we do the check against the caller's permissions even though it looks
10195            // to the content provider like the Activity Manager itself is making
10196            // the request.
10197            Binder token = new Binder();
10198            sCallerIdentity.set(new Identity(
10199                    token, Binder.getCallingPid(), Binder.getCallingUid()));
10200            try {
10201                pfd = cph.provider.openFile(null, uri, "r", null, token);
10202            } catch (FileNotFoundException e) {
10203                // do nothing; pfd will be returned null
10204            } finally {
10205                // Ensure that whatever happens, we clean up the identity state
10206                sCallerIdentity.remove();
10207                // Ensure we're done with the provider.
10208                removeContentProviderExternalUnchecked(name, null, userId);
10209            }
10210        } else {
10211            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10212        }
10213        return pfd;
10214    }
10215
10216    // Actually is sleeping or shutting down or whatever else in the future
10217    // is an inactive state.
10218    public boolean isSleepingOrShuttingDown() {
10219        return isSleeping() || mShuttingDown;
10220    }
10221
10222    public boolean isSleeping() {
10223        return mSleeping;
10224    }
10225
10226    void onWakefulnessChanged(int wakefulness) {
10227        synchronized(this) {
10228            mWakefulness = wakefulness;
10229            updateSleepIfNeededLocked();
10230        }
10231    }
10232
10233    void finishRunningVoiceLocked() {
10234        if (mRunningVoice != null) {
10235            mRunningVoice = null;
10236            mVoiceWakeLock.release();
10237            updateSleepIfNeededLocked();
10238        }
10239    }
10240
10241    void startTimeTrackingFocusedActivityLocked() {
10242        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
10243            mCurAppTimeTracker.start(mFocusedActivity.packageName);
10244        }
10245    }
10246
10247    void updateSleepIfNeededLocked() {
10248        if (mSleeping && !shouldSleepLocked()) {
10249            mSleeping = false;
10250            startTimeTrackingFocusedActivityLocked();
10251            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
10252            mStackSupervisor.comeOutOfSleepIfNeededLocked();
10253            updateOomAdjLocked();
10254        } else if (!mSleeping && shouldSleepLocked()) {
10255            mSleeping = true;
10256            if (mCurAppTimeTracker != null) {
10257                mCurAppTimeTracker.stop();
10258            }
10259            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
10260            mStackSupervisor.goingToSleepLocked();
10261            updateOomAdjLocked();
10262
10263            // Initialize the wake times of all processes.
10264            checkExcessivePowerUsageLocked(false);
10265            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10266            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10267            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10268        }
10269    }
10270
10271    private boolean shouldSleepLocked() {
10272        // Resume applications while running a voice interactor.
10273        if (mRunningVoice != null) {
10274            return false;
10275        }
10276
10277        // TODO: Transform the lock screen state into a sleep token instead.
10278        switch (mWakefulness) {
10279            case PowerManagerInternal.WAKEFULNESS_AWAKE:
10280            case PowerManagerInternal.WAKEFULNESS_DREAMING:
10281            case PowerManagerInternal.WAKEFULNESS_DOZING:
10282                // Pause applications whenever the lock screen is shown or any sleep
10283                // tokens have been acquired.
10284                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
10285            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10286            default:
10287                // If we're asleep then pause applications unconditionally.
10288                return true;
10289        }
10290    }
10291
10292    /** Pokes the task persister. */
10293    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10294        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10295            // Never persist the home stack.
10296            return;
10297        }
10298        mTaskPersister.wakeup(task, flush);
10299    }
10300
10301    /** Notifies all listeners when the task stack has changed. */
10302    void notifyTaskStackChangedLocked() {
10303        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10304        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10305        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10306    }
10307
10308    @Override
10309    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
10310        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
10311    }
10312
10313    @Override
10314    public boolean shutdown(int timeout) {
10315        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10316                != PackageManager.PERMISSION_GRANTED) {
10317            throw new SecurityException("Requires permission "
10318                    + android.Manifest.permission.SHUTDOWN);
10319        }
10320
10321        boolean timedout = false;
10322
10323        synchronized(this) {
10324            mShuttingDown = true;
10325            updateEventDispatchingLocked();
10326            timedout = mStackSupervisor.shutdownLocked(timeout);
10327        }
10328
10329        mAppOpsService.shutdown();
10330        if (mUsageStatsService != null) {
10331            mUsageStatsService.prepareShutdown();
10332        }
10333        mBatteryStatsService.shutdown();
10334        synchronized (this) {
10335            mProcessStats.shutdownLocked();
10336            notifyTaskPersisterLocked(null, true);
10337        }
10338
10339        return timedout;
10340    }
10341
10342    public final void activitySlept(IBinder token) {
10343        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
10344
10345        final long origId = Binder.clearCallingIdentity();
10346
10347        synchronized (this) {
10348            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10349            if (r != null) {
10350                mStackSupervisor.activitySleptLocked(r);
10351            }
10352        }
10353
10354        Binder.restoreCallingIdentity(origId);
10355    }
10356
10357    private String lockScreenShownToString() {
10358        switch (mLockScreenShown) {
10359            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10360            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10361            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10362            default: return "Unknown=" + mLockScreenShown;
10363        }
10364    }
10365
10366    void logLockScreen(String msg) {
10367        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
10368                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10369                + PowerManagerInternal.wakefulnessToString(mWakefulness)
10370                + " mSleeping=" + mSleeping);
10371    }
10372
10373    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
10374        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
10375        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
10376            boolean wasRunningVoice = mRunningVoice != null;
10377            mRunningVoice = session;
10378            if (!wasRunningVoice) {
10379                mVoiceWakeLock.acquire();
10380                updateSleepIfNeededLocked();
10381            }
10382        }
10383    }
10384
10385    private void updateEventDispatchingLocked() {
10386        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10387    }
10388
10389    public void setLockScreenShown(boolean shown) {
10390        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10391                != PackageManager.PERMISSION_GRANTED) {
10392            throw new SecurityException("Requires permission "
10393                    + android.Manifest.permission.DEVICE_POWER);
10394        }
10395
10396        synchronized(this) {
10397            long ident = Binder.clearCallingIdentity();
10398            try {
10399                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10400                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10401                updateSleepIfNeededLocked();
10402            } finally {
10403                Binder.restoreCallingIdentity(ident);
10404            }
10405        }
10406    }
10407
10408    @Override
10409    public void stopAppSwitches() {
10410        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10411                != PackageManager.PERMISSION_GRANTED) {
10412            throw new SecurityException("Requires permission "
10413                    + android.Manifest.permission.STOP_APP_SWITCHES);
10414        }
10415
10416        synchronized(this) {
10417            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10418                    + APP_SWITCH_DELAY_TIME;
10419            mDidAppSwitch = false;
10420            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10421            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10422            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10423        }
10424    }
10425
10426    public void resumeAppSwitches() {
10427        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10428                != PackageManager.PERMISSION_GRANTED) {
10429            throw new SecurityException("Requires permission "
10430                    + android.Manifest.permission.STOP_APP_SWITCHES);
10431        }
10432
10433        synchronized(this) {
10434            // Note that we don't execute any pending app switches... we will
10435            // let those wait until either the timeout, or the next start
10436            // activity request.
10437            mAppSwitchesAllowedTime = 0;
10438        }
10439    }
10440
10441    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10442            int callingPid, int callingUid, String name) {
10443        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10444            return true;
10445        }
10446
10447        int perm = checkComponentPermission(
10448                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10449                sourceUid, -1, true);
10450        if (perm == PackageManager.PERMISSION_GRANTED) {
10451            return true;
10452        }
10453
10454        // If the actual IPC caller is different from the logical source, then
10455        // also see if they are allowed to control app switches.
10456        if (callingUid != -1 && callingUid != sourceUid) {
10457            perm = checkComponentPermission(
10458                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10459                    callingUid, -1, true);
10460            if (perm == PackageManager.PERMISSION_GRANTED) {
10461                return true;
10462            }
10463        }
10464
10465        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10466        return false;
10467    }
10468
10469    public void setDebugApp(String packageName, boolean waitForDebugger,
10470            boolean persistent) {
10471        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10472                "setDebugApp()");
10473
10474        long ident = Binder.clearCallingIdentity();
10475        try {
10476            // Note that this is not really thread safe if there are multiple
10477            // callers into it at the same time, but that's not a situation we
10478            // care about.
10479            if (persistent) {
10480                final ContentResolver resolver = mContext.getContentResolver();
10481                Settings.Global.putString(
10482                    resolver, Settings.Global.DEBUG_APP,
10483                    packageName);
10484                Settings.Global.putInt(
10485                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10486                    waitForDebugger ? 1 : 0);
10487            }
10488
10489            synchronized (this) {
10490                if (!persistent) {
10491                    mOrigDebugApp = mDebugApp;
10492                    mOrigWaitForDebugger = mWaitForDebugger;
10493                }
10494                mDebugApp = packageName;
10495                mWaitForDebugger = waitForDebugger;
10496                mDebugTransient = !persistent;
10497                if (packageName != null) {
10498                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10499                            false, UserHandle.USER_ALL, "set debug app");
10500                }
10501            }
10502        } finally {
10503            Binder.restoreCallingIdentity(ident);
10504        }
10505    }
10506
10507    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10508        synchronized (this) {
10509            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10510            if (!isDebuggable) {
10511                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10512                    throw new SecurityException("Process not debuggable: " + app.packageName);
10513                }
10514            }
10515
10516            mOpenGlTraceApp = processName;
10517        }
10518    }
10519
10520    void setTrackAllocationApp(ApplicationInfo app, String processName) {
10521        synchronized (this) {
10522            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10523            if (!isDebuggable) {
10524                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10525                    throw new SecurityException("Process not debuggable: " + app.packageName);
10526                }
10527            }
10528
10529            mTrackAllocationApp = processName;
10530        }
10531    }
10532
10533    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10534        synchronized (this) {
10535            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10536            if (!isDebuggable) {
10537                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10538                    throw new SecurityException("Process not debuggable: " + app.packageName);
10539                }
10540            }
10541            mProfileApp = processName;
10542            mProfileFile = profilerInfo.profileFile;
10543            if (mProfileFd != null) {
10544                try {
10545                    mProfileFd.close();
10546                } catch (IOException e) {
10547                }
10548                mProfileFd = null;
10549            }
10550            mProfileFd = profilerInfo.profileFd;
10551            mSamplingInterval = profilerInfo.samplingInterval;
10552            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10553            mProfileType = 0;
10554        }
10555    }
10556
10557    @Override
10558    public void setAlwaysFinish(boolean enabled) {
10559        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10560                "setAlwaysFinish()");
10561
10562        Settings.Global.putInt(
10563                mContext.getContentResolver(),
10564                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10565
10566        synchronized (this) {
10567            mAlwaysFinishActivities = enabled;
10568        }
10569    }
10570
10571    @Override
10572    public void setActivityController(IActivityController controller) {
10573        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10574                "setActivityController()");
10575        synchronized (this) {
10576            mController = controller;
10577            Watchdog.getInstance().setActivityController(controller);
10578        }
10579    }
10580
10581    @Override
10582    public void setUserIsMonkey(boolean userIsMonkey) {
10583        synchronized (this) {
10584            synchronized (mPidsSelfLocked) {
10585                final int callingPid = Binder.getCallingPid();
10586                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10587                if (precessRecord == null) {
10588                    throw new SecurityException("Unknown process: " + callingPid);
10589                }
10590                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10591                    throw new SecurityException("Only an instrumentation process "
10592                            + "with a UiAutomation can call setUserIsMonkey");
10593                }
10594            }
10595            mUserIsMonkey = userIsMonkey;
10596        }
10597    }
10598
10599    @Override
10600    public boolean isUserAMonkey() {
10601        synchronized (this) {
10602            // If there is a controller also implies the user is a monkey.
10603            return (mUserIsMonkey || mController != null);
10604        }
10605    }
10606
10607    public void requestBugReport() {
10608        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10609        SystemProperties.set("ctl.start", "bugreport");
10610    }
10611
10612    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10613        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10614    }
10615
10616    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10617        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10618            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10619        }
10620        return KEY_DISPATCHING_TIMEOUT;
10621    }
10622
10623    @Override
10624    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10625        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10626                != PackageManager.PERMISSION_GRANTED) {
10627            throw new SecurityException("Requires permission "
10628                    + android.Manifest.permission.FILTER_EVENTS);
10629        }
10630        ProcessRecord proc;
10631        long timeout;
10632        synchronized (this) {
10633            synchronized (mPidsSelfLocked) {
10634                proc = mPidsSelfLocked.get(pid);
10635            }
10636            timeout = getInputDispatchingTimeoutLocked(proc);
10637        }
10638
10639        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10640            return -1;
10641        }
10642
10643        return timeout;
10644    }
10645
10646    /**
10647     * Handle input dispatching timeouts.
10648     * Returns whether input dispatching should be aborted or not.
10649     */
10650    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10651            final ActivityRecord activity, final ActivityRecord parent,
10652            final boolean aboveSystem, String reason) {
10653        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10654                != PackageManager.PERMISSION_GRANTED) {
10655            throw new SecurityException("Requires permission "
10656                    + android.Manifest.permission.FILTER_EVENTS);
10657        }
10658
10659        final String annotation;
10660        if (reason == null) {
10661            annotation = "Input dispatching timed out";
10662        } else {
10663            annotation = "Input dispatching timed out (" + reason + ")";
10664        }
10665
10666        if (proc != null) {
10667            synchronized (this) {
10668                if (proc.debugging) {
10669                    return false;
10670                }
10671
10672                if (mDidDexOpt) {
10673                    // Give more time since we were dexopting.
10674                    mDidDexOpt = false;
10675                    return false;
10676                }
10677
10678                if (proc.instrumentationClass != null) {
10679                    Bundle info = new Bundle();
10680                    info.putString("shortMsg", "keyDispatchingTimedOut");
10681                    info.putString("longMsg", annotation);
10682                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10683                    return true;
10684                }
10685            }
10686            mHandler.post(new Runnable() {
10687                @Override
10688                public void run() {
10689                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10690                }
10691            });
10692        }
10693
10694        return true;
10695    }
10696
10697    @Override
10698    public Bundle getAssistContextExtras(int requestType) {
10699        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
10700                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
10701        if (pae == null) {
10702            return null;
10703        }
10704        synchronized (pae) {
10705            while (!pae.haveResult) {
10706                try {
10707                    pae.wait();
10708                } catch (InterruptedException e) {
10709                }
10710            }
10711        }
10712        synchronized (this) {
10713            buildAssistBundleLocked(pae, pae.result);
10714            mPendingAssistExtras.remove(pae);
10715            mHandler.removeCallbacks(pae);
10716        }
10717        return pae.extras;
10718    }
10719
10720    @Override
10721    public boolean isScreenCaptureAllowedOnCurrentActivity() {
10722        int userId = mCurrentUserId;
10723        synchronized (this) {
10724            ActivityRecord activity = getFocusedStack().topActivity();
10725            if (activity == null) {
10726                return false;
10727            }
10728            userId = activity.userId;
10729        }
10730        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
10731                Context.DEVICE_POLICY_SERVICE);
10732        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
10733    }
10734
10735    @Override
10736    public void requestAssistContextExtras(int requestType, IResultReceiver receiver) {
10737        enqueueAssistContext(requestType, null, null, receiver, UserHandle.getCallingUserId(),
10738                null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT);
10739    }
10740
10741    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10742            IResultReceiver receiver, int userHandle, Bundle args, long timeout) {
10743        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10744                "enqueueAssistContext()");
10745        synchronized (this) {
10746            ActivityRecord activity = getFocusedStack().topActivity();
10747            if (activity == null) {
10748                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
10749                return null;
10750            }
10751            if (activity.app == null || activity.app.thread == null) {
10752                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10753                return null;
10754            }
10755            if (activity.app.pid == Binder.getCallingPid()) {
10756                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10757                return null;
10758            }
10759            PendingAssistExtras pae;
10760            Bundle extras = new Bundle();
10761            if (args != null) {
10762                extras.putAll(args);
10763            }
10764            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10765            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
10766            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
10767            try {
10768                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10769                        requestType);
10770                mPendingAssistExtras.add(pae);
10771                mHandler.postDelayed(pae, timeout);
10772            } catch (RemoteException e) {
10773                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10774                return null;
10775            }
10776            return pae;
10777        }
10778    }
10779
10780    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
10781        IResultReceiver receiver;
10782        synchronized (this) {
10783            mPendingAssistExtras.remove(pae);
10784            receiver = pae.receiver;
10785        }
10786        if (receiver != null) {
10787            // Caller wants result sent back to them.
10788            try {
10789                pae.receiver.send(0, null);
10790            } catch (RemoteException e) {
10791            }
10792        }
10793    }
10794
10795    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
10796        if (result != null) {
10797            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
10798        }
10799        if (pae.hint != null) {
10800            pae.extras.putBoolean(pae.hint, true);
10801        }
10802    }
10803
10804    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
10805            AssistContent content, Uri referrer) {
10806        PendingAssistExtras pae = (PendingAssistExtras)token;
10807        synchronized (pae) {
10808            pae.result = extras;
10809            pae.structure = structure;
10810            pae.content = content;
10811            if (referrer != null) {
10812                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
10813            }
10814            pae.haveResult = true;
10815            pae.notifyAll();
10816            if (pae.intent == null && pae.receiver == null) {
10817                // Caller is just waiting for the result.
10818                return;
10819            }
10820        }
10821
10822        // We are now ready to launch the assist activity.
10823        synchronized (this) {
10824            buildAssistBundleLocked(pae, extras);
10825            boolean exists = mPendingAssistExtras.remove(pae);
10826            mHandler.removeCallbacks(pae);
10827            if (!exists) {
10828                // Timed out.
10829                return;
10830            }
10831            if (pae.receiver != null) {
10832                // Caller wants result sent back to them.
10833                Bundle topBundle = new Bundle();
10834                topBundle.putBundle("data", pae.extras);
10835                topBundle.putParcelable("structure", pae.structure);
10836                topBundle.putParcelable("content", pae.content);
10837                try {
10838                    pae.receiver.send(0, topBundle);
10839                } catch (RemoteException e) {
10840                }
10841                return;
10842            }
10843        }
10844
10845        long ident = Binder.clearCallingIdentity();
10846        try {
10847            pae.intent.replaceExtras(pae.extras);
10848            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10849                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
10850                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10851            closeSystemDialogs("assist");
10852            try {
10853                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10854            } catch (ActivityNotFoundException e) {
10855                Slog.w(TAG, "No activity to handle assist action.", e);
10856            }
10857        } finally {
10858            Binder.restoreCallingIdentity(ident);
10859        }
10860    }
10861
10862    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
10863            Bundle args) {
10864        return enqueueAssistContext(requestType, intent, hint, null, userHandle, args,
10865                PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
10866    }
10867
10868    public void registerProcessObserver(IProcessObserver observer) {
10869        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10870                "registerProcessObserver()");
10871        synchronized (this) {
10872            mProcessObservers.register(observer);
10873        }
10874    }
10875
10876    @Override
10877    public void unregisterProcessObserver(IProcessObserver observer) {
10878        synchronized (this) {
10879            mProcessObservers.unregister(observer);
10880        }
10881    }
10882
10883    public void registerUidObserver(IUidObserver observer) {
10884        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10885                "registerUidObserver()");
10886        synchronized (this) {
10887            mUidObservers.register(observer);
10888        }
10889    }
10890
10891    @Override
10892    public void unregisterUidObserver(IUidObserver observer) {
10893        synchronized (this) {
10894            mUidObservers.unregister(observer);
10895        }
10896    }
10897
10898    @Override
10899    public boolean convertFromTranslucent(IBinder token) {
10900        final long origId = Binder.clearCallingIdentity();
10901        try {
10902            synchronized (this) {
10903                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10904                if (r == null) {
10905                    return false;
10906                }
10907                final boolean translucentChanged = r.changeWindowTranslucency(true);
10908                if (translucentChanged) {
10909                    r.task.stack.releaseBackgroundResources(r);
10910                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10911                }
10912                mWindowManager.setAppFullscreen(token, true);
10913                return translucentChanged;
10914            }
10915        } finally {
10916            Binder.restoreCallingIdentity(origId);
10917        }
10918    }
10919
10920    @Override
10921    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10922        final long origId = Binder.clearCallingIdentity();
10923        try {
10924            synchronized (this) {
10925                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10926                if (r == null) {
10927                    return false;
10928                }
10929                int index = r.task.mActivities.lastIndexOf(r);
10930                if (index > 0) {
10931                    ActivityRecord under = r.task.mActivities.get(index - 1);
10932                    under.returningOptions = options;
10933                }
10934                final boolean translucentChanged = r.changeWindowTranslucency(false);
10935                if (translucentChanged) {
10936                    r.task.stack.convertActivityToTranslucent(r);
10937                }
10938                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10939                mWindowManager.setAppFullscreen(token, false);
10940                return translucentChanged;
10941            }
10942        } finally {
10943            Binder.restoreCallingIdentity(origId);
10944        }
10945    }
10946
10947    @Override
10948    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10949        final long origId = Binder.clearCallingIdentity();
10950        try {
10951            synchronized (this) {
10952                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10953                if (r != null) {
10954                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10955                }
10956            }
10957            return false;
10958        } finally {
10959            Binder.restoreCallingIdentity(origId);
10960        }
10961    }
10962
10963    @Override
10964    public boolean isBackgroundVisibleBehind(IBinder token) {
10965        final long origId = Binder.clearCallingIdentity();
10966        try {
10967            synchronized (this) {
10968                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10969                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10970                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
10971                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10972                return visible;
10973            }
10974        } finally {
10975            Binder.restoreCallingIdentity(origId);
10976        }
10977    }
10978
10979    @Override
10980    public ActivityOptions getActivityOptions(IBinder token) {
10981        final long origId = Binder.clearCallingIdentity();
10982        try {
10983            synchronized (this) {
10984                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10985                if (r != null) {
10986                    final ActivityOptions activityOptions = r.pendingOptions;
10987                    r.pendingOptions = null;
10988                    return activityOptions;
10989                }
10990                return null;
10991            }
10992        } finally {
10993            Binder.restoreCallingIdentity(origId);
10994        }
10995    }
10996
10997    @Override
10998    public void setImmersive(IBinder token, boolean immersive) {
10999        synchronized(this) {
11000            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11001            if (r == null) {
11002                throw new IllegalArgumentException();
11003            }
11004            r.immersive = immersive;
11005
11006            // update associated state if we're frontmost
11007            if (r == mFocusedActivity) {
11008                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
11009                applyUpdateLockStateLocked(r);
11010            }
11011        }
11012    }
11013
11014    @Override
11015    public boolean isImmersive(IBinder token) {
11016        synchronized (this) {
11017            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11018            if (r == null) {
11019                throw new IllegalArgumentException();
11020            }
11021            return r.immersive;
11022        }
11023    }
11024
11025    public boolean isTopActivityImmersive() {
11026        enforceNotIsolatedCaller("startActivity");
11027        synchronized (this) {
11028            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
11029            return (r != null) ? r.immersive : false;
11030        }
11031    }
11032
11033    @Override
11034    public boolean isTopOfTask(IBinder token) {
11035        synchronized (this) {
11036            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11037            if (r == null) {
11038                throw new IllegalArgumentException();
11039            }
11040            return r.task.getTopActivity() == r;
11041        }
11042    }
11043
11044    public final void enterSafeMode() {
11045        synchronized(this) {
11046            // It only makes sense to do this before the system is ready
11047            // and started launching other packages.
11048            if (!mSystemReady) {
11049                try {
11050                    AppGlobals.getPackageManager().enterSafeMode();
11051                } catch (RemoteException e) {
11052                }
11053            }
11054
11055            mSafeMode = true;
11056        }
11057    }
11058
11059    public final void showSafeModeOverlay() {
11060        View v = LayoutInflater.from(mContext).inflate(
11061                com.android.internal.R.layout.safe_mode, null);
11062        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
11063        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
11064        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
11065        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
11066        lp.gravity = Gravity.BOTTOM | Gravity.START;
11067        lp.format = v.getBackground().getOpacity();
11068        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
11069                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
11070        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
11071        ((WindowManager)mContext.getSystemService(
11072                Context.WINDOW_SERVICE)).addView(v, lp);
11073    }
11074
11075    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
11076        if (!(sender instanceof PendingIntentRecord)) {
11077            return;
11078        }
11079        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11080        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11081        synchronized (stats) {
11082            if (mBatteryStatsService.isOnBattery()) {
11083                mBatteryStatsService.enforceCallingPermission();
11084                int MY_UID = Binder.getCallingUid();
11085                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11086                BatteryStatsImpl.Uid.Pkg pkg =
11087                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
11088                            sourcePkg != null ? sourcePkg : rec.key.packageName);
11089                pkg.noteWakeupAlarmLocked(tag);
11090            }
11091        }
11092    }
11093
11094    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
11095        if (!(sender instanceof PendingIntentRecord)) {
11096            return;
11097        }
11098        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11099        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11100        synchronized (stats) {
11101            mBatteryStatsService.enforceCallingPermission();
11102            int MY_UID = Binder.getCallingUid();
11103            int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11104            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
11105        }
11106    }
11107
11108    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
11109        if (!(sender instanceof PendingIntentRecord)) {
11110            return;
11111        }
11112        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11113        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11114        synchronized (stats) {
11115            mBatteryStatsService.enforceCallingPermission();
11116            int MY_UID = Binder.getCallingUid();
11117            int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11118            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
11119        }
11120    }
11121
11122    public boolean killPids(int[] pids, String pReason, boolean secure) {
11123        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11124            throw new SecurityException("killPids only available to the system");
11125        }
11126        String reason = (pReason == null) ? "Unknown" : pReason;
11127        // XXX Note: don't acquire main activity lock here, because the window
11128        // manager calls in with its locks held.
11129
11130        boolean killed = false;
11131        synchronized (mPidsSelfLocked) {
11132            int[] types = new int[pids.length];
11133            int worstType = 0;
11134            for (int i=0; i<pids.length; i++) {
11135                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11136                if (proc != null) {
11137                    int type = proc.setAdj;
11138                    types[i] = type;
11139                    if (type > worstType) {
11140                        worstType = type;
11141                    }
11142                }
11143            }
11144
11145            // If the worst oom_adj is somewhere in the cached proc LRU range,
11146            // then constrain it so we will kill all cached procs.
11147            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
11148                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
11149                worstType = ProcessList.CACHED_APP_MIN_ADJ;
11150            }
11151
11152            // If this is not a secure call, don't let it kill processes that
11153            // are important.
11154            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
11155                worstType = ProcessList.SERVICE_ADJ;
11156            }
11157
11158            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
11159            for (int i=0; i<pids.length; i++) {
11160                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11161                if (proc == null) {
11162                    continue;
11163                }
11164                int adj = proc.setAdj;
11165                if (adj >= worstType && !proc.killedByAm) {
11166                    proc.kill(reason, true);
11167                    killed = true;
11168                }
11169            }
11170        }
11171        return killed;
11172    }
11173
11174    @Override
11175    public void killUid(int uid, String reason) {
11176        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
11177        synchronized (this) {
11178            final long identity = Binder.clearCallingIdentity();
11179            try {
11180                killPackageProcessesLocked(null, UserHandle.getAppId(uid),
11181                        UserHandle.getUserId(uid),
11182                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
11183                        reason != null ? reason : "kill uid");
11184            } finally {
11185                Binder.restoreCallingIdentity(identity);
11186            }
11187        }
11188    }
11189
11190    @Override
11191    public boolean killProcessesBelowForeground(String reason) {
11192        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11193            throw new SecurityException("killProcessesBelowForeground() only available to system");
11194        }
11195
11196        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
11197    }
11198
11199    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
11200        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11201            throw new SecurityException("killProcessesBelowAdj() only available to system");
11202        }
11203
11204        boolean killed = false;
11205        synchronized (mPidsSelfLocked) {
11206            final int size = mPidsSelfLocked.size();
11207            for (int i = 0; i < size; i++) {
11208                final int pid = mPidsSelfLocked.keyAt(i);
11209                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11210                if (proc == null) continue;
11211
11212                final int adj = proc.setAdj;
11213                if (adj > belowAdj && !proc.killedByAm) {
11214                    proc.kill(reason, true);
11215                    killed = true;
11216                }
11217            }
11218        }
11219        return killed;
11220    }
11221
11222    @Override
11223    public void hang(final IBinder who, boolean allowRestart) {
11224        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11225                != PackageManager.PERMISSION_GRANTED) {
11226            throw new SecurityException("Requires permission "
11227                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11228        }
11229
11230        final IBinder.DeathRecipient death = new DeathRecipient() {
11231            @Override
11232            public void binderDied() {
11233                synchronized (this) {
11234                    notifyAll();
11235                }
11236            }
11237        };
11238
11239        try {
11240            who.linkToDeath(death, 0);
11241        } catch (RemoteException e) {
11242            Slog.w(TAG, "hang: given caller IBinder is already dead.");
11243            return;
11244        }
11245
11246        synchronized (this) {
11247            Watchdog.getInstance().setAllowRestart(allowRestart);
11248            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
11249            synchronized (death) {
11250                while (who.isBinderAlive()) {
11251                    try {
11252                        death.wait();
11253                    } catch (InterruptedException e) {
11254                    }
11255                }
11256            }
11257            Watchdog.getInstance().setAllowRestart(true);
11258        }
11259    }
11260
11261    @Override
11262    public void restart() {
11263        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11264                != PackageManager.PERMISSION_GRANTED) {
11265            throw new SecurityException("Requires permission "
11266                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11267        }
11268
11269        Log.i(TAG, "Sending shutdown broadcast...");
11270
11271        BroadcastReceiver br = new BroadcastReceiver() {
11272            @Override public void onReceive(Context context, Intent intent) {
11273                // Now the broadcast is done, finish up the low-level shutdown.
11274                Log.i(TAG, "Shutting down activity manager...");
11275                shutdown(10000);
11276                Log.i(TAG, "Shutdown complete, restarting!");
11277                Process.killProcess(Process.myPid());
11278                System.exit(10);
11279            }
11280        };
11281
11282        // First send the high-level shut down broadcast.
11283        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
11284        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
11285        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
11286        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
11287        mContext.sendOrderedBroadcastAsUser(intent,
11288                UserHandle.ALL, null, br, mHandler, 0, null, null);
11289        */
11290        br.onReceive(mContext, intent);
11291    }
11292
11293    private long getLowRamTimeSinceIdle(long now) {
11294        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
11295    }
11296
11297    @Override
11298    public void performIdleMaintenance() {
11299        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11300                != PackageManager.PERMISSION_GRANTED) {
11301            throw new SecurityException("Requires permission "
11302                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11303        }
11304
11305        synchronized (this) {
11306            final long now = SystemClock.uptimeMillis();
11307            final long timeSinceLastIdle = now - mLastIdleTime;
11308            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
11309            mLastIdleTime = now;
11310            mLowRamTimeSinceLastIdle = 0;
11311            if (mLowRamStartTime != 0) {
11312                mLowRamStartTime = now;
11313            }
11314
11315            StringBuilder sb = new StringBuilder(128);
11316            sb.append("Idle maintenance over ");
11317            TimeUtils.formatDuration(timeSinceLastIdle, sb);
11318            sb.append(" low RAM for ");
11319            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11320            Slog.i(TAG, sb.toString());
11321
11322            // If at least 1/3 of our time since the last idle period has been spent
11323            // with RAM low, then we want to kill processes.
11324            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
11325
11326            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11327                ProcessRecord proc = mLruProcesses.get(i);
11328                if (proc.notCachedSinceIdle) {
11329                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
11330                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
11331                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
11332                        if (doKilling && proc.initialIdlePss != 0
11333                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
11334                            sb = new StringBuilder(128);
11335                            sb.append("Kill");
11336                            sb.append(proc.processName);
11337                            sb.append(" in idle maint: pss=");
11338                            sb.append(proc.lastPss);
11339                            sb.append(", initialPss=");
11340                            sb.append(proc.initialIdlePss);
11341                            sb.append(", period=");
11342                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
11343                            sb.append(", lowRamPeriod=");
11344                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11345                            Slog.wtfQuiet(TAG, sb.toString());
11346                            proc.kill("idle maint (pss " + proc.lastPss
11347                                    + " from " + proc.initialIdlePss + ")", true);
11348                        }
11349                    }
11350                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
11351                    proc.notCachedSinceIdle = true;
11352                    proc.initialIdlePss = 0;
11353                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
11354                            mTestPssMode, isSleeping(), now);
11355                }
11356            }
11357
11358            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
11359            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
11360        }
11361    }
11362
11363    private void retrieveSettings() {
11364        final ContentResolver resolver = mContext.getContentResolver();
11365        String debugApp = Settings.Global.getString(
11366            resolver, Settings.Global.DEBUG_APP);
11367        boolean waitForDebugger = Settings.Global.getInt(
11368            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11369        boolean alwaysFinishActivities = Settings.Global.getInt(
11370            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11371        boolean forceRtl = Settings.Global.getInt(
11372                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11373        // Transfer any global setting for forcing RTL layout, into a System Property
11374        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11375
11376        Configuration configuration = new Configuration();
11377        Settings.System.getConfiguration(resolver, configuration);
11378        if (forceRtl) {
11379            // This will take care of setting the correct layout direction flags
11380            configuration.setLayoutDirection(configuration.locale);
11381        }
11382
11383        synchronized (this) {
11384            mDebugApp = mOrigDebugApp = debugApp;
11385            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11386            mAlwaysFinishActivities = alwaysFinishActivities;
11387            // This happens before any activities are started, so we can
11388            // change mConfiguration in-place.
11389            updateConfigurationLocked(configuration, null, false, true);
11390            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
11391                    "Initial config: " + mConfiguration);
11392        }
11393    }
11394
11395    /** Loads resources after the current configuration has been set. */
11396    private void loadResourcesOnSystemReady() {
11397        final Resources res = mContext.getResources();
11398        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11399        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11400        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11401    }
11402
11403    public boolean testIsSystemReady() {
11404        // no need to synchronize(this) just to read & return the value
11405        return mSystemReady;
11406    }
11407
11408    private static File getCalledPreBootReceiversFile() {
11409        File dataDir = Environment.getDataDirectory();
11410        File systemDir = new File(dataDir, "system");
11411        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11412        return fname;
11413    }
11414
11415    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11416        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11417        File file = getCalledPreBootReceiversFile();
11418        FileInputStream fis = null;
11419        try {
11420            fis = new FileInputStream(file);
11421            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11422            int fvers = dis.readInt();
11423            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11424                String vers = dis.readUTF();
11425                String codename = dis.readUTF();
11426                String build = dis.readUTF();
11427                if (android.os.Build.VERSION.RELEASE.equals(vers)
11428                        && android.os.Build.VERSION.CODENAME.equals(codename)
11429                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11430                    int num = dis.readInt();
11431                    while (num > 0) {
11432                        num--;
11433                        String pkg = dis.readUTF();
11434                        String cls = dis.readUTF();
11435                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11436                    }
11437                }
11438            }
11439        } catch (FileNotFoundException e) {
11440        } catch (IOException e) {
11441            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11442        } finally {
11443            if (fis != null) {
11444                try {
11445                    fis.close();
11446                } catch (IOException e) {
11447                }
11448            }
11449        }
11450        return lastDoneReceivers;
11451    }
11452
11453    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11454        File file = getCalledPreBootReceiversFile();
11455        FileOutputStream fos = null;
11456        DataOutputStream dos = null;
11457        try {
11458            fos = new FileOutputStream(file);
11459            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11460            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11461            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11462            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11463            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11464            dos.writeInt(list.size());
11465            for (int i=0; i<list.size(); i++) {
11466                dos.writeUTF(list.get(i).getPackageName());
11467                dos.writeUTF(list.get(i).getClassName());
11468            }
11469        } catch (IOException e) {
11470            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11471            file.delete();
11472        } finally {
11473            FileUtils.sync(fos);
11474            if (dos != null) {
11475                try {
11476                    dos.close();
11477                } catch (IOException e) {
11478                    // TODO Auto-generated catch block
11479                    e.printStackTrace();
11480                }
11481            }
11482        }
11483    }
11484
11485    final class PreBootContinuation extends IIntentReceiver.Stub {
11486        final Intent intent;
11487        final Runnable onFinishCallback;
11488        final ArrayList<ComponentName> doneReceivers;
11489        final List<ResolveInfo> ris;
11490        final int[] users;
11491        int lastRi = -1;
11492        int curRi = 0;
11493        int curUser = 0;
11494
11495        PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
11496                ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
11497            intent = _intent;
11498            onFinishCallback = _onFinishCallback;
11499            doneReceivers = _doneReceivers;
11500            ris = _ris;
11501            users = _users;
11502        }
11503
11504        void go() {
11505            if (lastRi != curRi) {
11506                ActivityInfo ai = ris.get(curRi).activityInfo;
11507                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11508                intent.setComponent(comp);
11509                doneReceivers.add(comp);
11510                lastRi = curRi;
11511                CharSequence label = ai.loadLabel(mContext.getPackageManager());
11512                showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
11513            }
11514            Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
11515                    + " for user " + users[curUser]);
11516            EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
11517            broadcastIntentLocked(null, null, intent, null, this,
11518                    0, null, null, null, AppOpsManager.OP_NONE,
11519                    null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
11520        }
11521
11522        public void performReceive(Intent intent, int resultCode,
11523                String data, Bundle extras, boolean ordered,
11524                boolean sticky, int sendingUser) {
11525            curUser++;
11526            if (curUser >= users.length) {
11527                curUser = 0;
11528                curRi++;
11529                if (curRi >= ris.size()) {
11530                    // All done sending broadcasts!
11531                    if (onFinishCallback != null) {
11532                        // The raw IIntentReceiver interface is called
11533                        // with the AM lock held, so redispatch to
11534                        // execute our code without the lock.
11535                        mHandler.post(onFinishCallback);
11536                    }
11537                    return;
11538                }
11539            }
11540            go();
11541        }
11542    }
11543
11544    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11545            ArrayList<ComponentName> doneReceivers, int userId) {
11546        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11547        List<ResolveInfo> ris = null;
11548        try {
11549            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11550                    intent, null, 0, userId);
11551        } catch (RemoteException e) {
11552        }
11553        if (ris == null) {
11554            return false;
11555        }
11556        for (int i=ris.size()-1; i>=0; i--) {
11557            if ((ris.get(i).activityInfo.applicationInfo.flags
11558                    &ApplicationInfo.FLAG_SYSTEM) == 0) {
11559                ris.remove(i);
11560            }
11561        }
11562        intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11563
11564        // For User 0, load the version number. When delivering to a new user, deliver
11565        // to all receivers.
11566        if (userId == UserHandle.USER_OWNER) {
11567            ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11568            for (int i=0; i<ris.size(); i++) {
11569                ActivityInfo ai = ris.get(i).activityInfo;
11570                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11571                if (lastDoneReceivers.contains(comp)) {
11572                    // We already did the pre boot receiver for this app with the current
11573                    // platform version, so don't do it again...
11574                    ris.remove(i);
11575                    i--;
11576                    // ...however, do keep it as one that has been done, so we don't
11577                    // forget about it when rewriting the file of last done receivers.
11578                    doneReceivers.add(comp);
11579                }
11580            }
11581        }
11582
11583        if (ris.size() <= 0) {
11584            return false;
11585        }
11586
11587        // If primary user, send broadcast to all available users, else just to userId
11588        final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11589                : new int[] { userId };
11590        if (users.length <= 0) {
11591            return false;
11592        }
11593
11594        PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
11595                ris, users);
11596        cont.go();
11597        return true;
11598    }
11599
11600    public void systemReady(final Runnable goingCallback) {
11601        synchronized(this) {
11602            if (mSystemReady) {
11603                // If we're done calling all the receivers, run the next "boot phase" passed in
11604                // by the SystemServer
11605                if (goingCallback != null) {
11606                    goingCallback.run();
11607                }
11608                return;
11609            }
11610
11611            mLocalDeviceIdleController
11612                    = LocalServices.getService(DeviceIdleController.LocalService.class);
11613
11614            // Make sure we have the current profile info, since it is needed for
11615            // security checks.
11616            updateCurrentProfileIdsLocked();
11617
11618            mRecentTasks.clear();
11619            mRecentTasks.addAll(mTaskPersister.restoreTasksLocked());
11620            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
11621            mTaskPersister.startPersisting();
11622
11623            // Check to see if there are any update receivers to run.
11624            if (!mDidUpdate) {
11625                if (mWaitingUpdate) {
11626                    return;
11627                }
11628                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11629                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11630                    public void run() {
11631                        synchronized (ActivityManagerService.this) {
11632                            mDidUpdate = true;
11633                        }
11634                        showBootMessage(mContext.getText(
11635                                R.string.android_upgrading_complete),
11636                                false);
11637                        writeLastDonePreBootReceivers(doneReceivers);
11638                        systemReady(goingCallback);
11639                    }
11640                }, doneReceivers, UserHandle.USER_OWNER);
11641
11642                if (mWaitingUpdate) {
11643                    return;
11644                }
11645                mDidUpdate = true;
11646            }
11647
11648            mAppOpsService.systemReady();
11649            mSystemReady = true;
11650        }
11651
11652        ArrayList<ProcessRecord> procsToKill = null;
11653        synchronized(mPidsSelfLocked) {
11654            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11655                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11656                if (!isAllowedWhileBooting(proc.info)){
11657                    if (procsToKill == null) {
11658                        procsToKill = new ArrayList<ProcessRecord>();
11659                    }
11660                    procsToKill.add(proc);
11661                }
11662            }
11663        }
11664
11665        synchronized(this) {
11666            if (procsToKill != null) {
11667                for (int i=procsToKill.size()-1; i>=0; i--) {
11668                    ProcessRecord proc = procsToKill.get(i);
11669                    Slog.i(TAG, "Removing system update proc: " + proc);
11670                    removeProcessLocked(proc, true, false, "system update done");
11671                }
11672            }
11673
11674            // Now that we have cleaned up any update processes, we
11675            // are ready to start launching real processes and know that
11676            // we won't trample on them any more.
11677            mProcessesReady = true;
11678        }
11679
11680        Slog.i(TAG, "System now ready");
11681        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11682            SystemClock.uptimeMillis());
11683
11684        synchronized(this) {
11685            // Make sure we have no pre-ready processes sitting around.
11686
11687            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11688                ResolveInfo ri = mContext.getPackageManager()
11689                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11690                                STOCK_PM_FLAGS);
11691                CharSequence errorMsg = null;
11692                if (ri != null) {
11693                    ActivityInfo ai = ri.activityInfo;
11694                    ApplicationInfo app = ai.applicationInfo;
11695                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11696                        mTopAction = Intent.ACTION_FACTORY_TEST;
11697                        mTopData = null;
11698                        mTopComponent = new ComponentName(app.packageName,
11699                                ai.name);
11700                    } else {
11701                        errorMsg = mContext.getResources().getText(
11702                                com.android.internal.R.string.factorytest_not_system);
11703                    }
11704                } else {
11705                    errorMsg = mContext.getResources().getText(
11706                            com.android.internal.R.string.factorytest_no_action);
11707                }
11708                if (errorMsg != null) {
11709                    mTopAction = null;
11710                    mTopData = null;
11711                    mTopComponent = null;
11712                    Message msg = Message.obtain();
11713                    msg.what = SHOW_FACTORY_ERROR_MSG;
11714                    msg.getData().putCharSequence("msg", errorMsg);
11715                    mUiHandler.sendMessage(msg);
11716                }
11717            }
11718        }
11719
11720        retrieveSettings();
11721        loadResourcesOnSystemReady();
11722
11723        synchronized (this) {
11724            readGrantedUriPermissionsLocked();
11725        }
11726
11727        if (goingCallback != null) goingCallback.run();
11728
11729        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11730                Integer.toString(mCurrentUserId), mCurrentUserId);
11731        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11732                Integer.toString(mCurrentUserId), mCurrentUserId);
11733        mSystemServiceManager.startUser(mCurrentUserId);
11734
11735        synchronized (this) {
11736            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11737                try {
11738                    List apps = AppGlobals.getPackageManager().
11739                        getPersistentApplications(STOCK_PM_FLAGS);
11740                    if (apps != null) {
11741                        int N = apps.size();
11742                        int i;
11743                        for (i=0; i<N; i++) {
11744                            ApplicationInfo info
11745                                = (ApplicationInfo)apps.get(i);
11746                            if (info != null &&
11747                                    !info.packageName.equals("android")) {
11748                                addAppLocked(info, false, null /* ABI override */);
11749                            }
11750                        }
11751                    }
11752                } catch (RemoteException ex) {
11753                    // pm is in same process, this will never happen.
11754                }
11755            }
11756
11757            // Start up initial activity.
11758            mBooting = true;
11759            startHomeActivityLocked(mCurrentUserId, "systemReady");
11760
11761            try {
11762                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11763                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11764                            + " data partition or your device will be unstable.");
11765                    mUiHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11766                }
11767            } catch (RemoteException e) {
11768            }
11769
11770            if (!Build.isBuildConsistent()) {
11771                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11772                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11773            }
11774
11775            long ident = Binder.clearCallingIdentity();
11776            try {
11777                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11778                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11779                        | Intent.FLAG_RECEIVER_FOREGROUND);
11780                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11781                broadcastIntentLocked(null, null, intent,
11782                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11783                        null, false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11784                intent = new Intent(Intent.ACTION_USER_STARTING);
11785                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11786                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11787                broadcastIntentLocked(null, null, intent,
11788                        null, new IIntentReceiver.Stub() {
11789                            @Override
11790                            public void performReceive(Intent intent, int resultCode, String data,
11791                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11792                                    throws RemoteException {
11793                            }
11794                        }, 0, null, null,
11795                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
11796                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11797            } catch (Throwable t) {
11798                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11799            } finally {
11800                Binder.restoreCallingIdentity(ident);
11801            }
11802            mStackSupervisor.resumeTopActivitiesLocked();
11803            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11804        }
11805    }
11806
11807    private boolean makeAppCrashingLocked(ProcessRecord app,
11808            String shortMsg, String longMsg, String stackTrace) {
11809        app.crashing = true;
11810        app.crashingReport = generateProcessError(app,
11811                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11812        startAppProblemLocked(app);
11813        app.stopFreezingAllLocked();
11814        return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
11815    }
11816
11817    private void makeAppNotRespondingLocked(ProcessRecord app,
11818            String activity, String shortMsg, String longMsg) {
11819        app.notResponding = true;
11820        app.notRespondingReport = generateProcessError(app,
11821                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11822                activity, shortMsg, longMsg, null);
11823        startAppProblemLocked(app);
11824        app.stopFreezingAllLocked();
11825    }
11826
11827    /**
11828     * Generate a process error record, suitable for attachment to a ProcessRecord.
11829     *
11830     * @param app The ProcessRecord in which the error occurred.
11831     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11832     *                      ActivityManager.AppErrorStateInfo
11833     * @param activity The activity associated with the crash, if known.
11834     * @param shortMsg Short message describing the crash.
11835     * @param longMsg Long message describing the crash.
11836     * @param stackTrace Full crash stack trace, may be null.
11837     *
11838     * @return Returns a fully-formed AppErrorStateInfo record.
11839     */
11840    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11841            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11842        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11843
11844        report.condition = condition;
11845        report.processName = app.processName;
11846        report.pid = app.pid;
11847        report.uid = app.info.uid;
11848        report.tag = activity;
11849        report.shortMsg = shortMsg;
11850        report.longMsg = longMsg;
11851        report.stackTrace = stackTrace;
11852
11853        return report;
11854    }
11855
11856    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11857        synchronized (this) {
11858            app.crashing = false;
11859            app.crashingReport = null;
11860            app.notResponding = false;
11861            app.notRespondingReport = null;
11862            if (app.anrDialog == fromDialog) {
11863                app.anrDialog = null;
11864            }
11865            if (app.waitDialog == fromDialog) {
11866                app.waitDialog = null;
11867            }
11868            if (app.pid > 0 && app.pid != MY_PID) {
11869                handleAppCrashLocked(app, "user-terminated" /*reason*/,
11870                        null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
11871                app.kill("user request after error", true);
11872            }
11873        }
11874    }
11875
11876    private boolean handleAppCrashLocked(ProcessRecord app, String reason,
11877            String shortMsg, String longMsg, String stackTrace) {
11878        long now = SystemClock.uptimeMillis();
11879
11880        Long crashTime;
11881        if (!app.isolated) {
11882            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11883        } else {
11884            crashTime = null;
11885        }
11886        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11887            // This process loses!
11888            Slog.w(TAG, "Process " + app.info.processName
11889                    + " has crashed too many times: killing!");
11890            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11891                    app.userId, app.info.processName, app.uid);
11892            mStackSupervisor.handleAppCrashLocked(app);
11893            if (!app.persistent) {
11894                // We don't want to start this process again until the user
11895                // explicitly does so...  but for persistent process, we really
11896                // need to keep it running.  If a persistent process is actually
11897                // repeatedly crashing, then badness for everyone.
11898                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11899                        app.info.processName);
11900                if (!app.isolated) {
11901                    // XXX We don't have a way to mark isolated processes
11902                    // as bad, since they don't have a peristent identity.
11903                    mBadProcesses.put(app.info.processName, app.uid,
11904                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11905                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11906                }
11907                app.bad = true;
11908                app.removed = true;
11909                // Don't let services in this process be restarted and potentially
11910                // annoy the user repeatedly.  Unless it is persistent, since those
11911                // processes run critical code.
11912                removeProcessLocked(app, false, false, "crash");
11913                mStackSupervisor.resumeTopActivitiesLocked();
11914                return false;
11915            }
11916            mStackSupervisor.resumeTopActivitiesLocked();
11917        } else {
11918            mStackSupervisor.finishTopRunningActivityLocked(app, reason);
11919        }
11920
11921        // Bump up the crash count of any services currently running in the proc.
11922        for (int i=app.services.size()-1; i>=0; i--) {
11923            // Any services running in the application need to be placed
11924            // back in the pending list.
11925            ServiceRecord sr = app.services.valueAt(i);
11926            sr.crashCount++;
11927        }
11928
11929        // If the crashing process is what we consider to be the "home process" and it has been
11930        // replaced by a third-party app, clear the package preferred activities from packages
11931        // with a home activity running in the process to prevent a repeatedly crashing app
11932        // from blocking the user to manually clear the list.
11933        final ArrayList<ActivityRecord> activities = app.activities;
11934        if (app == mHomeProcess && activities.size() > 0
11935                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11936            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11937                final ActivityRecord r = activities.get(activityNdx);
11938                if (r.isHomeActivity()) {
11939                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11940                    try {
11941                        ActivityThread.getPackageManager()
11942                                .clearPackagePreferredActivities(r.packageName);
11943                    } catch (RemoteException c) {
11944                        // pm is in same process, this will never happen.
11945                    }
11946                }
11947            }
11948        }
11949
11950        if (!app.isolated) {
11951            // XXX Can't keep track of crash times for isolated processes,
11952            // because they don't have a perisistent identity.
11953            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11954        }
11955
11956        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11957        return true;
11958    }
11959
11960    void startAppProblemLocked(ProcessRecord app) {
11961        // If this app is not running under the current user, then we
11962        // can't give it a report button because that would require
11963        // launching the report UI under a different user.
11964        app.errorReportReceiver = null;
11965
11966        for (int userId : mCurrentProfileIds) {
11967            if (app.userId == userId) {
11968                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11969                        mContext, app.info.packageName, app.info.flags);
11970            }
11971        }
11972        skipCurrentReceiverLocked(app);
11973    }
11974
11975    void skipCurrentReceiverLocked(ProcessRecord app) {
11976        for (BroadcastQueue queue : mBroadcastQueues) {
11977            queue.skipCurrentReceiverLocked(app);
11978        }
11979    }
11980
11981    /**
11982     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11983     * The application process will exit immediately after this call returns.
11984     * @param app object of the crashing app, null for the system server
11985     * @param crashInfo describing the exception
11986     */
11987    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11988        ProcessRecord r = findAppProcess(app, "Crash");
11989        final String processName = app == null ? "system_server"
11990                : (r == null ? "unknown" : r.processName);
11991
11992        handleApplicationCrashInner("crash", r, processName, crashInfo);
11993    }
11994
11995    /* Native crash reporting uses this inner version because it needs to be somewhat
11996     * decoupled from the AM-managed cleanup lifecycle
11997     */
11998    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11999            ApplicationErrorReport.CrashInfo crashInfo) {
12000        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12001                UserHandle.getUserId(Binder.getCallingUid()), processName,
12002                r == null ? -1 : r.info.flags,
12003                crashInfo.exceptionClassName,
12004                crashInfo.exceptionMessage,
12005                crashInfo.throwFileName,
12006                crashInfo.throwLineNumber);
12007
12008        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12009
12010        crashApplication(r, crashInfo);
12011    }
12012
12013    public void handleApplicationStrictModeViolation(
12014            IBinder app,
12015            int violationMask,
12016            StrictMode.ViolationInfo info) {
12017        ProcessRecord r = findAppProcess(app, "StrictMode");
12018        if (r == null) {
12019            return;
12020        }
12021
12022        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12023            Integer stackFingerprint = info.hashCode();
12024            boolean logIt = true;
12025            synchronized (mAlreadyLoggedViolatedStacks) {
12026                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12027                    logIt = false;
12028                    // TODO: sub-sample into EventLog for these, with
12029                    // the info.durationMillis?  Then we'd get
12030                    // the relative pain numbers, without logging all
12031                    // the stack traces repeatedly.  We'd want to do
12032                    // likewise in the client code, which also does
12033                    // dup suppression, before the Binder call.
12034                } else {
12035                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12036                        mAlreadyLoggedViolatedStacks.clear();
12037                    }
12038                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12039                }
12040            }
12041            if (logIt) {
12042                logStrictModeViolationToDropBox(r, info);
12043            }
12044        }
12045
12046        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12047            AppErrorResult result = new AppErrorResult();
12048            synchronized (this) {
12049                final long origId = Binder.clearCallingIdentity();
12050
12051                Message msg = Message.obtain();
12052                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
12053                HashMap<String, Object> data = new HashMap<String, Object>();
12054                data.put("result", result);
12055                data.put("app", r);
12056                data.put("violationMask", violationMask);
12057                data.put("info", info);
12058                msg.obj = data;
12059                mUiHandler.sendMessage(msg);
12060
12061                Binder.restoreCallingIdentity(origId);
12062            }
12063            int res = result.get();
12064            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12065        }
12066    }
12067
12068    // Depending on the policy in effect, there could be a bunch of
12069    // these in quick succession so we try to batch these together to
12070    // minimize disk writes, number of dropbox entries, and maximize
12071    // compression, by having more fewer, larger records.
12072    private void logStrictModeViolationToDropBox(
12073            ProcessRecord process,
12074            StrictMode.ViolationInfo info) {
12075        if (info == null) {
12076            return;
12077        }
12078        final boolean isSystemApp = process == null ||
12079                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12080                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12081        final String processName = process == null ? "unknown" : process.processName;
12082        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12083        final DropBoxManager dbox = (DropBoxManager)
12084                mContext.getSystemService(Context.DROPBOX_SERVICE);
12085
12086        // Exit early if the dropbox isn't configured to accept this report type.
12087        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12088
12089        boolean bufferWasEmpty;
12090        boolean needsFlush;
12091        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12092        synchronized (sb) {
12093            bufferWasEmpty = sb.length() == 0;
12094            appendDropBoxProcessHeaders(process, processName, sb);
12095            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12096            sb.append("System-App: ").append(isSystemApp).append("\n");
12097            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12098            if (info.violationNumThisLoop != 0) {
12099                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12100            }
12101            if (info.numAnimationsRunning != 0) {
12102                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12103            }
12104            if (info.broadcastIntentAction != null) {
12105                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12106            }
12107            if (info.durationMillis != -1) {
12108                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12109            }
12110            if (info.numInstances != -1) {
12111                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12112            }
12113            if (info.tags != null) {
12114                for (String tag : info.tags) {
12115                    sb.append("Span-Tag: ").append(tag).append("\n");
12116                }
12117            }
12118            sb.append("\n");
12119            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
12120                sb.append(info.crashInfo.stackTrace);
12121                sb.append("\n");
12122            }
12123            if (info.message != null) {
12124                sb.append(info.message);
12125                sb.append("\n");
12126            }
12127
12128            // Only buffer up to ~64k.  Various logging bits truncate
12129            // things at 128k.
12130            needsFlush = (sb.length() > 64 * 1024);
12131        }
12132
12133        // Flush immediately if the buffer's grown too large, or this
12134        // is a non-system app.  Non-system apps are isolated with a
12135        // different tag & policy and not batched.
12136        //
12137        // Batching is useful during internal testing with
12138        // StrictMode settings turned up high.  Without batching,
12139        // thousands of separate files could be created on boot.
12140        if (!isSystemApp || needsFlush) {
12141            new Thread("Error dump: " + dropboxTag) {
12142                @Override
12143                public void run() {
12144                    String report;
12145                    synchronized (sb) {
12146                        report = sb.toString();
12147                        sb.delete(0, sb.length());
12148                        sb.trimToSize();
12149                    }
12150                    if (report.length() != 0) {
12151                        dbox.addText(dropboxTag, report);
12152                    }
12153                }
12154            }.start();
12155            return;
12156        }
12157
12158        // System app batching:
12159        if (!bufferWasEmpty) {
12160            // An existing dropbox-writing thread is outstanding, so
12161            // we don't need to start it up.  The existing thread will
12162            // catch the buffer appends we just did.
12163            return;
12164        }
12165
12166        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
12167        // (After this point, we shouldn't access AMS internal data structures.)
12168        new Thread("Error dump: " + dropboxTag) {
12169            @Override
12170            public void run() {
12171                // 5 second sleep to let stacks arrive and be batched together
12172                try {
12173                    Thread.sleep(5000);  // 5 seconds
12174                } catch (InterruptedException e) {}
12175
12176                String errorReport;
12177                synchronized (mStrictModeBuffer) {
12178                    errorReport = mStrictModeBuffer.toString();
12179                    if (errorReport.length() == 0) {
12180                        return;
12181                    }
12182                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
12183                    mStrictModeBuffer.trimToSize();
12184                }
12185                dbox.addText(dropboxTag, errorReport);
12186            }
12187        }.start();
12188    }
12189
12190    /**
12191     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
12192     * @param app object of the crashing app, null for the system server
12193     * @param tag reported by the caller
12194     * @param system whether this wtf is coming from the system
12195     * @param crashInfo describing the context of the error
12196     * @return true if the process should exit immediately (WTF is fatal)
12197     */
12198    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
12199            final ApplicationErrorReport.CrashInfo crashInfo) {
12200        final int callingUid = Binder.getCallingUid();
12201        final int callingPid = Binder.getCallingPid();
12202
12203        if (system) {
12204            // If this is coming from the system, we could very well have low-level
12205            // system locks held, so we want to do this all asynchronously.  And we
12206            // never want this to become fatal, so there is that too.
12207            mHandler.post(new Runnable() {
12208                @Override public void run() {
12209                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
12210                }
12211            });
12212            return false;
12213        }
12214
12215        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
12216                crashInfo);
12217
12218        if (r != null && r.pid != Process.myPid() &&
12219                Settings.Global.getInt(mContext.getContentResolver(),
12220                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
12221            crashApplication(r, crashInfo);
12222            return true;
12223        } else {
12224            return false;
12225        }
12226    }
12227
12228    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
12229            final ApplicationErrorReport.CrashInfo crashInfo) {
12230        final ProcessRecord r = findAppProcess(app, "WTF");
12231        final String processName = app == null ? "system_server"
12232                : (r == null ? "unknown" : r.processName);
12233
12234        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
12235                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
12236
12237        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
12238
12239        return r;
12240    }
12241
12242    /**
12243     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
12244     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
12245     */
12246    private ProcessRecord findAppProcess(IBinder app, String reason) {
12247        if (app == null) {
12248            return null;
12249        }
12250
12251        synchronized (this) {
12252            final int NP = mProcessNames.getMap().size();
12253            for (int ip=0; ip<NP; ip++) {
12254                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12255                final int NA = apps.size();
12256                for (int ia=0; ia<NA; ia++) {
12257                    ProcessRecord p = apps.valueAt(ia);
12258                    if (p.thread != null && p.thread.asBinder() == app) {
12259                        return p;
12260                    }
12261                }
12262            }
12263
12264            Slog.w(TAG, "Can't find mystery application for " + reason
12265                    + " from pid=" + Binder.getCallingPid()
12266                    + " uid=" + Binder.getCallingUid() + ": " + app);
12267            return null;
12268        }
12269    }
12270
12271    /**
12272     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
12273     * to append various headers to the dropbox log text.
12274     */
12275    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
12276            StringBuilder sb) {
12277        // Watchdog thread ends up invoking this function (with
12278        // a null ProcessRecord) to add the stack file to dropbox.
12279        // Do not acquire a lock on this (am) in such cases, as it
12280        // could cause a potential deadlock, if and when watchdog
12281        // is invoked due to unavailability of lock on am and it
12282        // would prevent watchdog from killing system_server.
12283        if (process == null) {
12284            sb.append("Process: ").append(processName).append("\n");
12285            return;
12286        }
12287        // Note: ProcessRecord 'process' is guarded by the service
12288        // instance.  (notably process.pkgList, which could otherwise change
12289        // concurrently during execution of this method)
12290        synchronized (this) {
12291            sb.append("Process: ").append(processName).append("\n");
12292            int flags = process.info.flags;
12293            IPackageManager pm = AppGlobals.getPackageManager();
12294            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
12295            for (int ip=0; ip<process.pkgList.size(); ip++) {
12296                String pkg = process.pkgList.keyAt(ip);
12297                sb.append("Package: ").append(pkg);
12298                try {
12299                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
12300                    if (pi != null) {
12301                        sb.append(" v").append(pi.versionCode);
12302                        if (pi.versionName != null) {
12303                            sb.append(" (").append(pi.versionName).append(")");
12304                        }
12305                    }
12306                } catch (RemoteException e) {
12307                    Slog.e(TAG, "Error getting package info: " + pkg, e);
12308                }
12309                sb.append("\n");
12310            }
12311        }
12312    }
12313
12314    private static String processClass(ProcessRecord process) {
12315        if (process == null || process.pid == MY_PID) {
12316            return "system_server";
12317        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
12318            return "system_app";
12319        } else {
12320            return "data_app";
12321        }
12322    }
12323
12324    /**
12325     * Write a description of an error (crash, WTF, ANR) to the drop box.
12326     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
12327     * @param process which caused the error, null means the system server
12328     * @param activity which triggered the error, null if unknown
12329     * @param parent activity related to the error, null if unknown
12330     * @param subject line related to the error, null if absent
12331     * @param report in long form describing the error, null if absent
12332     * @param logFile to include in the report, null if none
12333     * @param crashInfo giving an application stack trace, null if absent
12334     */
12335    public void addErrorToDropBox(String eventType,
12336            ProcessRecord process, String processName, ActivityRecord activity,
12337            ActivityRecord parent, String subject,
12338            final String report, final File logFile,
12339            final ApplicationErrorReport.CrashInfo crashInfo) {
12340        // NOTE -- this must never acquire the ActivityManagerService lock,
12341        // otherwise the watchdog may be prevented from resetting the system.
12342
12343        final String dropboxTag = processClass(process) + "_" + eventType;
12344        final DropBoxManager dbox = (DropBoxManager)
12345                mContext.getSystemService(Context.DROPBOX_SERVICE);
12346
12347        // Exit early if the dropbox isn't configured to accept this report type.
12348        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12349
12350        final StringBuilder sb = new StringBuilder(1024);
12351        appendDropBoxProcessHeaders(process, processName, sb);
12352        if (activity != null) {
12353            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
12354        }
12355        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
12356            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
12357        }
12358        if (parent != null && parent != activity) {
12359            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
12360        }
12361        if (subject != null) {
12362            sb.append("Subject: ").append(subject).append("\n");
12363        }
12364        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12365        if (Debug.isDebuggerConnected()) {
12366            sb.append("Debugger: Connected\n");
12367        }
12368        sb.append("\n");
12369
12370        // Do the rest in a worker thread to avoid blocking the caller on I/O
12371        // (After this point, we shouldn't access AMS internal data structures.)
12372        Thread worker = new Thread("Error dump: " + dropboxTag) {
12373            @Override
12374            public void run() {
12375                if (report != null) {
12376                    sb.append(report);
12377                }
12378                if (logFile != null) {
12379                    try {
12380                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
12381                                    "\n\n[[TRUNCATED]]"));
12382                    } catch (IOException e) {
12383                        Slog.e(TAG, "Error reading " + logFile, e);
12384                    }
12385                }
12386                if (crashInfo != null && crashInfo.stackTrace != null) {
12387                    sb.append(crashInfo.stackTrace);
12388                }
12389
12390                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
12391                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
12392                if (lines > 0) {
12393                    sb.append("\n");
12394
12395                    // Merge several logcat streams, and take the last N lines
12396                    InputStreamReader input = null;
12397                    try {
12398                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
12399                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
12400                                "-b", "crash",
12401                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
12402
12403                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
12404                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
12405                        input = new InputStreamReader(logcat.getInputStream());
12406
12407                        int num;
12408                        char[] buf = new char[8192];
12409                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
12410                    } catch (IOException e) {
12411                        Slog.e(TAG, "Error running logcat", e);
12412                    } finally {
12413                        if (input != null) try { input.close(); } catch (IOException e) {}
12414                    }
12415                }
12416
12417                dbox.addText(dropboxTag, sb.toString());
12418            }
12419        };
12420
12421        if (process == null) {
12422            // If process is null, we are being called from some internal code
12423            // and may be about to die -- run this synchronously.
12424            worker.run();
12425        } else {
12426            worker.start();
12427        }
12428    }
12429
12430    /**
12431     * Bring up the "unexpected error" dialog box for a crashing app.
12432     * Deal with edge cases (intercepts from instrumented applications,
12433     * ActivityController, error intent receivers, that sort of thing).
12434     * @param r the application crashing
12435     * @param crashInfo describing the failure
12436     */
12437    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12438        long timeMillis = System.currentTimeMillis();
12439        String shortMsg = crashInfo.exceptionClassName;
12440        String longMsg = crashInfo.exceptionMessage;
12441        String stackTrace = crashInfo.stackTrace;
12442        if (shortMsg != null && longMsg != null) {
12443            longMsg = shortMsg + ": " + longMsg;
12444        } else if (shortMsg != null) {
12445            longMsg = shortMsg;
12446        }
12447
12448        AppErrorResult result = new AppErrorResult();
12449        synchronized (this) {
12450            if (mController != null) {
12451                try {
12452                    String name = r != null ? r.processName : null;
12453                    int pid = r != null ? r.pid : Binder.getCallingPid();
12454                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
12455                    if (!mController.appCrashed(name, pid,
12456                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12457                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12458                                && "Native crash".equals(crashInfo.exceptionClassName)) {
12459                            Slog.w(TAG, "Skip killing native crashed app " + name
12460                                    + "(" + pid + ") during testing");
12461                        } else {
12462                            Slog.w(TAG, "Force-killing crashed app " + name
12463                                    + " at watcher's request");
12464                            if (r != null) {
12465                                r.kill("crash", true);
12466                            } else {
12467                                // Huh.
12468                                Process.killProcess(pid);
12469                                killProcessGroup(uid, pid);
12470                            }
12471                        }
12472                        return;
12473                    }
12474                } catch (RemoteException e) {
12475                    mController = null;
12476                    Watchdog.getInstance().setActivityController(null);
12477                }
12478            }
12479
12480            final long origId = Binder.clearCallingIdentity();
12481
12482            // If this process is running instrumentation, finish it.
12483            if (r != null && r.instrumentationClass != null) {
12484                Slog.w(TAG, "Error in app " + r.processName
12485                      + " running instrumentation " + r.instrumentationClass + ":");
12486                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12487                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12488                Bundle info = new Bundle();
12489                info.putString("shortMsg", shortMsg);
12490                info.putString("longMsg", longMsg);
12491                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12492                Binder.restoreCallingIdentity(origId);
12493                return;
12494            }
12495
12496            // Log crash in battery stats.
12497            if (r != null) {
12498                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12499            }
12500
12501            // If we can't identify the process or it's already exceeded its crash quota,
12502            // quit right away without showing a crash dialog.
12503            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12504                Binder.restoreCallingIdentity(origId);
12505                return;
12506            }
12507
12508            Message msg = Message.obtain();
12509            msg.what = SHOW_ERROR_MSG;
12510            HashMap data = new HashMap();
12511            data.put("result", result);
12512            data.put("app", r);
12513            msg.obj = data;
12514            mUiHandler.sendMessage(msg);
12515
12516            Binder.restoreCallingIdentity(origId);
12517        }
12518
12519        int res = result.get();
12520
12521        Intent appErrorIntent = null;
12522        synchronized (this) {
12523            if (r != null && !r.isolated) {
12524                // XXX Can't keep track of crash time for isolated processes,
12525                // since they don't have a persistent identity.
12526                mProcessCrashTimes.put(r.info.processName, r.uid,
12527                        SystemClock.uptimeMillis());
12528            }
12529            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12530                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12531            }
12532        }
12533
12534        if (appErrorIntent != null) {
12535            try {
12536                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12537            } catch (ActivityNotFoundException e) {
12538                Slog.w(TAG, "bug report receiver dissappeared", e);
12539            }
12540        }
12541    }
12542
12543    Intent createAppErrorIntentLocked(ProcessRecord r,
12544            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12545        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12546        if (report == null) {
12547            return null;
12548        }
12549        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12550        result.setComponent(r.errorReportReceiver);
12551        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12552        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12553        return result;
12554    }
12555
12556    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12557            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12558        if (r.errorReportReceiver == null) {
12559            return null;
12560        }
12561
12562        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12563            return null;
12564        }
12565
12566        ApplicationErrorReport report = new ApplicationErrorReport();
12567        report.packageName = r.info.packageName;
12568        report.installerPackageName = r.errorReportReceiver.getPackageName();
12569        report.processName = r.processName;
12570        report.time = timeMillis;
12571        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12572
12573        if (r.crashing || r.forceCrashReport) {
12574            report.type = ApplicationErrorReport.TYPE_CRASH;
12575            report.crashInfo = crashInfo;
12576        } else if (r.notResponding) {
12577            report.type = ApplicationErrorReport.TYPE_ANR;
12578            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12579
12580            report.anrInfo.activity = r.notRespondingReport.tag;
12581            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12582            report.anrInfo.info = r.notRespondingReport.longMsg;
12583        }
12584
12585        return report;
12586    }
12587
12588    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12589        enforceNotIsolatedCaller("getProcessesInErrorState");
12590        // assume our apps are happy - lazy create the list
12591        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12592
12593        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12594                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12595        int userId = UserHandle.getUserId(Binder.getCallingUid());
12596
12597        synchronized (this) {
12598
12599            // iterate across all processes
12600            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12601                ProcessRecord app = mLruProcesses.get(i);
12602                if (!allUsers && app.userId != userId) {
12603                    continue;
12604                }
12605                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12606                    // This one's in trouble, so we'll generate a report for it
12607                    // crashes are higher priority (in case there's a crash *and* an anr)
12608                    ActivityManager.ProcessErrorStateInfo report = null;
12609                    if (app.crashing) {
12610                        report = app.crashingReport;
12611                    } else if (app.notResponding) {
12612                        report = app.notRespondingReport;
12613                    }
12614
12615                    if (report != null) {
12616                        if (errList == null) {
12617                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12618                        }
12619                        errList.add(report);
12620                    } else {
12621                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12622                                " crashing = " + app.crashing +
12623                                " notResponding = " + app.notResponding);
12624                    }
12625                }
12626            }
12627        }
12628
12629        return errList;
12630    }
12631
12632    static int procStateToImportance(int procState, int memAdj,
12633            ActivityManager.RunningAppProcessInfo currApp) {
12634        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12635        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12636            currApp.lru = memAdj;
12637        } else {
12638            currApp.lru = 0;
12639        }
12640        return imp;
12641    }
12642
12643    private void fillInProcMemInfo(ProcessRecord app,
12644            ActivityManager.RunningAppProcessInfo outInfo) {
12645        outInfo.pid = app.pid;
12646        outInfo.uid = app.info.uid;
12647        if (mHeavyWeightProcess == app) {
12648            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12649        }
12650        if (app.persistent) {
12651            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12652        }
12653        if (app.activities.size() > 0) {
12654            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12655        }
12656        outInfo.lastTrimLevel = app.trimMemoryLevel;
12657        int adj = app.curAdj;
12658        int procState = app.curProcState;
12659        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12660        outInfo.importanceReasonCode = app.adjTypeCode;
12661        outInfo.processState = app.curProcState;
12662    }
12663
12664    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12665        enforceNotIsolatedCaller("getRunningAppProcesses");
12666
12667        final int callingUid = Binder.getCallingUid();
12668
12669        // Lazy instantiation of list
12670        List<ActivityManager.RunningAppProcessInfo> runList = null;
12671        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12672                callingUid) == PackageManager.PERMISSION_GRANTED;
12673        final int userId = UserHandle.getUserId(callingUid);
12674        final boolean allUids = isGetTasksAllowed(
12675                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
12676
12677        synchronized (this) {
12678            // Iterate across all processes
12679            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
12680                ProcessRecord app = mLruProcesses.get(i);
12681                if ((!allUsers && app.userId != userId)
12682                        || (!allUids && app.uid != callingUid)) {
12683                    continue;
12684                }
12685                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12686                    // Generate process state info for running application
12687                    ActivityManager.RunningAppProcessInfo currApp =
12688                        new ActivityManager.RunningAppProcessInfo(app.processName,
12689                                app.pid, app.getPackageList());
12690                    fillInProcMemInfo(app, currApp);
12691                    if (app.adjSource instanceof ProcessRecord) {
12692                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12693                        currApp.importanceReasonImportance =
12694                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12695                                        app.adjSourceProcState);
12696                    } else if (app.adjSource instanceof ActivityRecord) {
12697                        ActivityRecord r = (ActivityRecord)app.adjSource;
12698                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12699                    }
12700                    if (app.adjTarget instanceof ComponentName) {
12701                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12702                    }
12703                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12704                    //        + " lru=" + currApp.lru);
12705                    if (runList == null) {
12706                        runList = new ArrayList<>();
12707                    }
12708                    runList.add(currApp);
12709                }
12710            }
12711        }
12712        return runList;
12713    }
12714
12715    public List<ApplicationInfo> getRunningExternalApplications() {
12716        enforceNotIsolatedCaller("getRunningExternalApplications");
12717        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12718        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12719        if (runningApps != null && runningApps.size() > 0) {
12720            Set<String> extList = new HashSet<String>();
12721            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12722                if (app.pkgList != null) {
12723                    for (String pkg : app.pkgList) {
12724                        extList.add(pkg);
12725                    }
12726                }
12727            }
12728            IPackageManager pm = AppGlobals.getPackageManager();
12729            for (String pkg : extList) {
12730                try {
12731                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12732                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12733                        retList.add(info);
12734                    }
12735                } catch (RemoteException e) {
12736                }
12737            }
12738        }
12739        return retList;
12740    }
12741
12742    @Override
12743    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12744        enforceNotIsolatedCaller("getMyMemoryState");
12745        synchronized (this) {
12746            ProcessRecord proc;
12747            synchronized (mPidsSelfLocked) {
12748                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12749            }
12750            fillInProcMemInfo(proc, outInfo);
12751        }
12752    }
12753
12754    @Override
12755    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12756        if (checkCallingPermission(android.Manifest.permission.DUMP)
12757                != PackageManager.PERMISSION_GRANTED) {
12758            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12759                    + Binder.getCallingPid()
12760                    + ", uid=" + Binder.getCallingUid()
12761                    + " without permission "
12762                    + android.Manifest.permission.DUMP);
12763            return;
12764        }
12765
12766        boolean dumpAll = false;
12767        boolean dumpClient = false;
12768        String dumpPackage = null;
12769
12770        int opti = 0;
12771        while (opti < args.length) {
12772            String opt = args[opti];
12773            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12774                break;
12775            }
12776            opti++;
12777            if ("-a".equals(opt)) {
12778                dumpAll = true;
12779            } else if ("-c".equals(opt)) {
12780                dumpClient = true;
12781            } else if ("-p".equals(opt)) {
12782                if (opti < args.length) {
12783                    dumpPackage = args[opti];
12784                    opti++;
12785                } else {
12786                    pw.println("Error: -p option requires package argument");
12787                    return;
12788                }
12789                dumpClient = true;
12790            } else if ("-h".equals(opt)) {
12791                pw.println("Activity manager dump options:");
12792                pw.println("  [-a] [-c] [-p package] [-h] [cmd] ...");
12793                pw.println("  cmd may be one of:");
12794                pw.println("    a[ctivities]: activity stack state");
12795                pw.println("    r[recents]: recent activities state");
12796                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12797                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12798                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12799                pw.println("    o[om]: out of memory management");
12800                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12801                pw.println("    provider [COMP_SPEC]: provider client-side state");
12802                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12803                pw.println("    as[sociations]: tracked app associations");
12804                pw.println("    service [COMP_SPEC]: service client-side state");
12805                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12806                pw.println("    all: dump all activities");
12807                pw.println("    top: dump the top activity");
12808                pw.println("    write: write all pending state to storage");
12809                pw.println("    track-associations: enable association tracking");
12810                pw.println("    untrack-associations: disable and clear association tracking");
12811                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12812                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12813                pw.println("    a partial substring in a component name, a");
12814                pw.println("    hex object identifier.");
12815                pw.println("  -a: include all available server state.");
12816                pw.println("  -c: include client state.");
12817                pw.println("  -p: limit output to given package.");
12818                return;
12819            } else {
12820                pw.println("Unknown argument: " + opt + "; use -h for help");
12821            }
12822        }
12823
12824        long origId = Binder.clearCallingIdentity();
12825        boolean more = false;
12826        // Is the caller requesting to dump a particular piece of data?
12827        if (opti < args.length) {
12828            String cmd = args[opti];
12829            opti++;
12830            if ("activities".equals(cmd) || "a".equals(cmd)) {
12831                synchronized (this) {
12832                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12833                }
12834            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12835                synchronized (this) {
12836                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
12837                }
12838            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12839                String[] newArgs;
12840                String name;
12841                if (opti >= args.length) {
12842                    name = null;
12843                    newArgs = EMPTY_STRING_ARRAY;
12844                } else {
12845                    dumpPackage = args[opti];
12846                    opti++;
12847                    newArgs = new String[args.length - opti];
12848                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12849                            args.length - opti);
12850                }
12851                synchronized (this) {
12852                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
12853                }
12854            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12855                String[] newArgs;
12856                String name;
12857                if (opti >= args.length) {
12858                    name = null;
12859                    newArgs = EMPTY_STRING_ARRAY;
12860                } else {
12861                    dumpPackage = args[opti];
12862                    opti++;
12863                    newArgs = new String[args.length - opti];
12864                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12865                            args.length - opti);
12866                }
12867                synchronized (this) {
12868                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
12869                }
12870            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12871                String[] newArgs;
12872                String name;
12873                if (opti >= args.length) {
12874                    name = null;
12875                    newArgs = EMPTY_STRING_ARRAY;
12876                } else {
12877                    dumpPackage = args[opti];
12878                    opti++;
12879                    newArgs = new String[args.length - opti];
12880                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12881                            args.length - opti);
12882                }
12883                synchronized (this) {
12884                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
12885                }
12886            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12887                synchronized (this) {
12888                    dumpOomLocked(fd, pw, args, opti, true);
12889                }
12890            } else if ("provider".equals(cmd)) {
12891                String[] newArgs;
12892                String name;
12893                if (opti >= args.length) {
12894                    name = null;
12895                    newArgs = EMPTY_STRING_ARRAY;
12896                } else {
12897                    name = args[opti];
12898                    opti++;
12899                    newArgs = new String[args.length - opti];
12900                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12901                }
12902                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12903                    pw.println("No providers match: " + name);
12904                    pw.println("Use -h for help.");
12905                }
12906            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12907                synchronized (this) {
12908                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12909                }
12910            } else if ("service".equals(cmd)) {
12911                String[] newArgs;
12912                String name;
12913                if (opti >= args.length) {
12914                    name = null;
12915                    newArgs = EMPTY_STRING_ARRAY;
12916                } else {
12917                    name = args[opti];
12918                    opti++;
12919                    newArgs = new String[args.length - opti];
12920                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12921                            args.length - opti);
12922                }
12923                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12924                    pw.println("No services match: " + name);
12925                    pw.println("Use -h for help.");
12926                }
12927            } else if ("package".equals(cmd)) {
12928                String[] newArgs;
12929                if (opti >= args.length) {
12930                    pw.println("package: no package name specified");
12931                    pw.println("Use -h for help.");
12932                } else {
12933                    dumpPackage = args[opti];
12934                    opti++;
12935                    newArgs = new String[args.length - opti];
12936                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12937                            args.length - opti);
12938                    args = newArgs;
12939                    opti = 0;
12940                    more = true;
12941                }
12942            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
12943                synchronized (this) {
12944                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12945                }
12946            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12947                synchronized (this) {
12948                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12949                }
12950            } else if ("write".equals(cmd)) {
12951                mTaskPersister.flush();
12952                pw.println("All tasks persisted.");
12953                return;
12954            } else if ("track-associations".equals(cmd)) {
12955                synchronized (this) {
12956                    if (!mTrackingAssociations) {
12957                        mTrackingAssociations = true;
12958                        pw.println("Association tracking started.");
12959                    } else {
12960                        pw.println("Association tracking already enabled.");
12961                    }
12962                }
12963                return;
12964            } else if ("untrack-associations".equals(cmd)) {
12965                synchronized (this) {
12966                    if (mTrackingAssociations) {
12967                        mTrackingAssociations = false;
12968                        mAssociations.clear();
12969                        pw.println("Association tracking stopped.");
12970                    } else {
12971                        pw.println("Association tracking not running.");
12972                    }
12973                }
12974                return;
12975            } else {
12976                // Dumping a single activity?
12977                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12978                    pw.println("Bad activity command, or no activities match: " + cmd);
12979                    pw.println("Use -h for help.");
12980                }
12981            }
12982            if (!more) {
12983                Binder.restoreCallingIdentity(origId);
12984                return;
12985            }
12986        }
12987
12988        // No piece of data specified, dump everything.
12989        synchronized (this) {
12990            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12991            pw.println();
12992            if (dumpAll) {
12993                pw.println("-------------------------------------------------------------------------------");
12994            }
12995            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12996            pw.println();
12997            if (dumpAll) {
12998                pw.println("-------------------------------------------------------------------------------");
12999            }
13000            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13001            pw.println();
13002            if (dumpAll) {
13003                pw.println("-------------------------------------------------------------------------------");
13004            }
13005            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13006            pw.println();
13007            if (dumpAll) {
13008                pw.println("-------------------------------------------------------------------------------");
13009            }
13010            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13011            pw.println();
13012            if (dumpAll) {
13013                pw.println("-------------------------------------------------------------------------------");
13014            }
13015            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13016            if (mAssociations.size() > 0) {
13017                pw.println();
13018                if (dumpAll) {
13019                    pw.println("-------------------------------------------------------------------------------");
13020                }
13021                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13022            }
13023            pw.println();
13024            if (dumpAll) {
13025                pw.println("-------------------------------------------------------------------------------");
13026            }
13027            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13028        }
13029        Binder.restoreCallingIdentity(origId);
13030    }
13031
13032    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13033            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13034        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13035
13036        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13037                dumpPackage);
13038        boolean needSep = printedAnything;
13039
13040        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13041                dumpPackage, needSep, "  mFocusedActivity: ");
13042        if (printed) {
13043            printedAnything = true;
13044            needSep = false;
13045        }
13046
13047        if (dumpPackage == null) {
13048            if (needSep) {
13049                pw.println();
13050            }
13051            needSep = true;
13052            printedAnything = true;
13053            mStackSupervisor.dump(pw, "  ");
13054        }
13055
13056        if (!printedAnything) {
13057            pw.println("  (nothing)");
13058        }
13059    }
13060
13061    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13062            int opti, boolean dumpAll, String dumpPackage) {
13063        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13064
13065        boolean printedAnything = false;
13066
13067        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13068            boolean printedHeader = false;
13069
13070            final int N = mRecentTasks.size();
13071            for (int i=0; i<N; i++) {
13072                TaskRecord tr = mRecentTasks.get(i);
13073                if (dumpPackage != null) {
13074                    if (tr.realActivity == null ||
13075                            !dumpPackage.equals(tr.realActivity)) {
13076                        continue;
13077                    }
13078                }
13079                if (!printedHeader) {
13080                    pw.println("  Recent tasks:");
13081                    printedHeader = true;
13082                    printedAnything = true;
13083                }
13084                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13085                        pw.println(tr);
13086                if (dumpAll) {
13087                    mRecentTasks.get(i).dump(pw, "    ");
13088                }
13089            }
13090        }
13091
13092        if (!printedAnything) {
13093            pw.println("  (nothing)");
13094        }
13095    }
13096
13097    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13098            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13099        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13100
13101        int dumpUid = 0;
13102        if (dumpPackage != null) {
13103            IPackageManager pm = AppGlobals.getPackageManager();
13104            try {
13105                dumpUid = pm.getPackageUid(dumpPackage, 0);
13106            } catch (RemoteException e) {
13107            }
13108        }
13109
13110        boolean printedAnything = false;
13111
13112        final long now = SystemClock.uptimeMillis();
13113
13114        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13115            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13116                    = mAssociations.valueAt(i1);
13117            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13118                SparseArray<ArrayMap<String, Association>> sourceUids
13119                        = targetComponents.valueAt(i2);
13120                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13121                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13122                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13123                        Association ass = sourceProcesses.valueAt(i4);
13124                        if (dumpPackage != null) {
13125                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13126                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13127                                continue;
13128                            }
13129                        }
13130                        printedAnything = true;
13131                        pw.print("  ");
13132                        pw.print(ass.mTargetProcess);
13133                        pw.print("/");
13134                        UserHandle.formatUid(pw, ass.mTargetUid);
13135                        pw.print(" <- ");
13136                        pw.print(ass.mSourceProcess);
13137                        pw.print("/");
13138                        UserHandle.formatUid(pw, ass.mSourceUid);
13139                        pw.println();
13140                        pw.print("    via ");
13141                        pw.print(ass.mTargetComponent.flattenToShortString());
13142                        pw.println();
13143                        pw.print("    ");
13144                        long dur = ass.mTime;
13145                        if (ass.mNesting > 0) {
13146                            dur += now - ass.mStartTime;
13147                        }
13148                        TimeUtils.formatDuration(dur, pw);
13149                        pw.print(" (");
13150                        pw.print(ass.mCount);
13151                        pw.println(" times)");
13152                        if (ass.mNesting > 0) {
13153                            pw.print("    ");
13154                            pw.print(" Currently active: ");
13155                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13156                            pw.println();
13157                        }
13158                    }
13159                }
13160            }
13161
13162        }
13163
13164        if (!printedAnything) {
13165            pw.println("  (nothing)");
13166        }
13167    }
13168
13169    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13170            int opti, boolean dumpAll, String dumpPackage) {
13171        boolean needSep = false;
13172        boolean printedAnything = false;
13173        int numPers = 0;
13174
13175        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13176
13177        if (dumpAll) {
13178            final int NP = mProcessNames.getMap().size();
13179            for (int ip=0; ip<NP; ip++) {
13180                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13181                final int NA = procs.size();
13182                for (int ia=0; ia<NA; ia++) {
13183                    ProcessRecord r = procs.valueAt(ia);
13184                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13185                        continue;
13186                    }
13187                    if (!needSep) {
13188                        pw.println("  All known processes:");
13189                        needSep = true;
13190                        printedAnything = true;
13191                    }
13192                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13193                        pw.print(" UID "); pw.print(procs.keyAt(ia));
13194                        pw.print(" "); pw.println(r);
13195                    r.dump(pw, "    ");
13196                    if (r.persistent) {
13197                        numPers++;
13198                    }
13199                }
13200            }
13201        }
13202
13203        if (mIsolatedProcesses.size() > 0) {
13204            boolean printed = false;
13205            for (int i=0; i<mIsolatedProcesses.size(); i++) {
13206                ProcessRecord r = mIsolatedProcesses.valueAt(i);
13207                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13208                    continue;
13209                }
13210                if (!printed) {
13211                    if (needSep) {
13212                        pw.println();
13213                    }
13214                    pw.println("  Isolated process list (sorted by uid):");
13215                    printedAnything = true;
13216                    printed = true;
13217                    needSep = true;
13218                }
13219                pw.println(String.format("%sIsolated #%2d: %s",
13220                        "    ", i, r.toString()));
13221            }
13222        }
13223
13224        if (mActiveUids.size() > 0) {
13225            if (needSep) {
13226                pw.println();
13227            }
13228            pw.println("  UID states:");
13229            for (int i=0; i<mActiveUids.size(); i++) {
13230                UidRecord uidRec = mActiveUids.valueAt(i);
13231                pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13232                pw.print(": "); pw.println(uidRec);
13233            }
13234            needSep = true;
13235            printedAnything = true;
13236        }
13237
13238        if (mLruProcesses.size() > 0) {
13239            if (needSep) {
13240                pw.println();
13241            }
13242            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
13243                    pw.print(" total, non-act at ");
13244                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13245                    pw.print(", non-svc at ");
13246                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13247                    pw.println("):");
13248            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
13249            needSep = true;
13250            printedAnything = true;
13251        }
13252
13253        if (dumpAll || dumpPackage != null) {
13254            synchronized (mPidsSelfLocked) {
13255                boolean printed = false;
13256                for (int i=0; i<mPidsSelfLocked.size(); i++) {
13257                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
13258                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13259                        continue;
13260                    }
13261                    if (!printed) {
13262                        if (needSep) pw.println();
13263                        needSep = true;
13264                        pw.println("  PID mappings:");
13265                        printed = true;
13266                        printedAnything = true;
13267                    }
13268                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
13269                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
13270                }
13271            }
13272        }
13273
13274        if (mForegroundProcesses.size() > 0) {
13275            synchronized (mPidsSelfLocked) {
13276                boolean printed = false;
13277                for (int i=0; i<mForegroundProcesses.size(); i++) {
13278                    ProcessRecord r = mPidsSelfLocked.get(
13279                            mForegroundProcesses.valueAt(i).pid);
13280                    if (dumpPackage != null && (r == null
13281                            || !r.pkgList.containsKey(dumpPackage))) {
13282                        continue;
13283                    }
13284                    if (!printed) {
13285                        if (needSep) pw.println();
13286                        needSep = true;
13287                        pw.println("  Foreground Processes:");
13288                        printed = true;
13289                        printedAnything = true;
13290                    }
13291                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
13292                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
13293                }
13294            }
13295        }
13296
13297        if (mPersistentStartingProcesses.size() > 0) {
13298            if (needSep) pw.println();
13299            needSep = true;
13300            printedAnything = true;
13301            pw.println("  Persisent processes that are starting:");
13302            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
13303                    "Starting Norm", "Restarting PERS", dumpPackage);
13304        }
13305
13306        if (mRemovedProcesses.size() > 0) {
13307            if (needSep) pw.println();
13308            needSep = true;
13309            printedAnything = true;
13310            pw.println("  Processes that are being removed:");
13311            dumpProcessList(pw, this, mRemovedProcesses, "    ",
13312                    "Removed Norm", "Removed PERS", dumpPackage);
13313        }
13314
13315        if (mProcessesOnHold.size() > 0) {
13316            if (needSep) pw.println();
13317            needSep = true;
13318            printedAnything = true;
13319            pw.println("  Processes that are on old until the system is ready:");
13320            dumpProcessList(pw, this, mProcessesOnHold, "    ",
13321                    "OnHold Norm", "OnHold PERS", dumpPackage);
13322        }
13323
13324        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
13325
13326        if (mProcessCrashTimes.getMap().size() > 0) {
13327            boolean printed = false;
13328            long now = SystemClock.uptimeMillis();
13329            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
13330            final int NP = pmap.size();
13331            for (int ip=0; ip<NP; ip++) {
13332                String pname = pmap.keyAt(ip);
13333                SparseArray<Long> uids = pmap.valueAt(ip);
13334                final int N = uids.size();
13335                for (int i=0; i<N; i++) {
13336                    int puid = uids.keyAt(i);
13337                    ProcessRecord r = mProcessNames.get(pname, puid);
13338                    if (dumpPackage != null && (r == null
13339                            || !r.pkgList.containsKey(dumpPackage))) {
13340                        continue;
13341                    }
13342                    if (!printed) {
13343                        if (needSep) pw.println();
13344                        needSep = true;
13345                        pw.println("  Time since processes crashed:");
13346                        printed = true;
13347                        printedAnything = true;
13348                    }
13349                    pw.print("    Process "); pw.print(pname);
13350                            pw.print(" uid "); pw.print(puid);
13351                            pw.print(": last crashed ");
13352                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
13353                            pw.println(" ago");
13354                }
13355            }
13356        }
13357
13358        if (mBadProcesses.getMap().size() > 0) {
13359            boolean printed = false;
13360            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
13361            final int NP = pmap.size();
13362            for (int ip=0; ip<NP; ip++) {
13363                String pname = pmap.keyAt(ip);
13364                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
13365                final int N = uids.size();
13366                for (int i=0; i<N; i++) {
13367                    int puid = uids.keyAt(i);
13368                    ProcessRecord r = mProcessNames.get(pname, puid);
13369                    if (dumpPackage != null && (r == null
13370                            || !r.pkgList.containsKey(dumpPackage))) {
13371                        continue;
13372                    }
13373                    if (!printed) {
13374                        if (needSep) pw.println();
13375                        needSep = true;
13376                        pw.println("  Bad processes:");
13377                        printedAnything = true;
13378                    }
13379                    BadProcessInfo info = uids.valueAt(i);
13380                    pw.print("    Bad process "); pw.print(pname);
13381                            pw.print(" uid "); pw.print(puid);
13382                            pw.print(": crashed at time "); pw.println(info.time);
13383                    if (info.shortMsg != null) {
13384                        pw.print("      Short msg: "); pw.println(info.shortMsg);
13385                    }
13386                    if (info.longMsg != null) {
13387                        pw.print("      Long msg: "); pw.println(info.longMsg);
13388                    }
13389                    if (info.stack != null) {
13390                        pw.println("      Stack:");
13391                        int lastPos = 0;
13392                        for (int pos=0; pos<info.stack.length(); pos++) {
13393                            if (info.stack.charAt(pos) == '\n') {
13394                                pw.print("        ");
13395                                pw.write(info.stack, lastPos, pos-lastPos);
13396                                pw.println();
13397                                lastPos = pos+1;
13398                            }
13399                        }
13400                        if (lastPos < info.stack.length()) {
13401                            pw.print("        ");
13402                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
13403                            pw.println();
13404                        }
13405                    }
13406                }
13407            }
13408        }
13409
13410        if (dumpPackage == null) {
13411            pw.println();
13412            needSep = false;
13413            pw.println("  mStartedUsers:");
13414            for (int i=0; i<mStartedUsers.size(); i++) {
13415                UserState uss = mStartedUsers.valueAt(i);
13416                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
13417                        pw.print(": "); uss.dump("", pw);
13418            }
13419            pw.print("  mStartedUserArray: [");
13420            for (int i=0; i<mStartedUserArray.length; i++) {
13421                if (i > 0) pw.print(", ");
13422                pw.print(mStartedUserArray[i]);
13423            }
13424            pw.println("]");
13425            pw.print("  mUserLru: [");
13426            for (int i=0; i<mUserLru.size(); i++) {
13427                if (i > 0) pw.print(", ");
13428                pw.print(mUserLru.get(i));
13429            }
13430            pw.println("]");
13431            if (dumpAll) {
13432                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
13433            }
13434            synchronized (mUserProfileGroupIdsSelfLocked) {
13435                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
13436                    pw.println("  mUserProfileGroupIds:");
13437                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
13438                        pw.print("    User #");
13439                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
13440                        pw.print(" -> profile #");
13441                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
13442                    }
13443                }
13444            }
13445        }
13446        if (mHomeProcess != null && (dumpPackage == null
13447                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13448            if (needSep) {
13449                pw.println();
13450                needSep = false;
13451            }
13452            pw.println("  mHomeProcess: " + mHomeProcess);
13453        }
13454        if (mPreviousProcess != null && (dumpPackage == null
13455                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13456            if (needSep) {
13457                pw.println();
13458                needSep = false;
13459            }
13460            pw.println("  mPreviousProcess: " + mPreviousProcess);
13461        }
13462        if (dumpAll) {
13463            StringBuilder sb = new StringBuilder(128);
13464            sb.append("  mPreviousProcessVisibleTime: ");
13465            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13466            pw.println(sb);
13467        }
13468        if (mHeavyWeightProcess != null && (dumpPackage == null
13469                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13470            if (needSep) {
13471                pw.println();
13472                needSep = false;
13473            }
13474            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13475        }
13476        if (dumpPackage == null) {
13477            pw.println("  mConfiguration: " + mConfiguration);
13478        }
13479        if (dumpAll) {
13480            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13481            if (mCompatModePackages.getPackages().size() > 0) {
13482                boolean printed = false;
13483                for (Map.Entry<String, Integer> entry
13484                        : mCompatModePackages.getPackages().entrySet()) {
13485                    String pkg = entry.getKey();
13486                    int mode = entry.getValue();
13487                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
13488                        continue;
13489                    }
13490                    if (!printed) {
13491                        pw.println("  mScreenCompatPackages:");
13492                        printed = true;
13493                    }
13494                    pw.print("    "); pw.print(pkg); pw.print(": ");
13495                            pw.print(mode); pw.println();
13496                }
13497            }
13498        }
13499        if (dumpPackage == null) {
13500            pw.println("  mWakefulness="
13501                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
13502            pw.println("  mSleepTokens=" + mSleepTokens);
13503            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
13504                    + lockScreenShownToString());
13505            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
13506            if (mRunningVoice != null) {
13507                pw.println("  mRunningVoice=" + mRunningVoice);
13508                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
13509            }
13510        }
13511        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
13512                || mOrigWaitForDebugger) {
13513            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
13514                    || dumpPackage.equals(mOrigDebugApp)) {
13515                if (needSep) {
13516                    pw.println();
13517                    needSep = false;
13518                }
13519                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
13520                        + " mDebugTransient=" + mDebugTransient
13521                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
13522            }
13523        }
13524        if (mCurAppTimeTracker != null) {
13525            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
13526        }
13527        if (mMemWatchProcesses.getMap().size() > 0) {
13528            pw.println("  Mem watch processes:");
13529            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
13530                    = mMemWatchProcesses.getMap();
13531            for (int i=0; i<procs.size(); i++) {
13532                final String proc = procs.keyAt(i);
13533                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
13534                for (int j=0; j<uids.size(); j++) {
13535                    if (needSep) {
13536                        pw.println();
13537                        needSep = false;
13538                    }
13539                    StringBuilder sb = new StringBuilder();
13540                    sb.append("    ").append(proc).append('/');
13541                    UserHandle.formatUid(sb, uids.keyAt(j));
13542                    Pair<Long, String> val = uids.valueAt(j);
13543                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
13544                    if (val.second != null) {
13545                        sb.append(", report to ").append(val.second);
13546                    }
13547                    pw.println(sb.toString());
13548                }
13549            }
13550            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
13551            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
13552            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
13553                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
13554        }
13555        if (mOpenGlTraceApp != null) {
13556            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
13557                if (needSep) {
13558                    pw.println();
13559                    needSep = false;
13560                }
13561                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
13562            }
13563        }
13564        if (mTrackAllocationApp != null) {
13565            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
13566                if (needSep) {
13567                    pw.println();
13568                    needSep = false;
13569                }
13570                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
13571            }
13572        }
13573        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
13574                || mProfileFd != null) {
13575            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13576                if (needSep) {
13577                    pw.println();
13578                    needSep = false;
13579                }
13580                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13581                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13582                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13583                        + mAutoStopProfiler);
13584                pw.println("  mProfileType=" + mProfileType);
13585            }
13586        }
13587        if (dumpPackage == null) {
13588            if (mAlwaysFinishActivities || mController != null) {
13589                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
13590                        + " mController=" + mController);
13591            }
13592            if (dumpAll) {
13593                pw.println("  Total persistent processes: " + numPers);
13594                pw.println("  mProcessesReady=" + mProcessesReady
13595                        + " mSystemReady=" + mSystemReady
13596                        + " mBooted=" + mBooted
13597                        + " mFactoryTest=" + mFactoryTest);
13598                pw.println("  mBooting=" + mBooting
13599                        + " mCallFinishBooting=" + mCallFinishBooting
13600                        + " mBootAnimationComplete=" + mBootAnimationComplete);
13601                pw.print("  mLastPowerCheckRealtime=");
13602                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13603                        pw.println("");
13604                pw.print("  mLastPowerCheckUptime=");
13605                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13606                        pw.println("");
13607                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13608                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13609                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13610                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
13611                        + " (" + mLruProcesses.size() + " total)"
13612                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13613                        + " mNumServiceProcs=" + mNumServiceProcs
13614                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13615                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
13616                        + " mLastMemoryLevel" + mLastMemoryLevel
13617                        + " mLastNumProcesses" + mLastNumProcesses);
13618                long now = SystemClock.uptimeMillis();
13619                pw.print("  mLastIdleTime=");
13620                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
13621                        pw.print(" mLowRamSinceLastIdle=");
13622                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13623                        pw.println();
13624            }
13625        }
13626
13627        if (!printedAnything) {
13628            pw.println("  (nothing)");
13629        }
13630    }
13631
13632    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13633            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13634        if (mProcessesToGc.size() > 0) {
13635            boolean printed = false;
13636            long now = SystemClock.uptimeMillis();
13637            for (int i=0; i<mProcessesToGc.size(); i++) {
13638                ProcessRecord proc = mProcessesToGc.get(i);
13639                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13640                    continue;
13641                }
13642                if (!printed) {
13643                    if (needSep) pw.println();
13644                    needSep = true;
13645                    pw.println("  Processes that are waiting to GC:");
13646                    printed = true;
13647                }
13648                pw.print("    Process "); pw.println(proc);
13649                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13650                        pw.print(", last gced=");
13651                        pw.print(now-proc.lastRequestedGc);
13652                        pw.print(" ms ago, last lowMem=");
13653                        pw.print(now-proc.lastLowMemory);
13654                        pw.println(" ms ago");
13655
13656            }
13657        }
13658        return needSep;
13659    }
13660
13661    void printOomLevel(PrintWriter pw, String name, int adj) {
13662        pw.print("    ");
13663        if (adj >= 0) {
13664            pw.print(' ');
13665            if (adj < 10) pw.print(' ');
13666        } else {
13667            if (adj > -10) pw.print(' ');
13668        }
13669        pw.print(adj);
13670        pw.print(": ");
13671        pw.print(name);
13672        pw.print(" (");
13673        pw.print(mProcessList.getMemLevel(adj)/1024);
13674        pw.println(" kB)");
13675    }
13676
13677    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13678            int opti, boolean dumpAll) {
13679        boolean needSep = false;
13680
13681        if (mLruProcesses.size() > 0) {
13682            if (needSep) pw.println();
13683            needSep = true;
13684            pw.println("  OOM levels:");
13685            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13686            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13687            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13688            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13689            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13690            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13691            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13692            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13693            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13694            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13695            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13696            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13697            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13698            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13699
13700            if (needSep) pw.println();
13701            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13702                    pw.print(" total, non-act at ");
13703                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13704                    pw.print(", non-svc at ");
13705                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13706                    pw.println("):");
13707            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13708            needSep = true;
13709        }
13710
13711        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13712
13713        pw.println();
13714        pw.println("  mHomeProcess: " + mHomeProcess);
13715        pw.println("  mPreviousProcess: " + mPreviousProcess);
13716        if (mHeavyWeightProcess != null) {
13717            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13718        }
13719
13720        return true;
13721    }
13722
13723    /**
13724     * There are three ways to call this:
13725     *  - no provider specified: dump all the providers
13726     *  - a flattened component name that matched an existing provider was specified as the
13727     *    first arg: dump that one provider
13728     *  - the first arg isn't the flattened component name of an existing provider:
13729     *    dump all providers whose component contains the first arg as a substring
13730     */
13731    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13732            int opti, boolean dumpAll) {
13733        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13734    }
13735
13736    static class ItemMatcher {
13737        ArrayList<ComponentName> components;
13738        ArrayList<String> strings;
13739        ArrayList<Integer> objects;
13740        boolean all;
13741
13742        ItemMatcher() {
13743            all = true;
13744        }
13745
13746        void build(String name) {
13747            ComponentName componentName = ComponentName.unflattenFromString(name);
13748            if (componentName != null) {
13749                if (components == null) {
13750                    components = new ArrayList<ComponentName>();
13751                }
13752                components.add(componentName);
13753                all = false;
13754            } else {
13755                int objectId = 0;
13756                // Not a '/' separated full component name; maybe an object ID?
13757                try {
13758                    objectId = Integer.parseInt(name, 16);
13759                    if (objects == null) {
13760                        objects = new ArrayList<Integer>();
13761                    }
13762                    objects.add(objectId);
13763                    all = false;
13764                } catch (RuntimeException e) {
13765                    // Not an integer; just do string match.
13766                    if (strings == null) {
13767                        strings = new ArrayList<String>();
13768                    }
13769                    strings.add(name);
13770                    all = false;
13771                }
13772            }
13773        }
13774
13775        int build(String[] args, int opti) {
13776            for (; opti<args.length; opti++) {
13777                String name = args[opti];
13778                if ("--".equals(name)) {
13779                    return opti+1;
13780                }
13781                build(name);
13782            }
13783            return opti;
13784        }
13785
13786        boolean match(Object object, ComponentName comp) {
13787            if (all) {
13788                return true;
13789            }
13790            if (components != null) {
13791                for (int i=0; i<components.size(); i++) {
13792                    if (components.get(i).equals(comp)) {
13793                        return true;
13794                    }
13795                }
13796            }
13797            if (objects != null) {
13798                for (int i=0; i<objects.size(); i++) {
13799                    if (System.identityHashCode(object) == objects.get(i)) {
13800                        return true;
13801                    }
13802                }
13803            }
13804            if (strings != null) {
13805                String flat = comp.flattenToString();
13806                for (int i=0; i<strings.size(); i++) {
13807                    if (flat.contains(strings.get(i))) {
13808                        return true;
13809                    }
13810                }
13811            }
13812            return false;
13813        }
13814    }
13815
13816    /**
13817     * There are three things that cmd can be:
13818     *  - a flattened component name that matches an existing activity
13819     *  - the cmd arg isn't the flattened component name of an existing activity:
13820     *    dump all activity whose component contains the cmd as a substring
13821     *  - A hex number of the ActivityRecord object instance.
13822     */
13823    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13824            int opti, boolean dumpAll) {
13825        ArrayList<ActivityRecord> activities;
13826
13827        synchronized (this) {
13828            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13829        }
13830
13831        if (activities.size() <= 0) {
13832            return false;
13833        }
13834
13835        String[] newArgs = new String[args.length - opti];
13836        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13837
13838        TaskRecord lastTask = null;
13839        boolean needSep = false;
13840        for (int i=activities.size()-1; i>=0; i--) {
13841            ActivityRecord r = activities.get(i);
13842            if (needSep) {
13843                pw.println();
13844            }
13845            needSep = true;
13846            synchronized (this) {
13847                if (lastTask != r.task) {
13848                    lastTask = r.task;
13849                    pw.print("TASK "); pw.print(lastTask.affinity);
13850                            pw.print(" id="); pw.println(lastTask.taskId);
13851                    if (dumpAll) {
13852                        lastTask.dump(pw, "  ");
13853                    }
13854                }
13855            }
13856            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13857        }
13858        return true;
13859    }
13860
13861    /**
13862     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13863     * there is a thread associated with the activity.
13864     */
13865    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13866            final ActivityRecord r, String[] args, boolean dumpAll) {
13867        String innerPrefix = prefix + "  ";
13868        synchronized (this) {
13869            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13870                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13871                    pw.print(" pid=");
13872                    if (r.app != null) pw.println(r.app.pid);
13873                    else pw.println("(not running)");
13874            if (dumpAll) {
13875                r.dump(pw, innerPrefix);
13876            }
13877        }
13878        if (r.app != null && r.app.thread != null) {
13879            // flush anything that is already in the PrintWriter since the thread is going
13880            // to write to the file descriptor directly
13881            pw.flush();
13882            try {
13883                TransferPipe tp = new TransferPipe();
13884                try {
13885                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13886                            r.appToken, innerPrefix, args);
13887                    tp.go(fd);
13888                } finally {
13889                    tp.kill();
13890                }
13891            } catch (IOException e) {
13892                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13893            } catch (RemoteException e) {
13894                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13895            }
13896        }
13897    }
13898
13899    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13900            int opti, boolean dumpAll, String dumpPackage) {
13901        boolean needSep = false;
13902        boolean onlyHistory = false;
13903        boolean printedAnything = false;
13904
13905        if ("history".equals(dumpPackage)) {
13906            if (opti < args.length && "-s".equals(args[opti])) {
13907                dumpAll = false;
13908            }
13909            onlyHistory = true;
13910            dumpPackage = null;
13911        }
13912
13913        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13914        if (!onlyHistory && dumpAll) {
13915            if (mRegisteredReceivers.size() > 0) {
13916                boolean printed = false;
13917                Iterator it = mRegisteredReceivers.values().iterator();
13918                while (it.hasNext()) {
13919                    ReceiverList r = (ReceiverList)it.next();
13920                    if (dumpPackage != null && (r.app == null ||
13921                            !dumpPackage.equals(r.app.info.packageName))) {
13922                        continue;
13923                    }
13924                    if (!printed) {
13925                        pw.println("  Registered Receivers:");
13926                        needSep = true;
13927                        printed = true;
13928                        printedAnything = true;
13929                    }
13930                    pw.print("  * "); pw.println(r);
13931                    r.dump(pw, "    ");
13932                }
13933            }
13934
13935            if (mReceiverResolver.dump(pw, needSep ?
13936                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13937                    "    ", dumpPackage, false, false)) {
13938                needSep = true;
13939                printedAnything = true;
13940            }
13941        }
13942
13943        for (BroadcastQueue q : mBroadcastQueues) {
13944            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13945            printedAnything |= needSep;
13946        }
13947
13948        needSep = true;
13949
13950        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13951            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13952                if (needSep) {
13953                    pw.println();
13954                }
13955                needSep = true;
13956                printedAnything = true;
13957                pw.print("  Sticky broadcasts for user ");
13958                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13959                StringBuilder sb = new StringBuilder(128);
13960                for (Map.Entry<String, ArrayList<Intent>> ent
13961                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13962                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13963                    if (dumpAll) {
13964                        pw.println(":");
13965                        ArrayList<Intent> intents = ent.getValue();
13966                        final int N = intents.size();
13967                        for (int i=0; i<N; i++) {
13968                            sb.setLength(0);
13969                            sb.append("    Intent: ");
13970                            intents.get(i).toShortString(sb, false, true, false, false);
13971                            pw.println(sb.toString());
13972                            Bundle bundle = intents.get(i).getExtras();
13973                            if (bundle != null) {
13974                                pw.print("      ");
13975                                pw.println(bundle.toString());
13976                            }
13977                        }
13978                    } else {
13979                        pw.println("");
13980                    }
13981                }
13982            }
13983        }
13984
13985        if (!onlyHistory && dumpAll) {
13986            pw.println();
13987            for (BroadcastQueue queue : mBroadcastQueues) {
13988                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13989                        + queue.mBroadcastsScheduled);
13990            }
13991            pw.println("  mHandler:");
13992            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13993            needSep = true;
13994            printedAnything = true;
13995        }
13996
13997        if (!printedAnything) {
13998            pw.println("  (nothing)");
13999        }
14000    }
14001
14002    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14003            int opti, boolean dumpAll, String dumpPackage) {
14004        boolean needSep;
14005        boolean printedAnything = false;
14006
14007        ItemMatcher matcher = new ItemMatcher();
14008        matcher.build(args, opti);
14009
14010        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14011
14012        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14013        printedAnything |= needSep;
14014
14015        if (mLaunchingProviders.size() > 0) {
14016            boolean printed = false;
14017            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14018                ContentProviderRecord r = mLaunchingProviders.get(i);
14019                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14020                    continue;
14021                }
14022                if (!printed) {
14023                    if (needSep) pw.println();
14024                    needSep = true;
14025                    pw.println("  Launching content providers:");
14026                    printed = true;
14027                    printedAnything = true;
14028                }
14029                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14030                        pw.println(r);
14031            }
14032        }
14033
14034        if (mGrantedUriPermissions.size() > 0) {
14035            boolean printed = false;
14036            int dumpUid = -2;
14037            if (dumpPackage != null) {
14038                try {
14039                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
14040                } catch (NameNotFoundException e) {
14041                    dumpUid = -1;
14042                }
14043            }
14044            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14045                int uid = mGrantedUriPermissions.keyAt(i);
14046                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14047                    continue;
14048                }
14049                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14050                if (!printed) {
14051                    if (needSep) pw.println();
14052                    needSep = true;
14053                    pw.println("  Granted Uri Permissions:");
14054                    printed = true;
14055                    printedAnything = true;
14056                }
14057                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14058                for (UriPermission perm : perms.values()) {
14059                    pw.print("    "); pw.println(perm);
14060                    if (dumpAll) {
14061                        perm.dump(pw, "      ");
14062                    }
14063                }
14064            }
14065        }
14066
14067        if (!printedAnything) {
14068            pw.println("  (nothing)");
14069        }
14070    }
14071
14072    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14073            int opti, boolean dumpAll, String dumpPackage) {
14074        boolean printed = false;
14075
14076        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14077
14078        if (mIntentSenderRecords.size() > 0) {
14079            Iterator<WeakReference<PendingIntentRecord>> it
14080                    = mIntentSenderRecords.values().iterator();
14081            while (it.hasNext()) {
14082                WeakReference<PendingIntentRecord> ref = it.next();
14083                PendingIntentRecord rec = ref != null ? ref.get(): null;
14084                if (dumpPackage != null && (rec == null
14085                        || !dumpPackage.equals(rec.key.packageName))) {
14086                    continue;
14087                }
14088                printed = true;
14089                if (rec != null) {
14090                    pw.print("  * "); pw.println(rec);
14091                    if (dumpAll) {
14092                        rec.dump(pw, "    ");
14093                    }
14094                } else {
14095                    pw.print("  * "); pw.println(ref);
14096                }
14097            }
14098        }
14099
14100        if (!printed) {
14101            pw.println("  (nothing)");
14102        }
14103    }
14104
14105    private static final int dumpProcessList(PrintWriter pw,
14106            ActivityManagerService service, List list,
14107            String prefix, String normalLabel, String persistentLabel,
14108            String dumpPackage) {
14109        int numPers = 0;
14110        final int N = list.size()-1;
14111        for (int i=N; i>=0; i--) {
14112            ProcessRecord r = (ProcessRecord)list.get(i);
14113            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14114                continue;
14115            }
14116            pw.println(String.format("%s%s #%2d: %s",
14117                    prefix, (r.persistent ? persistentLabel : normalLabel),
14118                    i, r.toString()));
14119            if (r.persistent) {
14120                numPers++;
14121            }
14122        }
14123        return numPers;
14124    }
14125
14126    private static final boolean dumpProcessOomList(PrintWriter pw,
14127            ActivityManagerService service, List<ProcessRecord> origList,
14128            String prefix, String normalLabel, String persistentLabel,
14129            boolean inclDetails, String dumpPackage) {
14130
14131        ArrayList<Pair<ProcessRecord, Integer>> list
14132                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14133        for (int i=0; i<origList.size(); i++) {
14134            ProcessRecord r = origList.get(i);
14135            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14136                continue;
14137            }
14138            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14139        }
14140
14141        if (list.size() <= 0) {
14142            return false;
14143        }
14144
14145        Comparator<Pair<ProcessRecord, Integer>> comparator
14146                = new Comparator<Pair<ProcessRecord, Integer>>() {
14147            @Override
14148            public int compare(Pair<ProcessRecord, Integer> object1,
14149                    Pair<ProcessRecord, Integer> object2) {
14150                if (object1.first.setAdj != object2.first.setAdj) {
14151                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14152                }
14153                if (object1.second.intValue() != object2.second.intValue()) {
14154                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14155                }
14156                return 0;
14157            }
14158        };
14159
14160        Collections.sort(list, comparator);
14161
14162        final long curRealtime = SystemClock.elapsedRealtime();
14163        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14164        final long curUptime = SystemClock.uptimeMillis();
14165        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14166
14167        for (int i=list.size()-1; i>=0; i--) {
14168            ProcessRecord r = list.get(i).first;
14169            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14170            char schedGroup;
14171            switch (r.setSchedGroup) {
14172                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
14173                    schedGroup = 'B';
14174                    break;
14175                case Process.THREAD_GROUP_DEFAULT:
14176                    schedGroup = 'F';
14177                    break;
14178                default:
14179                    schedGroup = '?';
14180                    break;
14181            }
14182            char foreground;
14183            if (r.foregroundActivities) {
14184                foreground = 'A';
14185            } else if (r.foregroundServices) {
14186                foreground = 'S';
14187            } else {
14188                foreground = ' ';
14189            }
14190            String procState = ProcessList.makeProcStateString(r.curProcState);
14191            pw.print(prefix);
14192            pw.print(r.persistent ? persistentLabel : normalLabel);
14193            pw.print(" #");
14194            int num = (origList.size()-1)-list.get(i).second;
14195            if (num < 10) pw.print(' ');
14196            pw.print(num);
14197            pw.print(": ");
14198            pw.print(oomAdj);
14199            pw.print(' ');
14200            pw.print(schedGroup);
14201            pw.print('/');
14202            pw.print(foreground);
14203            pw.print('/');
14204            pw.print(procState);
14205            pw.print(" trm:");
14206            if (r.trimMemoryLevel < 10) pw.print(' ');
14207            pw.print(r.trimMemoryLevel);
14208            pw.print(' ');
14209            pw.print(r.toShortString());
14210            pw.print(" (");
14211            pw.print(r.adjType);
14212            pw.println(')');
14213            if (r.adjSource != null || r.adjTarget != null) {
14214                pw.print(prefix);
14215                pw.print("    ");
14216                if (r.adjTarget instanceof ComponentName) {
14217                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14218                } else if (r.adjTarget != null) {
14219                    pw.print(r.adjTarget.toString());
14220                } else {
14221                    pw.print("{null}");
14222                }
14223                pw.print("<=");
14224                if (r.adjSource instanceof ProcessRecord) {
14225                    pw.print("Proc{");
14226                    pw.print(((ProcessRecord)r.adjSource).toShortString());
14227                    pw.println("}");
14228                } else if (r.adjSource != null) {
14229                    pw.println(r.adjSource.toString());
14230                } else {
14231                    pw.println("{null}");
14232                }
14233            }
14234            if (inclDetails) {
14235                pw.print(prefix);
14236                pw.print("    ");
14237                pw.print("oom: max="); pw.print(r.maxAdj);
14238                pw.print(" curRaw="); pw.print(r.curRawAdj);
14239                pw.print(" setRaw="); pw.print(r.setRawAdj);
14240                pw.print(" cur="); pw.print(r.curAdj);
14241                pw.print(" set="); pw.println(r.setAdj);
14242                pw.print(prefix);
14243                pw.print("    ");
14244                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14245                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14246                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14247                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14248                pw.println();
14249                pw.print(prefix);
14250                pw.print("    ");
14251                pw.print("cached="); pw.print(r.cached);
14252                pw.print(" empty="); pw.print(r.empty);
14253                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14254
14255                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14256                    if (r.lastWakeTime != 0) {
14257                        long wtime;
14258                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14259                        synchronized (stats) {
14260                            wtime = stats.getProcessWakeTime(r.info.uid,
14261                                    r.pid, curRealtime);
14262                        }
14263                        long timeUsed = wtime - r.lastWakeTime;
14264                        pw.print(prefix);
14265                        pw.print("    ");
14266                        pw.print("keep awake over ");
14267                        TimeUtils.formatDuration(realtimeSince, pw);
14268                        pw.print(" used ");
14269                        TimeUtils.formatDuration(timeUsed, pw);
14270                        pw.print(" (");
14271                        pw.print((timeUsed*100)/realtimeSince);
14272                        pw.println("%)");
14273                    }
14274                    if (r.lastCpuTime != 0) {
14275                        long timeUsed = r.curCpuTime - r.lastCpuTime;
14276                        pw.print(prefix);
14277                        pw.print("    ");
14278                        pw.print("run cpu over ");
14279                        TimeUtils.formatDuration(uptimeSince, pw);
14280                        pw.print(" used ");
14281                        TimeUtils.formatDuration(timeUsed, pw);
14282                        pw.print(" (");
14283                        pw.print((timeUsed*100)/uptimeSince);
14284                        pw.println("%)");
14285                    }
14286                }
14287            }
14288        }
14289        return true;
14290    }
14291
14292    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14293            String[] args) {
14294        ArrayList<ProcessRecord> procs;
14295        synchronized (this) {
14296            if (args != null && args.length > start
14297                    && args[start].charAt(0) != '-') {
14298                procs = new ArrayList<ProcessRecord>();
14299                int pid = -1;
14300                try {
14301                    pid = Integer.parseInt(args[start]);
14302                } catch (NumberFormatException e) {
14303                }
14304                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14305                    ProcessRecord proc = mLruProcesses.get(i);
14306                    if (proc.pid == pid) {
14307                        procs.add(proc);
14308                    } else if (allPkgs && proc.pkgList != null
14309                            && proc.pkgList.containsKey(args[start])) {
14310                        procs.add(proc);
14311                    } else if (proc.processName.equals(args[start])) {
14312                        procs.add(proc);
14313                    }
14314                }
14315                if (procs.size() <= 0) {
14316                    return null;
14317                }
14318            } else {
14319                procs = new ArrayList<ProcessRecord>(mLruProcesses);
14320            }
14321        }
14322        return procs;
14323    }
14324
14325    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
14326            PrintWriter pw, String[] args) {
14327        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14328        if (procs == null) {
14329            pw.println("No process found for: " + args[0]);
14330            return;
14331        }
14332
14333        long uptime = SystemClock.uptimeMillis();
14334        long realtime = SystemClock.elapsedRealtime();
14335        pw.println("Applications Graphics Acceleration Info:");
14336        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14337
14338        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14339            ProcessRecord r = procs.get(i);
14340            if (r.thread != null) {
14341                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
14342                pw.flush();
14343                try {
14344                    TransferPipe tp = new TransferPipe();
14345                    try {
14346                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
14347                        tp.go(fd);
14348                    } finally {
14349                        tp.kill();
14350                    }
14351                } catch (IOException e) {
14352                    pw.println("Failure while dumping the app: " + r);
14353                    pw.flush();
14354                } catch (RemoteException e) {
14355                    pw.println("Got a RemoteException while dumping the app " + r);
14356                    pw.flush();
14357                }
14358            }
14359        }
14360    }
14361
14362    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
14363        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14364        if (procs == null) {
14365            pw.println("No process found for: " + args[0]);
14366            return;
14367        }
14368
14369        pw.println("Applications Database Info:");
14370
14371        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14372            ProcessRecord r = procs.get(i);
14373            if (r.thread != null) {
14374                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
14375                pw.flush();
14376                try {
14377                    TransferPipe tp = new TransferPipe();
14378                    try {
14379                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
14380                        tp.go(fd);
14381                    } finally {
14382                        tp.kill();
14383                    }
14384                } catch (IOException e) {
14385                    pw.println("Failure while dumping the app: " + r);
14386                    pw.flush();
14387                } catch (RemoteException e) {
14388                    pw.println("Got a RemoteException while dumping the app " + r);
14389                    pw.flush();
14390                }
14391            }
14392        }
14393    }
14394
14395    final static class MemItem {
14396        final boolean isProc;
14397        final String label;
14398        final String shortLabel;
14399        final long pss;
14400        final int id;
14401        final boolean hasActivities;
14402        ArrayList<MemItem> subitems;
14403
14404        public MemItem(String _label, String _shortLabel, long _pss, int _id,
14405                boolean _hasActivities) {
14406            isProc = true;
14407            label = _label;
14408            shortLabel = _shortLabel;
14409            pss = _pss;
14410            id = _id;
14411            hasActivities = _hasActivities;
14412        }
14413
14414        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
14415            isProc = false;
14416            label = _label;
14417            shortLabel = _shortLabel;
14418            pss = _pss;
14419            id = _id;
14420            hasActivities = false;
14421        }
14422    }
14423
14424    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
14425            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
14426        if (sort && !isCompact) {
14427            Collections.sort(items, new Comparator<MemItem>() {
14428                @Override
14429                public int compare(MemItem lhs, MemItem rhs) {
14430                    if (lhs.pss < rhs.pss) {
14431                        return 1;
14432                    } else if (lhs.pss > rhs.pss) {
14433                        return -1;
14434                    }
14435                    return 0;
14436                }
14437            });
14438        }
14439
14440        for (int i=0; i<items.size(); i++) {
14441            MemItem mi = items.get(i);
14442            if (!isCompact) {
14443                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
14444            } else if (mi.isProc) {
14445                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
14446                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
14447                pw.println(mi.hasActivities ? ",a" : ",e");
14448            } else {
14449                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
14450                pw.println(mi.pss);
14451            }
14452            if (mi.subitems != null) {
14453                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
14454                        true, isCompact);
14455            }
14456        }
14457    }
14458
14459    // These are in KB.
14460    static final long[] DUMP_MEM_BUCKETS = new long[] {
14461        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
14462        120*1024, 160*1024, 200*1024,
14463        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
14464        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
14465    };
14466
14467    static final void appendMemBucket(StringBuilder out, long memKB, String label,
14468            boolean stackLike) {
14469        int start = label.lastIndexOf('.');
14470        if (start >= 0) start++;
14471        else start = 0;
14472        int end = label.length();
14473        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
14474            if (DUMP_MEM_BUCKETS[i] >= memKB) {
14475                long bucket = DUMP_MEM_BUCKETS[i]/1024;
14476                out.append(bucket);
14477                out.append(stackLike ? "MB." : "MB ");
14478                out.append(label, start, end);
14479                return;
14480            }
14481        }
14482        out.append(memKB/1024);
14483        out.append(stackLike ? "MB." : "MB ");
14484        out.append(label, start, end);
14485    }
14486
14487    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
14488            ProcessList.NATIVE_ADJ,
14489            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
14490            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
14491            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
14492            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
14493            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
14494            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
14495    };
14496    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
14497            "Native",
14498            "System", "Persistent", "Persistent Service", "Foreground",
14499            "Visible", "Perceptible",
14500            "Heavy Weight", "Backup",
14501            "A Services", "Home",
14502            "Previous", "B Services", "Cached"
14503    };
14504    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
14505            "native",
14506            "sys", "pers", "persvc", "fore",
14507            "vis", "percept",
14508            "heavy", "backup",
14509            "servicea", "home",
14510            "prev", "serviceb", "cached"
14511    };
14512
14513    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
14514            long realtime, boolean isCheckinRequest, boolean isCompact) {
14515        if (isCheckinRequest || isCompact) {
14516            // short checkin version
14517            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
14518        } else {
14519            pw.println("Applications Memory Usage (kB):");
14520            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14521        }
14522    }
14523
14524    private static final int KSM_SHARED = 0;
14525    private static final int KSM_SHARING = 1;
14526    private static final int KSM_UNSHARED = 2;
14527    private static final int KSM_VOLATILE = 3;
14528
14529    private final long[] getKsmInfo() {
14530        long[] longOut = new long[4];
14531        final int[] SINGLE_LONG_FORMAT = new int[] {
14532            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14533        };
14534        long[] longTmp = new long[1];
14535        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14536                SINGLE_LONG_FORMAT, null, longTmp, null);
14537        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14538        longTmp[0] = 0;
14539        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14540                SINGLE_LONG_FORMAT, null, longTmp, null);
14541        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14542        longTmp[0] = 0;
14543        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14544                SINGLE_LONG_FORMAT, null, longTmp, null);
14545        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14546        longTmp[0] = 0;
14547        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14548                SINGLE_LONG_FORMAT, null, longTmp, null);
14549        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14550        return longOut;
14551    }
14552
14553    final void dumpApplicationMemoryUsage(FileDescriptor fd,
14554            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
14555        boolean dumpDetails = false;
14556        boolean dumpFullDetails = false;
14557        boolean dumpDalvik = false;
14558        boolean dumpSummaryOnly = false;
14559        boolean oomOnly = false;
14560        boolean isCompact = false;
14561        boolean localOnly = false;
14562        boolean packages = false;
14563
14564        int opti = 0;
14565        while (opti < args.length) {
14566            String opt = args[opti];
14567            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14568                break;
14569            }
14570            opti++;
14571            if ("-a".equals(opt)) {
14572                dumpDetails = true;
14573                dumpFullDetails = true;
14574                dumpDalvik = true;
14575            } else if ("-d".equals(opt)) {
14576                dumpDalvik = true;
14577            } else if ("-c".equals(opt)) {
14578                isCompact = true;
14579            } else if ("-s".equals(opt)) {
14580                dumpDetails = true;
14581                dumpSummaryOnly = true;
14582            } else if ("--oom".equals(opt)) {
14583                oomOnly = true;
14584            } else if ("--local".equals(opt)) {
14585                localOnly = true;
14586            } else if ("--package".equals(opt)) {
14587                packages = true;
14588            } else if ("-h".equals(opt)) {
14589                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
14590                pw.println("  -a: include all available information for each process.");
14591                pw.println("  -d: include dalvik details.");
14592                pw.println("  -c: dump in a compact machine-parseable representation.");
14593                pw.println("  -s: dump only summary of application memory usage.");
14594                pw.println("  --oom: only show processes organized by oom adj.");
14595                pw.println("  --local: only collect details locally, don't call process.");
14596                pw.println("  --package: interpret process arg as package, dumping all");
14597                pw.println("             processes that have loaded that package.");
14598                pw.println("If [process] is specified it can be the name or ");
14599                pw.println("pid of a specific process to dump.");
14600                return;
14601            } else {
14602                pw.println("Unknown argument: " + opt + "; use -h for help");
14603            }
14604        }
14605
14606        final boolean isCheckinRequest = scanArgs(args, "--checkin");
14607        long uptime = SystemClock.uptimeMillis();
14608        long realtime = SystemClock.elapsedRealtime();
14609        final long[] tmpLong = new long[1];
14610
14611        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
14612        if (procs == null) {
14613            // No Java processes.  Maybe they want to print a native process.
14614            if (args != null && args.length > opti
14615                    && args[opti].charAt(0) != '-') {
14616                ArrayList<ProcessCpuTracker.Stats> nativeProcs
14617                        = new ArrayList<ProcessCpuTracker.Stats>();
14618                updateCpuStatsNow();
14619                int findPid = -1;
14620                try {
14621                    findPid = Integer.parseInt(args[opti]);
14622                } catch (NumberFormatException e) {
14623                }
14624                synchronized (mProcessCpuTracker) {
14625                    final int N = mProcessCpuTracker.countStats();
14626                    for (int i=0; i<N; i++) {
14627                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14628                        if (st.pid == findPid || (st.baseName != null
14629                                && st.baseName.equals(args[opti]))) {
14630                            nativeProcs.add(st);
14631                        }
14632                    }
14633                }
14634                if (nativeProcs.size() > 0) {
14635                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14636                            isCompact);
14637                    Debug.MemoryInfo mi = null;
14638                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14639                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14640                        final int pid = r.pid;
14641                        if (!isCheckinRequest && dumpDetails) {
14642                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14643                        }
14644                        if (mi == null) {
14645                            mi = new Debug.MemoryInfo();
14646                        }
14647                        if (dumpDetails || (!brief && !oomOnly)) {
14648                            Debug.getMemoryInfo(pid, mi);
14649                        } else {
14650                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14651                            mi.dalvikPrivateDirty = (int)tmpLong[0];
14652                        }
14653                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14654                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14655                        if (isCheckinRequest) {
14656                            pw.println();
14657                        }
14658                    }
14659                    return;
14660                }
14661            }
14662            pw.println("No process found for: " + args[opti]);
14663            return;
14664        }
14665
14666        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14667            dumpDetails = true;
14668        }
14669
14670        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14671
14672        String[] innerArgs = new String[args.length-opti];
14673        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14674
14675        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14676        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14677        long nativePss = 0;
14678        long dalvikPss = 0;
14679        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
14680                EmptyArray.LONG;
14681        long otherPss = 0;
14682        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14683
14684        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14685        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14686                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14687
14688        long totalPss = 0;
14689        long cachedPss = 0;
14690
14691        Debug.MemoryInfo mi = null;
14692        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14693            final ProcessRecord r = procs.get(i);
14694            final IApplicationThread thread;
14695            final int pid;
14696            final int oomAdj;
14697            final boolean hasActivities;
14698            synchronized (this) {
14699                thread = r.thread;
14700                pid = r.pid;
14701                oomAdj = r.getSetAdjWithServices();
14702                hasActivities = r.activities.size() > 0;
14703            }
14704            if (thread != null) {
14705                if (!isCheckinRequest && dumpDetails) {
14706                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14707                }
14708                if (mi == null) {
14709                    mi = new Debug.MemoryInfo();
14710                }
14711                if (dumpDetails || (!brief && !oomOnly)) {
14712                    Debug.getMemoryInfo(pid, mi);
14713                } else {
14714                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14715                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14716                }
14717                if (dumpDetails) {
14718                    if (localOnly) {
14719                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14720                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
14721                        if (isCheckinRequest) {
14722                            pw.println();
14723                        }
14724                    } else {
14725                        try {
14726                            pw.flush();
14727                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14728                                    dumpDalvik, dumpSummaryOnly, innerArgs);
14729                        } catch (RemoteException e) {
14730                            if (!isCheckinRequest) {
14731                                pw.println("Got RemoteException!");
14732                                pw.flush();
14733                            }
14734                        }
14735                    }
14736                }
14737
14738                final long myTotalPss = mi.getTotalPss();
14739                final long myTotalUss = mi.getTotalUss();
14740
14741                synchronized (this) {
14742                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14743                        // Record this for posterity if the process has been stable.
14744                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14745                    }
14746                }
14747
14748                if (!isCheckinRequest && mi != null) {
14749                    totalPss += myTotalPss;
14750                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14751                            (hasActivities ? " / activities)" : ")"),
14752                            r.processName, myTotalPss, pid, hasActivities);
14753                    procMems.add(pssItem);
14754                    procMemsMap.put(pid, pssItem);
14755
14756                    nativePss += mi.nativePss;
14757                    dalvikPss += mi.dalvikPss;
14758                    for (int j=0; j<dalvikSubitemPss.length; j++) {
14759                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
14760                    }
14761                    otherPss += mi.otherPss;
14762                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14763                        long mem = mi.getOtherPss(j);
14764                        miscPss[j] += mem;
14765                        otherPss -= mem;
14766                    }
14767
14768                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14769                        cachedPss += myTotalPss;
14770                    }
14771
14772                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14773                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14774                                || oomIndex == (oomPss.length-1)) {
14775                            oomPss[oomIndex] += myTotalPss;
14776                            if (oomProcs[oomIndex] == null) {
14777                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14778                            }
14779                            oomProcs[oomIndex].add(pssItem);
14780                            break;
14781                        }
14782                    }
14783                }
14784            }
14785        }
14786
14787        long nativeProcTotalPss = 0;
14788
14789        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14790            // If we are showing aggregations, also look for native processes to
14791            // include so that our aggregations are more accurate.
14792            updateCpuStatsNow();
14793            mi = null;
14794            synchronized (mProcessCpuTracker) {
14795                final int N = mProcessCpuTracker.countStats();
14796                for (int i=0; i<N; i++) {
14797                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14798                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14799                        if (mi == null) {
14800                            mi = new Debug.MemoryInfo();
14801                        }
14802                        if (!brief && !oomOnly) {
14803                            Debug.getMemoryInfo(st.pid, mi);
14804                        } else {
14805                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14806                            mi.nativePrivateDirty = (int)tmpLong[0];
14807                        }
14808
14809                        final long myTotalPss = mi.getTotalPss();
14810                        totalPss += myTotalPss;
14811                        nativeProcTotalPss += myTotalPss;
14812
14813                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14814                                st.name, myTotalPss, st.pid, false);
14815                        procMems.add(pssItem);
14816
14817                        nativePss += mi.nativePss;
14818                        dalvikPss += mi.dalvikPss;
14819                        for (int j=0; j<dalvikSubitemPss.length; j++) {
14820                            dalvikSubitemPss[j] += mi.getOtherPss(
14821                                    Debug.MemoryInfo.NUM_OTHER_STATS + j);
14822                        }
14823                        otherPss += mi.otherPss;
14824                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14825                            long mem = mi.getOtherPss(j);
14826                            miscPss[j] += mem;
14827                            otherPss -= mem;
14828                        }
14829                        oomPss[0] += myTotalPss;
14830                        if (oomProcs[0] == null) {
14831                            oomProcs[0] = new ArrayList<MemItem>();
14832                        }
14833                        oomProcs[0].add(pssItem);
14834                    }
14835                }
14836            }
14837
14838            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14839
14840            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14841            final MemItem dalvikItem = new MemItem("Dalvik", "Dalvik", dalvikPss, -2);
14842            if (dalvikSubitemPss.length > 0) {
14843                dalvikItem.subitems = new ArrayList<MemItem>();
14844                for (int j=0; j<dalvikSubitemPss.length; j++) {
14845                    final String name = Debug.MemoryInfo.getOtherLabel(
14846                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
14847                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j], j));
14848                }
14849            }
14850            catMems.add(dalvikItem);
14851            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14852            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14853                String label = Debug.MemoryInfo.getOtherLabel(j);
14854                catMems.add(new MemItem(label, label, miscPss[j], j));
14855            }
14856
14857            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14858            for (int j=0; j<oomPss.length; j++) {
14859                if (oomPss[j] != 0) {
14860                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14861                            : DUMP_MEM_OOM_LABEL[j];
14862                    MemItem item = new MemItem(label, label, oomPss[j],
14863                            DUMP_MEM_OOM_ADJ[j]);
14864                    item.subitems = oomProcs[j];
14865                    oomMems.add(item);
14866                }
14867            }
14868
14869            if (!brief && !oomOnly && !isCompact) {
14870                pw.println();
14871                pw.println("Total PSS by process:");
14872                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14873                pw.println();
14874            }
14875            if (!isCompact) {
14876                pw.println("Total PSS by OOM adjustment:");
14877            }
14878            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14879            if (!brief && !oomOnly) {
14880                PrintWriter out = categoryPw != null ? categoryPw : pw;
14881                if (!isCompact) {
14882                    out.println();
14883                    out.println("Total PSS by category:");
14884                }
14885                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14886            }
14887            if (!isCompact) {
14888                pw.println();
14889            }
14890            MemInfoReader memInfo = new MemInfoReader();
14891            memInfo.readMemInfo();
14892            if (nativeProcTotalPss > 0) {
14893                synchronized (this) {
14894                    final long cachedKb = memInfo.getCachedSizeKb();
14895                    final long freeKb = memInfo.getFreeSizeKb();
14896                    final long zramKb = memInfo.getZramTotalSizeKb();
14897                    final long kernelKb = memInfo.getKernelUsedSizeKb();
14898                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
14899                            kernelKb*1024, nativeProcTotalPss*1024);
14900                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
14901                            nativeProcTotalPss);
14902                }
14903            }
14904            if (!brief) {
14905                if (!isCompact) {
14906                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14907                    pw.print(" kB (status ");
14908                    switch (mLastMemoryLevel) {
14909                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14910                            pw.println("normal)");
14911                            break;
14912                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14913                            pw.println("moderate)");
14914                            break;
14915                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14916                            pw.println("low)");
14917                            break;
14918                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14919                            pw.println("critical)");
14920                            break;
14921                        default:
14922                            pw.print(mLastMemoryLevel);
14923                            pw.println(")");
14924                            break;
14925                    }
14926                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14927                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14928                            pw.print(cachedPss); pw.print(" cached pss + ");
14929                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14930                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14931                } else {
14932                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14933                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14934                            + memInfo.getFreeSizeKb()); pw.print(",");
14935                    pw.println(totalPss - cachedPss);
14936                }
14937            }
14938            if (!isCompact) {
14939                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14940                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14941                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14942                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14943                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14944                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14945                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14946            }
14947            if (!brief) {
14948                if (memInfo.getZramTotalSizeKb() != 0) {
14949                    if (!isCompact) {
14950                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14951                                pw.print(" kB physical used for ");
14952                                pw.print(memInfo.getSwapTotalSizeKb()
14953                                        - memInfo.getSwapFreeSizeKb());
14954                                pw.print(" kB in swap (");
14955                                pw.print(memInfo.getSwapTotalSizeKb());
14956                                pw.println(" kB total swap)");
14957                    } else {
14958                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14959                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14960                                pw.println(memInfo.getSwapFreeSizeKb());
14961                    }
14962                }
14963                final long[] ksm = getKsmInfo();
14964                if (!isCompact) {
14965                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14966                            || ksm[KSM_VOLATILE] != 0) {
14967                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14968                                pw.print(" kB saved from shared ");
14969                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14970                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14971                                pw.print(" kB unshared; ");
14972                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14973                    }
14974                    pw.print("   Tuning: ");
14975                    pw.print(ActivityManager.staticGetMemoryClass());
14976                    pw.print(" (large ");
14977                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14978                    pw.print("), oom ");
14979                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14980                    pw.print(" kB");
14981                    pw.print(", restore limit ");
14982                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14983                    pw.print(" kB");
14984                    if (ActivityManager.isLowRamDeviceStatic()) {
14985                        pw.print(" (low-ram)");
14986                    }
14987                    if (ActivityManager.isHighEndGfx()) {
14988                        pw.print(" (high-end-gfx)");
14989                    }
14990                    pw.println();
14991                } else {
14992                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14993                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14994                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14995                    pw.print("tuning,");
14996                    pw.print(ActivityManager.staticGetMemoryClass());
14997                    pw.print(',');
14998                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14999                    pw.print(',');
15000                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15001                    if (ActivityManager.isLowRamDeviceStatic()) {
15002                        pw.print(",low-ram");
15003                    }
15004                    if (ActivityManager.isHighEndGfx()) {
15005                        pw.print(",high-end-gfx");
15006                    }
15007                    pw.println();
15008                }
15009            }
15010        }
15011    }
15012
15013    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15014            long memtrack, String name) {
15015        sb.append("  ");
15016        sb.append(ProcessList.makeOomAdjString(oomAdj));
15017        sb.append(' ');
15018        sb.append(ProcessList.makeProcStateString(procState));
15019        sb.append(' ');
15020        ProcessList.appendRamKb(sb, pss);
15021        sb.append(" kB: ");
15022        sb.append(name);
15023        if (memtrack > 0) {
15024            sb.append(" (");
15025            sb.append(memtrack);
15026            sb.append(" kB memtrack)");
15027        }
15028    }
15029
15030    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15031        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15032        sb.append(" (pid ");
15033        sb.append(mi.pid);
15034        sb.append(") ");
15035        sb.append(mi.adjType);
15036        sb.append('\n');
15037        if (mi.adjReason != null) {
15038            sb.append("                      ");
15039            sb.append(mi.adjReason);
15040            sb.append('\n');
15041        }
15042    }
15043
15044    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15045        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15046        for (int i=0, N=memInfos.size(); i<N; i++) {
15047            ProcessMemInfo mi = memInfos.get(i);
15048            infoMap.put(mi.pid, mi);
15049        }
15050        updateCpuStatsNow();
15051        long[] memtrackTmp = new long[1];
15052        synchronized (mProcessCpuTracker) {
15053            final int N = mProcessCpuTracker.countStats();
15054            for (int i=0; i<N; i++) {
15055                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15056                if (st.vsize > 0) {
15057                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
15058                    if (pss > 0) {
15059                        if (infoMap.indexOfKey(st.pid) < 0) {
15060                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15061                                    ProcessList.NATIVE_ADJ, -1, "native", null);
15062                            mi.pss = pss;
15063                            mi.memtrack = memtrackTmp[0];
15064                            memInfos.add(mi);
15065                        }
15066                    }
15067                }
15068            }
15069        }
15070
15071        long totalPss = 0;
15072        long totalMemtrack = 0;
15073        for (int i=0, N=memInfos.size(); i<N; i++) {
15074            ProcessMemInfo mi = memInfos.get(i);
15075            if (mi.pss == 0) {
15076                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15077                mi.memtrack = memtrackTmp[0];
15078            }
15079            totalPss += mi.pss;
15080            totalMemtrack += mi.memtrack;
15081        }
15082        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15083            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15084                if (lhs.oomAdj != rhs.oomAdj) {
15085                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15086                }
15087                if (lhs.pss != rhs.pss) {
15088                    return lhs.pss < rhs.pss ? 1 : -1;
15089                }
15090                return 0;
15091            }
15092        });
15093
15094        StringBuilder tag = new StringBuilder(128);
15095        StringBuilder stack = new StringBuilder(128);
15096        tag.append("Low on memory -- ");
15097        appendMemBucket(tag, totalPss, "total", false);
15098        appendMemBucket(stack, totalPss, "total", true);
15099
15100        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15101        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15102        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15103
15104        boolean firstLine = true;
15105        int lastOomAdj = Integer.MIN_VALUE;
15106        long extraNativeRam = 0;
15107        long extraNativeMemtrack = 0;
15108        long cachedPss = 0;
15109        for (int i=0, N=memInfos.size(); i<N; i++) {
15110            ProcessMemInfo mi = memInfos.get(i);
15111
15112            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15113                cachedPss += mi.pss;
15114            }
15115
15116            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15117                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15118                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15119                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15120                if (lastOomAdj != mi.oomAdj) {
15121                    lastOomAdj = mi.oomAdj;
15122                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15123                        tag.append(" / ");
15124                    }
15125                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15126                        if (firstLine) {
15127                            stack.append(":");
15128                            firstLine = false;
15129                        }
15130                        stack.append("\n\t at ");
15131                    } else {
15132                        stack.append("$");
15133                    }
15134                } else {
15135                    tag.append(" ");
15136                    stack.append("$");
15137                }
15138                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15139                    appendMemBucket(tag, mi.pss, mi.name, false);
15140                }
15141                appendMemBucket(stack, mi.pss, mi.name, true);
15142                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15143                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15144                    stack.append("(");
15145                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15146                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15147                            stack.append(DUMP_MEM_OOM_LABEL[k]);
15148                            stack.append(":");
15149                            stack.append(DUMP_MEM_OOM_ADJ[k]);
15150                        }
15151                    }
15152                    stack.append(")");
15153                }
15154            }
15155
15156            appendMemInfo(fullNativeBuilder, mi);
15157            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15158                // The short form only has native processes that are >= 512K.
15159                if (mi.pss >= 512) {
15160                    appendMemInfo(shortNativeBuilder, mi);
15161                } else {
15162                    extraNativeRam += mi.pss;
15163                    extraNativeMemtrack += mi.memtrack;
15164                }
15165            } else {
15166                // Short form has all other details, but if we have collected RAM
15167                // from smaller native processes let's dump a summary of that.
15168                if (extraNativeRam > 0) {
15169                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15170                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15171                    shortNativeBuilder.append('\n');
15172                    extraNativeRam = 0;
15173                }
15174                appendMemInfo(fullJavaBuilder, mi);
15175            }
15176        }
15177
15178        fullJavaBuilder.append("           ");
15179        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15180        fullJavaBuilder.append(" kB: TOTAL");
15181        if (totalMemtrack > 0) {
15182            fullJavaBuilder.append(" (");
15183            fullJavaBuilder.append(totalMemtrack);
15184            fullJavaBuilder.append(" kB memtrack)");
15185        } else {
15186        }
15187        fullJavaBuilder.append("\n");
15188
15189        MemInfoReader memInfo = new MemInfoReader();
15190        memInfo.readMemInfo();
15191        final long[] infos = memInfo.getRawInfo();
15192
15193        StringBuilder memInfoBuilder = new StringBuilder(1024);
15194        Debug.getMemInfo(infos);
15195        memInfoBuilder.append("  MemInfo: ");
15196        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
15197        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
15198        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
15199        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
15200        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
15201        memInfoBuilder.append("           ");
15202        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
15203        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
15204        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
15205        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
15206        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15207            memInfoBuilder.append("  ZRAM: ");
15208            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
15209            memInfoBuilder.append(" kB RAM, ");
15210            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
15211            memInfoBuilder.append(" kB swap total, ");
15212            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
15213            memInfoBuilder.append(" kB swap free\n");
15214        }
15215        final long[] ksm = getKsmInfo();
15216        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15217                || ksm[KSM_VOLATILE] != 0) {
15218            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
15219            memInfoBuilder.append(" kB saved from shared ");
15220            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
15221            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
15222            memInfoBuilder.append(" kB unshared; ");
15223            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
15224        }
15225        memInfoBuilder.append("  Free RAM: ");
15226        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
15227                + memInfo.getFreeSizeKb());
15228        memInfoBuilder.append(" kB\n");
15229        memInfoBuilder.append("  Used RAM: ");
15230        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
15231        memInfoBuilder.append(" kB\n");
15232        memInfoBuilder.append("  Lost RAM: ");
15233        memInfoBuilder.append(memInfo.getTotalSizeKb()
15234                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15235                - memInfo.getKernelUsedSizeKb());
15236        memInfoBuilder.append(" kB\n");
15237        Slog.i(TAG, "Low on memory:");
15238        Slog.i(TAG, shortNativeBuilder.toString());
15239        Slog.i(TAG, fullJavaBuilder.toString());
15240        Slog.i(TAG, memInfoBuilder.toString());
15241
15242        StringBuilder dropBuilder = new StringBuilder(1024);
15243        /*
15244        StringWriter oomSw = new StringWriter();
15245        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
15246        StringWriter catSw = new StringWriter();
15247        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15248        String[] emptyArgs = new String[] { };
15249        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
15250        oomPw.flush();
15251        String oomString = oomSw.toString();
15252        */
15253        dropBuilder.append("Low on memory:");
15254        dropBuilder.append(stack);
15255        dropBuilder.append('\n');
15256        dropBuilder.append(fullNativeBuilder);
15257        dropBuilder.append(fullJavaBuilder);
15258        dropBuilder.append('\n');
15259        dropBuilder.append(memInfoBuilder);
15260        dropBuilder.append('\n');
15261        /*
15262        dropBuilder.append(oomString);
15263        dropBuilder.append('\n');
15264        */
15265        StringWriter catSw = new StringWriter();
15266        synchronized (ActivityManagerService.this) {
15267            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15268            String[] emptyArgs = new String[] { };
15269            catPw.println();
15270            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
15271            catPw.println();
15272            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
15273                    false, false, null);
15274            catPw.println();
15275            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
15276            catPw.flush();
15277        }
15278        dropBuilder.append(catSw.toString());
15279        addErrorToDropBox("lowmem", null, "system_server", null,
15280                null, tag.toString(), dropBuilder.toString(), null, null);
15281        //Slog.i(TAG, "Sent to dropbox:");
15282        //Slog.i(TAG, dropBuilder.toString());
15283        synchronized (ActivityManagerService.this) {
15284            long now = SystemClock.uptimeMillis();
15285            if (mLastMemUsageReportTime < now) {
15286                mLastMemUsageReportTime = now;
15287            }
15288        }
15289    }
15290
15291    /**
15292     * Searches array of arguments for the specified string
15293     * @param args array of argument strings
15294     * @param value value to search for
15295     * @return true if the value is contained in the array
15296     */
15297    private static boolean scanArgs(String[] args, String value) {
15298        if (args != null) {
15299            for (String arg : args) {
15300                if (value.equals(arg)) {
15301                    return true;
15302                }
15303            }
15304        }
15305        return false;
15306    }
15307
15308    private final boolean removeDyingProviderLocked(ProcessRecord proc,
15309            ContentProviderRecord cpr, boolean always) {
15310        final boolean inLaunching = mLaunchingProviders.contains(cpr);
15311
15312        if (!inLaunching || always) {
15313            synchronized (cpr) {
15314                cpr.launchingApp = null;
15315                cpr.notifyAll();
15316            }
15317            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
15318            String names[] = cpr.info.authority.split(";");
15319            for (int j = 0; j < names.length; j++) {
15320                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
15321            }
15322        }
15323
15324        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
15325            ContentProviderConnection conn = cpr.connections.get(i);
15326            if (conn.waiting) {
15327                // If this connection is waiting for the provider, then we don't
15328                // need to mess with its process unless we are always removing
15329                // or for some reason the provider is not currently launching.
15330                if (inLaunching && !always) {
15331                    continue;
15332                }
15333            }
15334            ProcessRecord capp = conn.client;
15335            conn.dead = true;
15336            if (conn.stableCount > 0) {
15337                if (!capp.persistent && capp.thread != null
15338                        && capp.pid != 0
15339                        && capp.pid != MY_PID) {
15340                    capp.kill("depends on provider "
15341                            + cpr.name.flattenToShortString()
15342                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
15343                }
15344            } else if (capp.thread != null && conn.provider.provider != null) {
15345                try {
15346                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
15347                } catch (RemoteException e) {
15348                }
15349                // In the protocol here, we don't expect the client to correctly
15350                // clean up this connection, we'll just remove it.
15351                cpr.connections.remove(i);
15352                if (conn.client.conProviders.remove(conn)) {
15353                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
15354                }
15355            }
15356        }
15357
15358        if (inLaunching && always) {
15359            mLaunchingProviders.remove(cpr);
15360        }
15361        return inLaunching;
15362    }
15363
15364    /**
15365     * Main code for cleaning up a process when it has gone away.  This is
15366     * called both as a result of the process dying, or directly when stopping
15367     * a process when running in single process mode.
15368     *
15369     * @return Returns true if the given process has been restarted, so the
15370     * app that was passed in must remain on the process lists.
15371     */
15372    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
15373            boolean restarting, boolean allowRestart, int index) {
15374        if (index >= 0) {
15375            removeLruProcessLocked(app);
15376            ProcessList.remove(app.pid);
15377        }
15378
15379        mProcessesToGc.remove(app);
15380        mPendingPssProcesses.remove(app);
15381
15382        // Dismiss any open dialogs.
15383        if (app.crashDialog != null && !app.forceCrashReport) {
15384            app.crashDialog.dismiss();
15385            app.crashDialog = null;
15386        }
15387        if (app.anrDialog != null) {
15388            app.anrDialog.dismiss();
15389            app.anrDialog = null;
15390        }
15391        if (app.waitDialog != null) {
15392            app.waitDialog.dismiss();
15393            app.waitDialog = null;
15394        }
15395
15396        app.crashing = false;
15397        app.notResponding = false;
15398
15399        app.resetPackageList(mProcessStats);
15400        app.unlinkDeathRecipient();
15401        app.makeInactive(mProcessStats);
15402        app.waitingToKill = null;
15403        app.forcingToForeground = null;
15404        updateProcessForegroundLocked(app, false, false);
15405        app.foregroundActivities = false;
15406        app.hasShownUi = false;
15407        app.treatLikeActivity = false;
15408        app.hasAboveClient = false;
15409        app.hasClientActivities = false;
15410
15411        mServices.killServicesLocked(app, allowRestart);
15412
15413        boolean restart = false;
15414
15415        // Remove published content providers.
15416        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
15417            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
15418            final boolean always = app.bad || !allowRestart;
15419            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
15420            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
15421                // We left the provider in the launching list, need to
15422                // restart it.
15423                restart = true;
15424            }
15425
15426            cpr.provider = null;
15427            cpr.proc = null;
15428        }
15429        app.pubProviders.clear();
15430
15431        // Take care of any launching providers waiting for this process.
15432        if (checkAppInLaunchingProvidersLocked(app, false)) {
15433            restart = true;
15434        }
15435
15436        // Unregister from connected content providers.
15437        if (!app.conProviders.isEmpty()) {
15438            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
15439                ContentProviderConnection conn = app.conProviders.get(i);
15440                conn.provider.connections.remove(conn);
15441                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
15442                        conn.provider.name);
15443            }
15444            app.conProviders.clear();
15445        }
15446
15447        // At this point there may be remaining entries in mLaunchingProviders
15448        // where we were the only one waiting, so they are no longer of use.
15449        // Look for these and clean up if found.
15450        // XXX Commented out for now.  Trying to figure out a way to reproduce
15451        // the actual situation to identify what is actually going on.
15452        if (false) {
15453            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15454                ContentProviderRecord cpr = mLaunchingProviders.get(i);
15455                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
15456                    synchronized (cpr) {
15457                        cpr.launchingApp = null;
15458                        cpr.notifyAll();
15459                    }
15460                }
15461            }
15462        }
15463
15464        skipCurrentReceiverLocked(app);
15465
15466        // Unregister any receivers.
15467        for (int i = app.receivers.size() - 1; i >= 0; i--) {
15468            removeReceiverLocked(app.receivers.valueAt(i));
15469        }
15470        app.receivers.clear();
15471
15472        // If the app is undergoing backup, tell the backup manager about it
15473        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
15474            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
15475                    + mBackupTarget.appInfo + " died during backup");
15476            try {
15477                IBackupManager bm = IBackupManager.Stub.asInterface(
15478                        ServiceManager.getService(Context.BACKUP_SERVICE));
15479                bm.agentDisconnected(app.info.packageName);
15480            } catch (RemoteException e) {
15481                // can't happen; backup manager is local
15482            }
15483        }
15484
15485        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
15486            ProcessChangeItem item = mPendingProcessChanges.get(i);
15487            if (item.pid == app.pid) {
15488                mPendingProcessChanges.remove(i);
15489                mAvailProcessChanges.add(item);
15490            }
15491        }
15492        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
15493
15494        // If the caller is restarting this app, then leave it in its
15495        // current lists and let the caller take care of it.
15496        if (restarting) {
15497            return false;
15498        }
15499
15500        if (!app.persistent || app.isolated) {
15501            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
15502                    "Removing non-persistent process during cleanup: " + app);
15503            removeProcessNameLocked(app.processName, app.uid);
15504            if (mHeavyWeightProcess == app) {
15505                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
15506                        mHeavyWeightProcess.userId, 0));
15507                mHeavyWeightProcess = null;
15508            }
15509        } else if (!app.removed) {
15510            // This app is persistent, so we need to keep its record around.
15511            // If it is not already on the pending app list, add it there
15512            // and start a new process for it.
15513            if (mPersistentStartingProcesses.indexOf(app) < 0) {
15514                mPersistentStartingProcesses.add(app);
15515                restart = true;
15516            }
15517        }
15518        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
15519                TAG_CLEANUP, "Clean-up removing on hold: " + app);
15520        mProcessesOnHold.remove(app);
15521
15522        if (app == mHomeProcess) {
15523            mHomeProcess = null;
15524        }
15525        if (app == mPreviousProcess) {
15526            mPreviousProcess = null;
15527        }
15528
15529        if (restart && !app.isolated) {
15530            // We have components that still need to be running in the
15531            // process, so re-launch it.
15532            if (index < 0) {
15533                ProcessList.remove(app.pid);
15534            }
15535            addProcessNameLocked(app);
15536            startProcessLocked(app, "restart", app.processName);
15537            return true;
15538        } else if (app.pid > 0 && app.pid != MY_PID) {
15539            // Goodbye!
15540            boolean removed;
15541            synchronized (mPidsSelfLocked) {
15542                mPidsSelfLocked.remove(app.pid);
15543                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
15544            }
15545            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
15546            if (app.isolated) {
15547                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
15548            }
15549            app.setPid(0);
15550        }
15551        return false;
15552    }
15553
15554    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
15555        // Look through the content providers we are waiting to have launched,
15556        // and if any run in this process then either schedule a restart of
15557        // the process or kill the client waiting for it if this process has
15558        // gone bad.
15559        boolean restart = false;
15560        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15561            ContentProviderRecord cpr = mLaunchingProviders.get(i);
15562            if (cpr.launchingApp == app) {
15563                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
15564                    restart = true;
15565                } else {
15566                    removeDyingProviderLocked(app, cpr, true);
15567                }
15568            }
15569        }
15570        return restart;
15571    }
15572
15573    // =========================================================
15574    // SERVICES
15575    // =========================================================
15576
15577    @Override
15578    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
15579            int flags) {
15580        enforceNotIsolatedCaller("getServices");
15581        synchronized (this) {
15582            return mServices.getRunningServiceInfoLocked(maxNum, flags);
15583        }
15584    }
15585
15586    @Override
15587    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
15588        enforceNotIsolatedCaller("getRunningServiceControlPanel");
15589        synchronized (this) {
15590            return mServices.getRunningServiceControlPanelLocked(name);
15591        }
15592    }
15593
15594    @Override
15595    public ComponentName startService(IApplicationThread caller, Intent service,
15596            String resolvedType, String callingPackage, int userId)
15597            throws TransactionTooLargeException {
15598        enforceNotIsolatedCaller("startService");
15599        // Refuse possible leaked file descriptors
15600        if (service != null && service.hasFileDescriptors() == true) {
15601            throw new IllegalArgumentException("File descriptors passed in Intent");
15602        }
15603
15604        if (callingPackage == null) {
15605            throw new IllegalArgumentException("callingPackage cannot be null");
15606        }
15607
15608        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15609                "startService: " + service + " type=" + resolvedType);
15610        synchronized(this) {
15611            final int callingPid = Binder.getCallingPid();
15612            final int callingUid = Binder.getCallingUid();
15613            final long origId = Binder.clearCallingIdentity();
15614            ComponentName res = mServices.startServiceLocked(caller, service,
15615                    resolvedType, callingPid, callingUid, callingPackage, userId);
15616            Binder.restoreCallingIdentity(origId);
15617            return res;
15618        }
15619    }
15620
15621    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
15622            String callingPackage, int userId)
15623            throws TransactionTooLargeException {
15624        synchronized(this) {
15625            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15626                    "startServiceInPackage: " + service + " type=" + resolvedType);
15627            final long origId = Binder.clearCallingIdentity();
15628            ComponentName res = mServices.startServiceLocked(null, service,
15629                    resolvedType, -1, uid, callingPackage, userId);
15630            Binder.restoreCallingIdentity(origId);
15631            return res;
15632        }
15633    }
15634
15635    @Override
15636    public int stopService(IApplicationThread caller, Intent service,
15637            String resolvedType, int userId) {
15638        enforceNotIsolatedCaller("stopService");
15639        // Refuse possible leaked file descriptors
15640        if (service != null && service.hasFileDescriptors() == true) {
15641            throw new IllegalArgumentException("File descriptors passed in Intent");
15642        }
15643
15644        synchronized(this) {
15645            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
15646        }
15647    }
15648
15649    @Override
15650    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
15651        enforceNotIsolatedCaller("peekService");
15652        // Refuse possible leaked file descriptors
15653        if (service != null && service.hasFileDescriptors() == true) {
15654            throw new IllegalArgumentException("File descriptors passed in Intent");
15655        }
15656
15657        if (callingPackage == null) {
15658            throw new IllegalArgumentException("callingPackage cannot be null");
15659        }
15660
15661        synchronized(this) {
15662            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
15663        }
15664    }
15665
15666    @Override
15667    public boolean stopServiceToken(ComponentName className, IBinder token,
15668            int startId) {
15669        synchronized(this) {
15670            return mServices.stopServiceTokenLocked(className, token, startId);
15671        }
15672    }
15673
15674    @Override
15675    public void setServiceForeground(ComponentName className, IBinder token,
15676            int id, Notification notification, boolean removeNotification) {
15677        synchronized(this) {
15678            mServices.setServiceForegroundLocked(className, token, id, notification,
15679                    removeNotification);
15680        }
15681    }
15682
15683    @Override
15684    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15685            boolean requireFull, String name, String callerPackage) {
15686        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15687                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15688    }
15689
15690    int unsafeConvertIncomingUser(int userId) {
15691        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15692                ? mCurrentUserId : userId;
15693    }
15694
15695    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15696            int allowMode, String name, String callerPackage) {
15697        final int callingUserId = UserHandle.getUserId(callingUid);
15698        if (callingUserId == userId) {
15699            return userId;
15700        }
15701
15702        // Note that we may be accessing mCurrentUserId outside of a lock...
15703        // shouldn't be a big deal, if this is being called outside
15704        // of a locked context there is intrinsically a race with
15705        // the value the caller will receive and someone else changing it.
15706        // We assume that USER_CURRENT_OR_SELF will use the current user; later
15707        // we will switch to the calling user if access to the current user fails.
15708        int targetUserId = unsafeConvertIncomingUser(userId);
15709
15710        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15711            final boolean allow;
15712            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15713                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15714                // If the caller has this permission, they always pass go.  And collect $200.
15715                allow = true;
15716            } else if (allowMode == ALLOW_FULL_ONLY) {
15717                // We require full access, sucks to be you.
15718                allow = false;
15719            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15720                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15721                // If the caller does not have either permission, they are always doomed.
15722                allow = false;
15723            } else if (allowMode == ALLOW_NON_FULL) {
15724                // We are blanket allowing non-full access, you lucky caller!
15725                allow = true;
15726            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15727                // We may or may not allow this depending on whether the two users are
15728                // in the same profile.
15729                synchronized (mUserProfileGroupIdsSelfLocked) {
15730                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15731                            UserInfo.NO_PROFILE_GROUP_ID);
15732                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15733                            UserInfo.NO_PROFILE_GROUP_ID);
15734                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15735                            && callingProfile == targetProfile;
15736                }
15737            } else {
15738                throw new IllegalArgumentException("Unknown mode: " + allowMode);
15739            }
15740            if (!allow) {
15741                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15742                    // In this case, they would like to just execute as their
15743                    // owner user instead of failing.
15744                    targetUserId = callingUserId;
15745                } else {
15746                    StringBuilder builder = new StringBuilder(128);
15747                    builder.append("Permission Denial: ");
15748                    builder.append(name);
15749                    if (callerPackage != null) {
15750                        builder.append(" from ");
15751                        builder.append(callerPackage);
15752                    }
15753                    builder.append(" asks to run as user ");
15754                    builder.append(userId);
15755                    builder.append(" but is calling from user ");
15756                    builder.append(UserHandle.getUserId(callingUid));
15757                    builder.append("; this requires ");
15758                    builder.append(INTERACT_ACROSS_USERS_FULL);
15759                    if (allowMode != ALLOW_FULL_ONLY) {
15760                        builder.append(" or ");
15761                        builder.append(INTERACT_ACROSS_USERS);
15762                    }
15763                    String msg = builder.toString();
15764                    Slog.w(TAG, msg);
15765                    throw new SecurityException(msg);
15766                }
15767            }
15768        }
15769        if (!allowAll && targetUserId < 0) {
15770            throw new IllegalArgumentException(
15771                    "Call does not support special user #" + targetUserId);
15772        }
15773        // Check shell permission
15774        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15775            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15776                    targetUserId)) {
15777                throw new SecurityException("Shell does not have permission to access user "
15778                        + targetUserId + "\n " + Debug.getCallers(3));
15779            }
15780        }
15781        return targetUserId;
15782    }
15783
15784    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15785            String className, int flags) {
15786        boolean result = false;
15787        // For apps that don't have pre-defined UIDs, check for permission
15788        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15789            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15790                if (ActivityManager.checkUidPermission(
15791                        INTERACT_ACROSS_USERS,
15792                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15793                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15794                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15795                            + " requests FLAG_SINGLE_USER, but app does not hold "
15796                            + INTERACT_ACROSS_USERS;
15797                    Slog.w(TAG, msg);
15798                    throw new SecurityException(msg);
15799                }
15800                // Permission passed
15801                result = true;
15802            }
15803        } else if ("system".equals(componentProcessName)) {
15804            result = true;
15805        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15806            // Phone app and persistent apps are allowed to export singleuser providers.
15807            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15808                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15809        }
15810        if (DEBUG_MU) Slog.v(TAG_MU,
15811                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
15812                + Integer.toHexString(flags) + ") = " + result);
15813        return result;
15814    }
15815
15816    /**
15817     * Checks to see if the caller is in the same app as the singleton
15818     * component, or the component is in a special app. It allows special apps
15819     * to export singleton components but prevents exporting singleton
15820     * components for regular apps.
15821     */
15822    boolean isValidSingletonCall(int callingUid, int componentUid) {
15823        int componentAppId = UserHandle.getAppId(componentUid);
15824        return UserHandle.isSameApp(callingUid, componentUid)
15825                || componentAppId == Process.SYSTEM_UID
15826                || componentAppId == Process.PHONE_UID
15827                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15828                        == PackageManager.PERMISSION_GRANTED;
15829    }
15830
15831    public int bindService(IApplicationThread caller, IBinder token, Intent service,
15832            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
15833            int userId) throws TransactionTooLargeException {
15834        enforceNotIsolatedCaller("bindService");
15835
15836        // Refuse possible leaked file descriptors
15837        if (service != null && service.hasFileDescriptors() == true) {
15838            throw new IllegalArgumentException("File descriptors passed in Intent");
15839        }
15840
15841        if (callingPackage == null) {
15842            throw new IllegalArgumentException("callingPackage cannot be null");
15843        }
15844
15845        synchronized(this) {
15846            return mServices.bindServiceLocked(caller, token, service,
15847                    resolvedType, connection, flags, callingPackage, userId);
15848        }
15849    }
15850
15851    public boolean unbindService(IServiceConnection connection) {
15852        synchronized (this) {
15853            return mServices.unbindServiceLocked(connection);
15854        }
15855    }
15856
15857    public void publishService(IBinder token, Intent intent, IBinder service) {
15858        // Refuse possible leaked file descriptors
15859        if (intent != null && intent.hasFileDescriptors() == true) {
15860            throw new IllegalArgumentException("File descriptors passed in Intent");
15861        }
15862
15863        synchronized(this) {
15864            if (!(token instanceof ServiceRecord)) {
15865                throw new IllegalArgumentException("Invalid service token");
15866            }
15867            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15868        }
15869    }
15870
15871    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15872        // Refuse possible leaked file descriptors
15873        if (intent != null && intent.hasFileDescriptors() == true) {
15874            throw new IllegalArgumentException("File descriptors passed in Intent");
15875        }
15876
15877        synchronized(this) {
15878            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15879        }
15880    }
15881
15882    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15883        synchronized(this) {
15884            if (!(token instanceof ServiceRecord)) {
15885                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
15886                throw new IllegalArgumentException("Invalid service token");
15887            }
15888            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15889        }
15890    }
15891
15892    // =========================================================
15893    // BACKUP AND RESTORE
15894    // =========================================================
15895
15896    // Cause the target app to be launched if necessary and its backup agent
15897    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15898    // activity manager to announce its creation.
15899    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15900        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
15901                "bindBackupAgent: app=" + app + " mode=" + backupMode);
15902        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15903
15904        synchronized(this) {
15905            // !!! TODO: currently no check here that we're already bound
15906            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15907            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15908            synchronized (stats) {
15909                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15910            }
15911
15912            // Backup agent is now in use, its package can't be stopped.
15913            try {
15914                AppGlobals.getPackageManager().setPackageStoppedState(
15915                        app.packageName, false, UserHandle.getUserId(app.uid));
15916            } catch (RemoteException e) {
15917            } catch (IllegalArgumentException e) {
15918                Slog.w(TAG, "Failed trying to unstop package "
15919                        + app.packageName + ": " + e);
15920            }
15921
15922            BackupRecord r = new BackupRecord(ss, app, backupMode);
15923            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15924                    ? new ComponentName(app.packageName, app.backupAgentName)
15925                    : new ComponentName("android", "FullBackupAgent");
15926            // startProcessLocked() returns existing proc's record if it's already running
15927            ProcessRecord proc = startProcessLocked(app.processName, app,
15928                    false, 0, "backup", hostingName, false, false, false);
15929            if (proc == null) {
15930                Slog.e(TAG, "Unable to start backup agent process " + r);
15931                return false;
15932            }
15933
15934            r.app = proc;
15935            mBackupTarget = r;
15936            mBackupAppName = app.packageName;
15937
15938            // Try not to kill the process during backup
15939            updateOomAdjLocked(proc);
15940
15941            // If the process is already attached, schedule the creation of the backup agent now.
15942            // If it is not yet live, this will be done when it attaches to the framework.
15943            if (proc.thread != null) {
15944                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
15945                try {
15946                    proc.thread.scheduleCreateBackupAgent(app,
15947                            compatibilityInfoForPackageLocked(app), backupMode);
15948                } catch (RemoteException e) {
15949                    // Will time out on the backup manager side
15950                }
15951            } else {
15952                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
15953            }
15954            // Invariants: at this point, the target app process exists and the application
15955            // is either already running or in the process of coming up.  mBackupTarget and
15956            // mBackupAppName describe the app, so that when it binds back to the AM we
15957            // know that it's scheduled for a backup-agent operation.
15958        }
15959
15960        return true;
15961    }
15962
15963    @Override
15964    public void clearPendingBackup() {
15965        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
15966        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15967
15968        synchronized (this) {
15969            mBackupTarget = null;
15970            mBackupAppName = null;
15971        }
15972    }
15973
15974    // A backup agent has just come up
15975    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15976        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
15977                + " = " + agent);
15978
15979        synchronized(this) {
15980            if (!agentPackageName.equals(mBackupAppName)) {
15981                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15982                return;
15983            }
15984        }
15985
15986        long oldIdent = Binder.clearCallingIdentity();
15987        try {
15988            IBackupManager bm = IBackupManager.Stub.asInterface(
15989                    ServiceManager.getService(Context.BACKUP_SERVICE));
15990            bm.agentConnected(agentPackageName, agent);
15991        } catch (RemoteException e) {
15992            // can't happen; the backup manager service is local
15993        } catch (Exception e) {
15994            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15995            e.printStackTrace();
15996        } finally {
15997            Binder.restoreCallingIdentity(oldIdent);
15998        }
15999    }
16000
16001    // done with this agent
16002    public void unbindBackupAgent(ApplicationInfo appInfo) {
16003        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16004        if (appInfo == null) {
16005            Slog.w(TAG, "unbind backup agent for null app");
16006            return;
16007        }
16008
16009        synchronized(this) {
16010            try {
16011                if (mBackupAppName == null) {
16012                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16013                    return;
16014                }
16015
16016                if (!mBackupAppName.equals(appInfo.packageName)) {
16017                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16018                    return;
16019                }
16020
16021                // Not backing this app up any more; reset its OOM adjustment
16022                final ProcessRecord proc = mBackupTarget.app;
16023                updateOomAdjLocked(proc);
16024
16025                // If the app crashed during backup, 'thread' will be null here
16026                if (proc.thread != null) {
16027                    try {
16028                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16029                                compatibilityInfoForPackageLocked(appInfo));
16030                    } catch (Exception e) {
16031                        Slog.e(TAG, "Exception when unbinding backup agent:");
16032                        e.printStackTrace();
16033                    }
16034                }
16035            } finally {
16036                mBackupTarget = null;
16037                mBackupAppName = null;
16038            }
16039        }
16040    }
16041    // =========================================================
16042    // BROADCASTS
16043    // =========================================================
16044
16045    boolean isPendingBroadcastProcessLocked(int pid) {
16046        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16047                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16048    }
16049
16050    void skipPendingBroadcastLocked(int pid) {
16051            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16052            for (BroadcastQueue queue : mBroadcastQueues) {
16053                queue.skipPendingBroadcastLocked(pid);
16054            }
16055    }
16056
16057    // The app just attached; send any pending broadcasts that it should receive
16058    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16059        boolean didSomething = false;
16060        for (BroadcastQueue queue : mBroadcastQueues) {
16061            didSomething |= queue.sendPendingBroadcastsLocked(app);
16062        }
16063        return didSomething;
16064    }
16065
16066    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16067            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16068        enforceNotIsolatedCaller("registerReceiver");
16069        ArrayList<Intent> stickyIntents = null;
16070        ProcessRecord callerApp = null;
16071        int callingUid;
16072        int callingPid;
16073        synchronized(this) {
16074            if (caller != null) {
16075                callerApp = getRecordForAppLocked(caller);
16076                if (callerApp == null) {
16077                    throw new SecurityException(
16078                            "Unable to find app for caller " + caller
16079                            + " (pid=" + Binder.getCallingPid()
16080                            + ") when registering receiver " + receiver);
16081                }
16082                if (callerApp.info.uid != Process.SYSTEM_UID &&
16083                        !callerApp.pkgList.containsKey(callerPackage) &&
16084                        !"android".equals(callerPackage)) {
16085                    throw new SecurityException("Given caller package " + callerPackage
16086                            + " is not running in process " + callerApp);
16087                }
16088                callingUid = callerApp.info.uid;
16089                callingPid = callerApp.pid;
16090            } else {
16091                callerPackage = null;
16092                callingUid = Binder.getCallingUid();
16093                callingPid = Binder.getCallingPid();
16094            }
16095
16096            userId = handleIncomingUser(callingPid, callingUid, userId,
16097                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16098
16099            Iterator<String> actions = filter.actionsIterator();
16100            if (actions == null) {
16101                ArrayList<String> noAction = new ArrayList<String>(1);
16102                noAction.add(null);
16103                actions = noAction.iterator();
16104            }
16105
16106            // Collect stickies of users
16107            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16108            while (actions.hasNext()) {
16109                String action = actions.next();
16110                for (int id : userIds) {
16111                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16112                    if (stickies != null) {
16113                        ArrayList<Intent> intents = stickies.get(action);
16114                        if (intents != null) {
16115                            if (stickyIntents == null) {
16116                                stickyIntents = new ArrayList<Intent>();
16117                            }
16118                            stickyIntents.addAll(intents);
16119                        }
16120                    }
16121                }
16122            }
16123        }
16124
16125        ArrayList<Intent> allSticky = null;
16126        if (stickyIntents != null) {
16127            final ContentResolver resolver = mContext.getContentResolver();
16128            // Look for any matching sticky broadcasts...
16129            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16130                Intent intent = stickyIntents.get(i);
16131                // If intent has scheme "content", it will need to acccess
16132                // provider that needs to lock mProviderMap in ActivityThread
16133                // and also it may need to wait application response, so we
16134                // cannot lock ActivityManagerService here.
16135                if (filter.match(resolver, intent, true, TAG) >= 0) {
16136                    if (allSticky == null) {
16137                        allSticky = new ArrayList<Intent>();
16138                    }
16139                    allSticky.add(intent);
16140                }
16141            }
16142        }
16143
16144        // The first sticky in the list is returned directly back to the client.
16145        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16146        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16147        if (receiver == null) {
16148            return sticky;
16149        }
16150
16151        synchronized (this) {
16152            if (callerApp != null && (callerApp.thread == null
16153                    || callerApp.thread.asBinder() != caller.asBinder())) {
16154                // Original caller already died
16155                return null;
16156            }
16157            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16158            if (rl == null) {
16159                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16160                        userId, receiver);
16161                if (rl.app != null) {
16162                    rl.app.receivers.add(rl);
16163                } else {
16164                    try {
16165                        receiver.asBinder().linkToDeath(rl, 0);
16166                    } catch (RemoteException e) {
16167                        return sticky;
16168                    }
16169                    rl.linkedToDeath = true;
16170                }
16171                mRegisteredReceivers.put(receiver.asBinder(), rl);
16172            } else if (rl.uid != callingUid) {
16173                throw new IllegalArgumentException(
16174                        "Receiver requested to register for uid " + callingUid
16175                        + " was previously registered for uid " + rl.uid);
16176            } else if (rl.pid != callingPid) {
16177                throw new IllegalArgumentException(
16178                        "Receiver requested to register for pid " + callingPid
16179                        + " was previously registered for pid " + rl.pid);
16180            } else if (rl.userId != userId) {
16181                throw new IllegalArgumentException(
16182                        "Receiver requested to register for user " + userId
16183                        + " was previously registered for user " + rl.userId);
16184            }
16185            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16186                    permission, callingUid, userId);
16187            rl.add(bf);
16188            if (!bf.debugCheck()) {
16189                Slog.w(TAG, "==> For Dynamic broadcast");
16190            }
16191            mReceiverResolver.addFilter(bf);
16192
16193            // Enqueue broadcasts for all existing stickies that match
16194            // this filter.
16195            if (allSticky != null) {
16196                ArrayList receivers = new ArrayList();
16197                receivers.add(bf);
16198
16199                final int stickyCount = allSticky.size();
16200                for (int i = 0; i < stickyCount; i++) {
16201                    Intent intent = allSticky.get(i);
16202                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16203                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16204                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16205                            null, 0, null, null, false, true, true, -1);
16206                    queue.enqueueParallelBroadcastLocked(r);
16207                    queue.scheduleBroadcastsLocked();
16208                }
16209            }
16210
16211            return sticky;
16212        }
16213    }
16214
16215    public void unregisterReceiver(IIntentReceiver receiver) {
16216        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16217
16218        final long origId = Binder.clearCallingIdentity();
16219        try {
16220            boolean doTrim = false;
16221
16222            synchronized(this) {
16223                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16224                if (rl != null) {
16225                    final BroadcastRecord r = rl.curBroadcast;
16226                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16227                        final boolean doNext = r.queue.finishReceiverLocked(
16228                                r, r.resultCode, r.resultData, r.resultExtras,
16229                                r.resultAbort, false);
16230                        if (doNext) {
16231                            doTrim = true;
16232                            r.queue.processNextBroadcast(false);
16233                        }
16234                    }
16235
16236                    if (rl.app != null) {
16237                        rl.app.receivers.remove(rl);
16238                    }
16239                    removeReceiverLocked(rl);
16240                    if (rl.linkedToDeath) {
16241                        rl.linkedToDeath = false;
16242                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
16243                    }
16244                }
16245            }
16246
16247            // If we actually concluded any broadcasts, we might now be able
16248            // to trim the recipients' apps from our working set
16249            if (doTrim) {
16250                trimApplications();
16251                return;
16252            }
16253
16254        } finally {
16255            Binder.restoreCallingIdentity(origId);
16256        }
16257    }
16258
16259    void removeReceiverLocked(ReceiverList rl) {
16260        mRegisteredReceivers.remove(rl.receiver.asBinder());
16261        for (int i = rl.size() - 1; i >= 0; i--) {
16262            mReceiverResolver.removeFilter(rl.get(i));
16263        }
16264    }
16265
16266    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16267        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16268            ProcessRecord r = mLruProcesses.get(i);
16269            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16270                try {
16271                    r.thread.dispatchPackageBroadcast(cmd, packages);
16272                } catch (RemoteException ex) {
16273                }
16274            }
16275        }
16276    }
16277
16278    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16279            int callingUid, int[] users) {
16280        List<ResolveInfo> receivers = null;
16281        try {
16282            HashSet<ComponentName> singleUserReceivers = null;
16283            boolean scannedFirstReceivers = false;
16284            for (int user : users) {
16285                // Skip users that have Shell restrictions
16286                if (callingUid == Process.SHELL_UID
16287                        && getUserManagerLocked().hasUserRestriction(
16288                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
16289                    continue;
16290                }
16291                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16292                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
16293                if (user != UserHandle.USER_OWNER && newReceivers != null) {
16294                    // If this is not the primary user, we need to check for
16295                    // any receivers that should be filtered out.
16296                    for (int i=0; i<newReceivers.size(); i++) {
16297                        ResolveInfo ri = newReceivers.get(i);
16298                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
16299                            newReceivers.remove(i);
16300                            i--;
16301                        }
16302                    }
16303                }
16304                if (newReceivers != null && newReceivers.size() == 0) {
16305                    newReceivers = null;
16306                }
16307                if (receivers == null) {
16308                    receivers = newReceivers;
16309                } else if (newReceivers != null) {
16310                    // We need to concatenate the additional receivers
16311                    // found with what we have do far.  This would be easy,
16312                    // but we also need to de-dup any receivers that are
16313                    // singleUser.
16314                    if (!scannedFirstReceivers) {
16315                        // Collect any single user receivers we had already retrieved.
16316                        scannedFirstReceivers = true;
16317                        for (int i=0; i<receivers.size(); i++) {
16318                            ResolveInfo ri = receivers.get(i);
16319                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16320                                ComponentName cn = new ComponentName(
16321                                        ri.activityInfo.packageName, ri.activityInfo.name);
16322                                if (singleUserReceivers == null) {
16323                                    singleUserReceivers = new HashSet<ComponentName>();
16324                                }
16325                                singleUserReceivers.add(cn);
16326                            }
16327                        }
16328                    }
16329                    // Add the new results to the existing results, tracking
16330                    // and de-dupping single user receivers.
16331                    for (int i=0; i<newReceivers.size(); i++) {
16332                        ResolveInfo ri = newReceivers.get(i);
16333                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16334                            ComponentName cn = new ComponentName(
16335                                    ri.activityInfo.packageName, ri.activityInfo.name);
16336                            if (singleUserReceivers == null) {
16337                                singleUserReceivers = new HashSet<ComponentName>();
16338                            }
16339                            if (!singleUserReceivers.contains(cn)) {
16340                                singleUserReceivers.add(cn);
16341                                receivers.add(ri);
16342                            }
16343                        } else {
16344                            receivers.add(ri);
16345                        }
16346                    }
16347                }
16348            }
16349        } catch (RemoteException ex) {
16350            // pm is in same process, this will never happen.
16351        }
16352        return receivers;
16353    }
16354
16355    private final int broadcastIntentLocked(ProcessRecord callerApp,
16356            String callerPackage, Intent intent, String resolvedType,
16357            IIntentReceiver resultTo, int resultCode, String resultData,
16358            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle options,
16359            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
16360        intent = new Intent(intent);
16361
16362        // By default broadcasts do not go to stopped apps.
16363        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
16364
16365        // If we have not finished booting, don't allow this to launch new processes.
16366        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
16367            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16368        }
16369
16370        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
16371                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
16372                + " ordered=" + ordered + " userid=" + userId);
16373        if ((resultTo != null) && !ordered) {
16374            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
16375        }
16376
16377        userId = handleIncomingUser(callingPid, callingUid, userId,
16378                true, ALLOW_NON_FULL, "broadcast", callerPackage);
16379
16380        // Make sure that the user who is receiving this broadcast is running.
16381        // If not, we will just skip it. Make an exception for shutdown broadcasts
16382        // and upgrade steps.
16383
16384        if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
16385            if ((callingUid != Process.SYSTEM_UID
16386                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
16387                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
16388                Slog.w(TAG, "Skipping broadcast of " + intent
16389                        + ": user " + userId + " is stopped");
16390                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
16391            }
16392        }
16393
16394        BroadcastOptions brOptions = null;
16395        if (options != null) {
16396            brOptions = new BroadcastOptions(options);
16397            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
16398                // See if the caller is allowed to do this.  Note we are checking against
16399                // the actual real caller (not whoever provided the operation as say a
16400                // PendingIntent), because that who is actually supplied the arguments.
16401                if (checkComponentPermission(
16402                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
16403                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
16404                        != PackageManager.PERMISSION_GRANTED) {
16405                    String msg = "Permission Denial: " + intent.getAction()
16406                            + " broadcast from " + callerPackage + " (pid=" + callingPid
16407                            + ", uid=" + callingUid + ")"
16408                            + " requires "
16409                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
16410                    Slog.w(TAG, msg);
16411                    throw new SecurityException(msg);
16412                }
16413            }
16414        }
16415
16416        /*
16417         * Prevent non-system code (defined here to be non-persistent
16418         * processes) from sending protected broadcasts.
16419         */
16420        int callingAppId = UserHandle.getAppId(callingUid);
16421        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
16422            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
16423            || callingAppId == Process.NFC_UID || callingUid == 0) {
16424            // Always okay.
16425        } else if (callerApp == null || !callerApp.persistent) {
16426            try {
16427                if (AppGlobals.getPackageManager().isProtectedBroadcast(
16428                        intent.getAction())) {
16429                    String msg = "Permission Denial: not allowed to send broadcast "
16430                            + intent.getAction() + " from pid="
16431                            + callingPid + ", uid=" + callingUid;
16432                    Slog.w(TAG, msg);
16433                    throw new SecurityException(msg);
16434                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
16435                    // Special case for compatibility: we don't want apps to send this,
16436                    // but historically it has not been protected and apps may be using it
16437                    // to poke their own app widget.  So, instead of making it protected,
16438                    // just limit it to the caller.
16439                    if (callerApp == null) {
16440                        String msg = "Permission Denial: not allowed to send broadcast "
16441                                + intent.getAction() + " from unknown caller.";
16442                        Slog.w(TAG, msg);
16443                        throw new SecurityException(msg);
16444                    } else if (intent.getComponent() != null) {
16445                        // They are good enough to send to an explicit component...  verify
16446                        // it is being sent to the calling app.
16447                        if (!intent.getComponent().getPackageName().equals(
16448                                callerApp.info.packageName)) {
16449                            String msg = "Permission Denial: not allowed to send broadcast "
16450                                    + intent.getAction() + " to "
16451                                    + intent.getComponent().getPackageName() + " from "
16452                                    + callerApp.info.packageName;
16453                            Slog.w(TAG, msg);
16454                            throw new SecurityException(msg);
16455                        }
16456                    } else {
16457                        // Limit broadcast to their own package.
16458                        intent.setPackage(callerApp.info.packageName);
16459                    }
16460                }
16461            } catch (RemoteException e) {
16462                Slog.w(TAG, "Remote exception", e);
16463                return ActivityManager.BROADCAST_SUCCESS;
16464            }
16465        }
16466
16467        final String action = intent.getAction();
16468        if (action != null) {
16469            switch (action) {
16470                case Intent.ACTION_UID_REMOVED:
16471                case Intent.ACTION_PACKAGE_REMOVED:
16472                case Intent.ACTION_PACKAGE_CHANGED:
16473                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16474                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16475                    // Handle special intents: if this broadcast is from the package
16476                    // manager about a package being removed, we need to remove all of
16477                    // its activities from the history stack.
16478                    if (checkComponentPermission(
16479                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
16480                            callingPid, callingUid, -1, true)
16481                            != PackageManager.PERMISSION_GRANTED) {
16482                        String msg = "Permission Denial: " + intent.getAction()
16483                                + " broadcast from " + callerPackage + " (pid=" + callingPid
16484                                + ", uid=" + callingUid + ")"
16485                                + " requires "
16486                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
16487                        Slog.w(TAG, msg);
16488                        throw new SecurityException(msg);
16489                    }
16490                    switch (action) {
16491                        case Intent.ACTION_UID_REMOVED:
16492                            final Bundle intentExtras = intent.getExtras();
16493                            final int uid = intentExtras != null
16494                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
16495                            if (uid >= 0) {
16496                                mBatteryStatsService.removeUid(uid);
16497                                mAppOpsService.uidRemoved(uid);
16498                            }
16499                            break;
16500                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16501                            // If resources are unavailable just force stop all those packages
16502                            // and flush the attribute cache as well.
16503                            String list[] =
16504                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16505                            if (list != null && list.length > 0) {
16506                                for (int i = 0; i < list.length; i++) {
16507                                    forceStopPackageLocked(list[i], -1, false, true, true,
16508                                            false, false, userId, "storage unmount");
16509                                }
16510                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16511                                sendPackageBroadcastLocked(
16512                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
16513                                        userId);
16514                            }
16515                            break;
16516                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16517                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16518                            break;
16519                        case Intent.ACTION_PACKAGE_REMOVED:
16520                        case Intent.ACTION_PACKAGE_CHANGED:
16521                            Uri data = intent.getData();
16522                            String ssp;
16523                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
16524                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
16525                                boolean fullUninstall = removed &&
16526                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16527                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
16528                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
16529                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
16530                                            false, true, true, false, fullUninstall, userId,
16531                                            removed ? "pkg removed" : "pkg changed");
16532                                }
16533                                if (removed) {
16534                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
16535                                            new String[] {ssp}, userId);
16536                                    if (fullUninstall) {
16537                                        mAppOpsService.packageRemoved(
16538                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
16539
16540                                        // Remove all permissions granted from/to this package
16541                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
16542
16543                                        removeTasksByPackageNameLocked(ssp, userId);
16544                                        mBatteryStatsService.notePackageUninstalled(ssp);
16545                                    }
16546                                } else {
16547                                    cleanupDisabledPackageComponentsLocked(ssp, userId,
16548                                            intent.getStringArrayExtra(
16549                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
16550                                }
16551                            }
16552                            break;
16553                    }
16554                    break;
16555                case Intent.ACTION_PACKAGE_ADDED:
16556                    // Special case for adding a package: by default turn on compatibility mode.
16557                    Uri data = intent.getData();
16558                    String ssp;
16559                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
16560                        final boolean replacing =
16561                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16562                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
16563
16564                        try {
16565                            ApplicationInfo ai = AppGlobals.getPackageManager().
16566                                    getApplicationInfo(ssp, 0, 0);
16567                            mBatteryStatsService.notePackageInstalled(ssp,
16568                                    ai != null ? ai.versionCode : 0);
16569                        } catch (RemoteException e) {
16570                        }
16571                    }
16572                    break;
16573                case Intent.ACTION_TIMEZONE_CHANGED:
16574                    // If this is the time zone changed action, queue up a message that will reset
16575                    // the timezone of all currently running processes. This message will get
16576                    // queued up before the broadcast happens.
16577                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
16578                    break;
16579                case Intent.ACTION_TIME_CHANGED:
16580                    // If the user set the time, let all running processes know.
16581                    final int is24Hour =
16582                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
16583                                    : 0;
16584                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
16585                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16586                    synchronized (stats) {
16587                        stats.noteCurrentTimeChangedLocked();
16588                    }
16589                    break;
16590                case Intent.ACTION_CLEAR_DNS_CACHE:
16591                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
16592                    break;
16593                case Proxy.PROXY_CHANGE_ACTION:
16594                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
16595                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
16596                    break;
16597            }
16598        }
16599
16600        // Add to the sticky list if requested.
16601        if (sticky) {
16602            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
16603                    callingPid, callingUid)
16604                    != PackageManager.PERMISSION_GRANTED) {
16605                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
16606                        + callingPid + ", uid=" + callingUid
16607                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16608                Slog.w(TAG, msg);
16609                throw new SecurityException(msg);
16610            }
16611            if (requiredPermissions != null && requiredPermissions.length > 0) {
16612                Slog.w(TAG, "Can't broadcast sticky intent " + intent
16613                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
16614                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
16615            }
16616            if (intent.getComponent() != null) {
16617                throw new SecurityException(
16618                        "Sticky broadcasts can't target a specific component");
16619            }
16620            // We use userId directly here, since the "all" target is maintained
16621            // as a separate set of sticky broadcasts.
16622            if (userId != UserHandle.USER_ALL) {
16623                // But first, if this is not a broadcast to all users, then
16624                // make sure it doesn't conflict with an existing broadcast to
16625                // all users.
16626                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
16627                        UserHandle.USER_ALL);
16628                if (stickies != null) {
16629                    ArrayList<Intent> list = stickies.get(intent.getAction());
16630                    if (list != null) {
16631                        int N = list.size();
16632                        int i;
16633                        for (i=0; i<N; i++) {
16634                            if (intent.filterEquals(list.get(i))) {
16635                                throw new IllegalArgumentException(
16636                                        "Sticky broadcast " + intent + " for user "
16637                                        + userId + " conflicts with existing global broadcast");
16638                            }
16639                        }
16640                    }
16641                }
16642            }
16643            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16644            if (stickies == null) {
16645                stickies = new ArrayMap<>();
16646                mStickyBroadcasts.put(userId, stickies);
16647            }
16648            ArrayList<Intent> list = stickies.get(intent.getAction());
16649            if (list == null) {
16650                list = new ArrayList<>();
16651                stickies.put(intent.getAction(), list);
16652            }
16653            final int stickiesCount = list.size();
16654            int i;
16655            for (i = 0; i < stickiesCount; i++) {
16656                if (intent.filterEquals(list.get(i))) {
16657                    // This sticky already exists, replace it.
16658                    list.set(i, new Intent(intent));
16659                    break;
16660                }
16661            }
16662            if (i >= stickiesCount) {
16663                list.add(new Intent(intent));
16664            }
16665        }
16666
16667        int[] users;
16668        if (userId == UserHandle.USER_ALL) {
16669            // Caller wants broadcast to go to all started users.
16670            users = mStartedUserArray;
16671        } else {
16672            // Caller wants broadcast to go to one specific user.
16673            users = new int[] {userId};
16674        }
16675
16676        // Figure out who all will receive this broadcast.
16677        List receivers = null;
16678        List<BroadcastFilter> registeredReceivers = null;
16679        // Need to resolve the intent to interested receivers...
16680        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
16681                 == 0) {
16682            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
16683        }
16684        if (intent.getComponent() == null) {
16685            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
16686                // Query one target user at a time, excluding shell-restricted users
16687                UserManagerService ums = getUserManagerLocked();
16688                for (int i = 0; i < users.length; i++) {
16689                    if (ums.hasUserRestriction(
16690                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
16691                        continue;
16692                    }
16693                    List<BroadcastFilter> registeredReceiversForUser =
16694                            mReceiverResolver.queryIntent(intent,
16695                                    resolvedType, false, users[i]);
16696                    if (registeredReceivers == null) {
16697                        registeredReceivers = registeredReceiversForUser;
16698                    } else if (registeredReceiversForUser != null) {
16699                        registeredReceivers.addAll(registeredReceiversForUser);
16700                    }
16701                }
16702            } else {
16703                registeredReceivers = mReceiverResolver.queryIntent(intent,
16704                        resolvedType, false, userId);
16705            }
16706        }
16707
16708        final boolean replacePending =
16709                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16710
16711        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
16712                + " replacePending=" + replacePending);
16713
16714        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16715        if (!ordered && NR > 0) {
16716            // If we are not serializing this broadcast, then send the
16717            // registered receivers separately so they don't wait for the
16718            // components to be launched.
16719            final BroadcastQueue queue = broadcastQueueForIntent(intent);
16720            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16721                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
16722                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
16723                    resultExtras, ordered, sticky, false, userId);
16724            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
16725            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16726            if (!replaced) {
16727                queue.enqueueParallelBroadcastLocked(r);
16728                queue.scheduleBroadcastsLocked();
16729            }
16730            registeredReceivers = null;
16731            NR = 0;
16732        }
16733
16734        // Merge into one list.
16735        int ir = 0;
16736        if (receivers != null) {
16737            // A special case for PACKAGE_ADDED: do not allow the package
16738            // being added to see this broadcast.  This prevents them from
16739            // using this as a back door to get run as soon as they are
16740            // installed.  Maybe in the future we want to have a special install
16741            // broadcast or such for apps, but we'd like to deliberately make
16742            // this decision.
16743            String skipPackages[] = null;
16744            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16745                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16746                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16747                Uri data = intent.getData();
16748                if (data != null) {
16749                    String pkgName = data.getSchemeSpecificPart();
16750                    if (pkgName != null) {
16751                        skipPackages = new String[] { pkgName };
16752                    }
16753                }
16754            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16755                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16756            }
16757            if (skipPackages != null && (skipPackages.length > 0)) {
16758                for (String skipPackage : skipPackages) {
16759                    if (skipPackage != null) {
16760                        int NT = receivers.size();
16761                        for (int it=0; it<NT; it++) {
16762                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
16763                            if (curt.activityInfo.packageName.equals(skipPackage)) {
16764                                receivers.remove(it);
16765                                it--;
16766                                NT--;
16767                            }
16768                        }
16769                    }
16770                }
16771            }
16772
16773            int NT = receivers != null ? receivers.size() : 0;
16774            int it = 0;
16775            ResolveInfo curt = null;
16776            BroadcastFilter curr = null;
16777            while (it < NT && ir < NR) {
16778                if (curt == null) {
16779                    curt = (ResolveInfo)receivers.get(it);
16780                }
16781                if (curr == null) {
16782                    curr = registeredReceivers.get(ir);
16783                }
16784                if (curr.getPriority() >= curt.priority) {
16785                    // Insert this broadcast record into the final list.
16786                    receivers.add(it, curr);
16787                    ir++;
16788                    curr = null;
16789                    it++;
16790                    NT++;
16791                } else {
16792                    // Skip to the next ResolveInfo in the final list.
16793                    it++;
16794                    curt = null;
16795                }
16796            }
16797        }
16798        while (ir < NR) {
16799            if (receivers == null) {
16800                receivers = new ArrayList();
16801            }
16802            receivers.add(registeredReceivers.get(ir));
16803            ir++;
16804        }
16805
16806        if ((receivers != null && receivers.size() > 0)
16807                || resultTo != null) {
16808            BroadcastQueue queue = broadcastQueueForIntent(intent);
16809            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16810                    callerPackage, callingPid, callingUid, resolvedType,
16811                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
16812                    resultData, resultExtras, ordered, sticky, false, userId);
16813
16814            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
16815                    + ": prev had " + queue.mOrderedBroadcasts.size());
16816            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
16817                    "Enqueueing broadcast " + r.intent.getAction());
16818
16819            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16820            if (!replaced) {
16821                queue.enqueueOrderedBroadcastLocked(r);
16822                queue.scheduleBroadcastsLocked();
16823            }
16824        }
16825
16826        return ActivityManager.BROADCAST_SUCCESS;
16827    }
16828
16829    final Intent verifyBroadcastLocked(Intent intent) {
16830        // Refuse possible leaked file descriptors
16831        if (intent != null && intent.hasFileDescriptors() == true) {
16832            throw new IllegalArgumentException("File descriptors passed in Intent");
16833        }
16834
16835        int flags = intent.getFlags();
16836
16837        if (!mProcessesReady) {
16838            // if the caller really truly claims to know what they're doing, go
16839            // ahead and allow the broadcast without launching any receivers
16840            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16841                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
16842            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16843                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16844                        + " before boot completion");
16845                throw new IllegalStateException("Cannot broadcast before boot completed");
16846            }
16847        }
16848
16849        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16850            throw new IllegalArgumentException(
16851                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16852        }
16853
16854        return intent;
16855    }
16856
16857    public final int broadcastIntent(IApplicationThread caller,
16858            Intent intent, String resolvedType, IIntentReceiver resultTo,
16859            int resultCode, String resultData, Bundle resultExtras,
16860            String[] requiredPermissions, int appOp, Bundle options,
16861            boolean serialized, boolean sticky, int userId) {
16862        enforceNotIsolatedCaller("broadcastIntent");
16863        synchronized(this) {
16864            intent = verifyBroadcastLocked(intent);
16865
16866            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16867            final int callingPid = Binder.getCallingPid();
16868            final int callingUid = Binder.getCallingUid();
16869            final long origId = Binder.clearCallingIdentity();
16870            int res = broadcastIntentLocked(callerApp,
16871                    callerApp != null ? callerApp.info.packageName : null,
16872                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
16873                    requiredPermissions, appOp, null, serialized, sticky,
16874                    callingPid, callingUid, userId);
16875            Binder.restoreCallingIdentity(origId);
16876            return res;
16877        }
16878    }
16879
16880
16881    int broadcastIntentInPackage(String packageName, int uid,
16882            Intent intent, String resolvedType, IIntentReceiver resultTo,
16883            int resultCode, String resultData, Bundle resultExtras,
16884            String requiredPermission, Bundle options, boolean serialized, boolean sticky,
16885            int userId) {
16886        synchronized(this) {
16887            intent = verifyBroadcastLocked(intent);
16888
16889            final long origId = Binder.clearCallingIdentity();
16890            String[] requiredPermissions = requiredPermission == null ? null
16891                    : new String[] {requiredPermission};
16892            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16893                    resultTo, resultCode, resultData, resultExtras,
16894                    requiredPermissions, AppOpsManager.OP_NONE, options, serialized,
16895                    sticky, -1, uid, userId);
16896            Binder.restoreCallingIdentity(origId);
16897            return res;
16898        }
16899    }
16900
16901    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16902        // Refuse possible leaked file descriptors
16903        if (intent != null && intent.hasFileDescriptors() == true) {
16904            throw new IllegalArgumentException("File descriptors passed in Intent");
16905        }
16906
16907        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16908                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16909
16910        synchronized(this) {
16911            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16912                    != PackageManager.PERMISSION_GRANTED) {
16913                String msg = "Permission Denial: unbroadcastIntent() from pid="
16914                        + Binder.getCallingPid()
16915                        + ", uid=" + Binder.getCallingUid()
16916                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16917                Slog.w(TAG, msg);
16918                throw new SecurityException(msg);
16919            }
16920            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16921            if (stickies != null) {
16922                ArrayList<Intent> list = stickies.get(intent.getAction());
16923                if (list != null) {
16924                    int N = list.size();
16925                    int i;
16926                    for (i=0; i<N; i++) {
16927                        if (intent.filterEquals(list.get(i))) {
16928                            list.remove(i);
16929                            break;
16930                        }
16931                    }
16932                    if (list.size() <= 0) {
16933                        stickies.remove(intent.getAction());
16934                    }
16935                }
16936                if (stickies.size() <= 0) {
16937                    mStickyBroadcasts.remove(userId);
16938                }
16939            }
16940        }
16941    }
16942
16943    void backgroundServicesFinishedLocked(int userId) {
16944        for (BroadcastQueue queue : mBroadcastQueues) {
16945            queue.backgroundServicesFinishedLocked(userId);
16946        }
16947    }
16948
16949    public void finishReceiver(IBinder who, int resultCode, String resultData,
16950            Bundle resultExtras, boolean resultAbort, int flags) {
16951        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
16952
16953        // Refuse possible leaked file descriptors
16954        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16955            throw new IllegalArgumentException("File descriptors passed in Bundle");
16956        }
16957
16958        final long origId = Binder.clearCallingIdentity();
16959        try {
16960            boolean doNext = false;
16961            BroadcastRecord r;
16962
16963            synchronized(this) {
16964                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
16965                        ? mFgBroadcastQueue : mBgBroadcastQueue;
16966                r = queue.getMatchingOrderedReceiver(who);
16967                if (r != null) {
16968                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16969                        resultData, resultExtras, resultAbort, true);
16970                }
16971            }
16972
16973            if (doNext) {
16974                r.queue.processNextBroadcast(false);
16975            }
16976            trimApplications();
16977        } finally {
16978            Binder.restoreCallingIdentity(origId);
16979        }
16980    }
16981
16982    // =========================================================
16983    // INSTRUMENTATION
16984    // =========================================================
16985
16986    public boolean startInstrumentation(ComponentName className,
16987            String profileFile, int flags, Bundle arguments,
16988            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16989            int userId, String abiOverride) {
16990        enforceNotIsolatedCaller("startInstrumentation");
16991        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16992                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16993        // Refuse possible leaked file descriptors
16994        if (arguments != null && arguments.hasFileDescriptors()) {
16995            throw new IllegalArgumentException("File descriptors passed in Bundle");
16996        }
16997
16998        synchronized(this) {
16999            InstrumentationInfo ii = null;
17000            ApplicationInfo ai = null;
17001            try {
17002                ii = mContext.getPackageManager().getInstrumentationInfo(
17003                    className, STOCK_PM_FLAGS);
17004                ai = AppGlobals.getPackageManager().getApplicationInfo(
17005                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17006            } catch (PackageManager.NameNotFoundException e) {
17007            } catch (RemoteException e) {
17008            }
17009            if (ii == null) {
17010                reportStartInstrumentationFailure(watcher, className,
17011                        "Unable to find instrumentation info for: " + className);
17012                return false;
17013            }
17014            if (ai == null) {
17015                reportStartInstrumentationFailure(watcher, className,
17016                        "Unable to find instrumentation target package: " + ii.targetPackage);
17017                return false;
17018            }
17019
17020            int match = mContext.getPackageManager().checkSignatures(
17021                    ii.targetPackage, ii.packageName);
17022            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17023                String msg = "Permission Denial: starting instrumentation "
17024                        + className + " from pid="
17025                        + Binder.getCallingPid()
17026                        + ", uid=" + Binder.getCallingPid()
17027                        + " not allowed because package " + ii.packageName
17028                        + " does not have a signature matching the target "
17029                        + ii.targetPackage;
17030                reportStartInstrumentationFailure(watcher, className, msg);
17031                throw new SecurityException(msg);
17032            }
17033
17034            final long origId = Binder.clearCallingIdentity();
17035            // Instrumentation can kill and relaunch even persistent processes
17036            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17037                    "start instr");
17038            ProcessRecord app = addAppLocked(ai, false, abiOverride);
17039            app.instrumentationClass = className;
17040            app.instrumentationInfo = ai;
17041            app.instrumentationProfileFile = profileFile;
17042            app.instrumentationArguments = arguments;
17043            app.instrumentationWatcher = watcher;
17044            app.instrumentationUiAutomationConnection = uiAutomationConnection;
17045            app.instrumentationResultClass = className;
17046            Binder.restoreCallingIdentity(origId);
17047        }
17048
17049        return true;
17050    }
17051
17052    /**
17053     * Report errors that occur while attempting to start Instrumentation.  Always writes the
17054     * error to the logs, but if somebody is watching, send the report there too.  This enables
17055     * the "am" command to report errors with more information.
17056     *
17057     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17058     * @param cn The component name of the instrumentation.
17059     * @param report The error report.
17060     */
17061    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
17062            ComponentName cn, String report) {
17063        Slog.w(TAG, report);
17064        try {
17065            if (watcher != null) {
17066                Bundle results = new Bundle();
17067                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17068                results.putString("Error", report);
17069                watcher.instrumentationStatus(cn, -1, results);
17070            }
17071        } catch (RemoteException e) {
17072            Slog.w(TAG, e);
17073        }
17074    }
17075
17076    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17077        if (app.instrumentationWatcher != null) {
17078            try {
17079                // NOTE:  IInstrumentationWatcher *must* be oneway here
17080                app.instrumentationWatcher.instrumentationFinished(
17081                    app.instrumentationClass,
17082                    resultCode,
17083                    results);
17084            } catch (RemoteException e) {
17085            }
17086        }
17087        if (app.instrumentationUiAutomationConnection != null) {
17088            try {
17089                app.instrumentationUiAutomationConnection.shutdown();
17090            } catch (RemoteException re) {
17091                /* ignore */
17092            }
17093            // Only a UiAutomation can set this flag and now that
17094            // it is finished we make sure it is reset to its default.
17095            mUserIsMonkey = false;
17096        }
17097        app.instrumentationWatcher = null;
17098        app.instrumentationUiAutomationConnection = null;
17099        app.instrumentationClass = null;
17100        app.instrumentationInfo = null;
17101        app.instrumentationProfileFile = null;
17102        app.instrumentationArguments = null;
17103
17104        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17105                "finished inst");
17106    }
17107
17108    public void finishInstrumentation(IApplicationThread target,
17109            int resultCode, Bundle results) {
17110        int userId = UserHandle.getCallingUserId();
17111        // Refuse possible leaked file descriptors
17112        if (results != null && results.hasFileDescriptors()) {
17113            throw new IllegalArgumentException("File descriptors passed in Intent");
17114        }
17115
17116        synchronized(this) {
17117            ProcessRecord app = getRecordForAppLocked(target);
17118            if (app == null) {
17119                Slog.w(TAG, "finishInstrumentation: no app for " + target);
17120                return;
17121            }
17122            final long origId = Binder.clearCallingIdentity();
17123            finishInstrumentationLocked(app, resultCode, results);
17124            Binder.restoreCallingIdentity(origId);
17125        }
17126    }
17127
17128    // =========================================================
17129    // CONFIGURATION
17130    // =========================================================
17131
17132    public ConfigurationInfo getDeviceConfigurationInfo() {
17133        ConfigurationInfo config = new ConfigurationInfo();
17134        synchronized (this) {
17135            config.reqTouchScreen = mConfiguration.touchscreen;
17136            config.reqKeyboardType = mConfiguration.keyboard;
17137            config.reqNavigation = mConfiguration.navigation;
17138            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17139                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17140                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17141            }
17142            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17143                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17144                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17145            }
17146            config.reqGlEsVersion = GL_ES_VERSION;
17147        }
17148        return config;
17149    }
17150
17151    ActivityStack getFocusedStack() {
17152        return mStackSupervisor.getFocusedStack();
17153    }
17154
17155    @Override
17156    public int getFocusedStackId() throws RemoteException {
17157        ActivityStack focusedStack = getFocusedStack();
17158        if (focusedStack != null) {
17159            return focusedStack.getStackId();
17160        }
17161        return -1;
17162    }
17163
17164    public Configuration getConfiguration() {
17165        Configuration ci;
17166        synchronized(this) {
17167            ci = new Configuration(mConfiguration);
17168            ci.userSetLocale = false;
17169        }
17170        return ci;
17171    }
17172
17173    public void updatePersistentConfiguration(Configuration values) {
17174        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17175                "updateConfiguration()");
17176        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
17177                "updateConfiguration()");
17178        if (values == null) {
17179            throw new NullPointerException("Configuration must not be null");
17180        }
17181
17182        synchronized(this) {
17183            final long origId = Binder.clearCallingIdentity();
17184            updateConfigurationLocked(values, null, true, false);
17185            Binder.restoreCallingIdentity(origId);
17186        }
17187    }
17188
17189    public void updateConfiguration(Configuration values) {
17190        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17191                "updateConfiguration()");
17192
17193        synchronized(this) {
17194            if (values == null && mWindowManager != null) {
17195                // sentinel: fetch the current configuration from the window manager
17196                values = mWindowManager.computeNewConfiguration();
17197            }
17198
17199            if (mWindowManager != null) {
17200                mProcessList.applyDisplaySize(mWindowManager);
17201            }
17202
17203            final long origId = Binder.clearCallingIdentity();
17204            if (values != null) {
17205                Settings.System.clearConfiguration(values);
17206            }
17207            updateConfigurationLocked(values, null, false, false);
17208            Binder.restoreCallingIdentity(origId);
17209        }
17210    }
17211
17212    /**
17213     * Do either or both things: (1) change the current configuration, and (2)
17214     * make sure the given activity is running with the (now) current
17215     * configuration.  Returns true if the activity has been left running, or
17216     * false if <var>starting</var> is being destroyed to match the new
17217     * configuration.
17218     * @param persistent TODO
17219     */
17220    boolean updateConfigurationLocked(Configuration values,
17221            ActivityRecord starting, boolean persistent, boolean initLocale) {
17222        int changes = 0;
17223
17224        if (values != null) {
17225            Configuration newConfig = new Configuration(mConfiguration);
17226            changes = newConfig.updateFrom(values);
17227            if (changes != 0) {
17228                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
17229                        "Updating configuration to: " + values);
17230
17231                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
17232
17233                if (!initLocale && values.locale != null && values.userSetLocale) {
17234                    final String languageTag = values.locale.toLanguageTag();
17235                    SystemProperties.set("persist.sys.locale", languageTag);
17236                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
17237                            values.locale));
17238                }
17239
17240                mConfigurationSeq++;
17241                if (mConfigurationSeq <= 0) {
17242                    mConfigurationSeq = 1;
17243                }
17244                newConfig.seq = mConfigurationSeq;
17245                mConfiguration = newConfig;
17246                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
17247                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
17248                //mUsageStatsService.noteStartConfig(newConfig);
17249
17250                final Configuration configCopy = new Configuration(mConfiguration);
17251
17252                // TODO: If our config changes, should we auto dismiss any currently
17253                // showing dialogs?
17254                mShowDialogs = shouldShowDialogs(newConfig);
17255
17256                AttributeCache ac = AttributeCache.instance();
17257                if (ac != null) {
17258                    ac.updateConfiguration(configCopy);
17259                }
17260
17261                // Make sure all resources in our process are updated
17262                // right now, so that anyone who is going to retrieve
17263                // resource values after we return will be sure to get
17264                // the new ones.  This is especially important during
17265                // boot, where the first config change needs to guarantee
17266                // all resources have that config before following boot
17267                // code is executed.
17268                mSystemThread.applyConfigurationToResources(configCopy);
17269
17270                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
17271                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
17272                    msg.obj = new Configuration(configCopy);
17273                    mHandler.sendMessage(msg);
17274                }
17275
17276                for (int i=mLruProcesses.size()-1; i>=0; i--) {
17277                    ProcessRecord app = mLruProcesses.get(i);
17278                    try {
17279                        if (app.thread != null) {
17280                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
17281                                    + app.processName + " new config " + mConfiguration);
17282                            app.thread.scheduleConfigurationChanged(configCopy);
17283                        }
17284                    } catch (Exception e) {
17285                    }
17286                }
17287                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
17288                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17289                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
17290                        | Intent.FLAG_RECEIVER_FOREGROUND);
17291                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
17292                        null, AppOpsManager.OP_NONE, null, false, false,
17293                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17294                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
17295                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
17296                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17297                    if (!mProcessesReady) {
17298                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17299                    }
17300                    broadcastIntentLocked(null, null, intent,
17301                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17302                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17303                }
17304            }
17305        }
17306
17307        boolean kept = true;
17308        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
17309        // mainStack is null during startup.
17310        if (mainStack != null) {
17311            if (changes != 0 && starting == null) {
17312                // If the configuration changed, and the caller is not already
17313                // in the process of starting an activity, then find the top
17314                // activity to check if its configuration needs to change.
17315                starting = mainStack.topRunningActivityLocked(null);
17316            }
17317
17318            if (starting != null) {
17319                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
17320                // And we need to make sure at this point that all other activities
17321                // are made visible with the correct configuration.
17322                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
17323            }
17324        }
17325
17326        if (values != null && mWindowManager != null) {
17327            mWindowManager.setNewConfiguration(mConfiguration);
17328        }
17329
17330        return kept;
17331    }
17332
17333    /**
17334     * Decide based on the configuration whether we should shouw the ANR,
17335     * crash, etc dialogs.  The idea is that if there is no affordnace to
17336     * press the on-screen buttons, we shouldn't show the dialog.
17337     *
17338     * A thought: SystemUI might also want to get told about this, the Power
17339     * dialog / global actions also might want different behaviors.
17340     */
17341    private static final boolean shouldShowDialogs(Configuration config) {
17342        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
17343                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
17344                && config.navigation == Configuration.NAVIGATION_NONAV);
17345    }
17346
17347    @Override
17348    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
17349        synchronized (this) {
17350            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
17351            if (srec != null) {
17352                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
17353            }
17354        }
17355        return false;
17356    }
17357
17358    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
17359            Intent resultData) {
17360
17361        synchronized (this) {
17362            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
17363            if (r != null) {
17364                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
17365            }
17366            return false;
17367        }
17368    }
17369
17370    public int getLaunchedFromUid(IBinder activityToken) {
17371        ActivityRecord srec;
17372        synchronized (this) {
17373            srec = ActivityRecord.forTokenLocked(activityToken);
17374        }
17375        if (srec == null) {
17376            return -1;
17377        }
17378        return srec.launchedFromUid;
17379    }
17380
17381    public String getLaunchedFromPackage(IBinder activityToken) {
17382        ActivityRecord srec;
17383        synchronized (this) {
17384            srec = ActivityRecord.forTokenLocked(activityToken);
17385        }
17386        if (srec == null) {
17387            return null;
17388        }
17389        return srec.launchedFromPackage;
17390    }
17391
17392    // =========================================================
17393    // LIFETIME MANAGEMENT
17394    // =========================================================
17395
17396    // Returns which broadcast queue the app is the current [or imminent] receiver
17397    // on, or 'null' if the app is not an active broadcast recipient.
17398    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
17399        BroadcastRecord r = app.curReceiver;
17400        if (r != null) {
17401            return r.queue;
17402        }
17403
17404        // It's not the current receiver, but it might be starting up to become one
17405        synchronized (this) {
17406            for (BroadcastQueue queue : mBroadcastQueues) {
17407                r = queue.mPendingBroadcast;
17408                if (r != null && r.curApp == app) {
17409                    // found it; report which queue it's in
17410                    return queue;
17411                }
17412            }
17413        }
17414
17415        return null;
17416    }
17417
17418    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17419            ComponentName targetComponent, String targetProcess) {
17420        if (!mTrackingAssociations) {
17421            return null;
17422        }
17423        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17424                = mAssociations.get(targetUid);
17425        if (components == null) {
17426            components = new ArrayMap<>();
17427            mAssociations.put(targetUid, components);
17428        }
17429        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17430        if (sourceUids == null) {
17431            sourceUids = new SparseArray<>();
17432            components.put(targetComponent, sourceUids);
17433        }
17434        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17435        if (sourceProcesses == null) {
17436            sourceProcesses = new ArrayMap<>();
17437            sourceUids.put(sourceUid, sourceProcesses);
17438        }
17439        Association ass = sourceProcesses.get(sourceProcess);
17440        if (ass == null) {
17441            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
17442                    targetProcess);
17443            sourceProcesses.put(sourceProcess, ass);
17444        }
17445        ass.mCount++;
17446        ass.mNesting++;
17447        if (ass.mNesting == 1) {
17448            ass.mStartTime = SystemClock.uptimeMillis();
17449        }
17450        return ass;
17451    }
17452
17453    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17454            ComponentName targetComponent) {
17455        if (!mTrackingAssociations) {
17456            return;
17457        }
17458        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17459                = mAssociations.get(targetUid);
17460        if (components == null) {
17461            return;
17462        }
17463        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17464        if (sourceUids == null) {
17465            return;
17466        }
17467        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17468        if (sourceProcesses == null) {
17469            return;
17470        }
17471        Association ass = sourceProcesses.get(sourceProcess);
17472        if (ass == null || ass.mNesting <= 0) {
17473            return;
17474        }
17475        ass.mNesting--;
17476        if (ass.mNesting == 0) {
17477            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
17478        }
17479    }
17480
17481    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
17482            boolean doingAll, long now) {
17483        if (mAdjSeq == app.adjSeq) {
17484            // This adjustment has already been computed.
17485            return app.curRawAdj;
17486        }
17487
17488        if (app.thread == null) {
17489            app.adjSeq = mAdjSeq;
17490            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17491            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17492            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
17493        }
17494
17495        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
17496        app.adjSource = null;
17497        app.adjTarget = null;
17498        app.empty = false;
17499        app.cached = false;
17500
17501        final int activitiesSize = app.activities.size();
17502
17503        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17504            // The max adjustment doesn't allow this app to be anything
17505            // below foreground, so it is not worth doing work for it.
17506            app.adjType = "fixed";
17507            app.adjSeq = mAdjSeq;
17508            app.curRawAdj = app.maxAdj;
17509            app.foregroundActivities = false;
17510            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
17511            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
17512            // System processes can do UI, and when they do we want to have
17513            // them trim their memory after the user leaves the UI.  To
17514            // facilitate this, here we need to determine whether or not it
17515            // is currently showing UI.
17516            app.systemNoUi = true;
17517            if (app == TOP_APP) {
17518                app.systemNoUi = false;
17519            } else if (activitiesSize > 0) {
17520                for (int j = 0; j < activitiesSize; j++) {
17521                    final ActivityRecord r = app.activities.get(j);
17522                    if (r.visible) {
17523                        app.systemNoUi = false;
17524                    }
17525                }
17526            }
17527            if (!app.systemNoUi) {
17528                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
17529            }
17530            return (app.curAdj=app.maxAdj);
17531        }
17532
17533        app.systemNoUi = false;
17534
17535        final int PROCESS_STATE_TOP = mTopProcessState;
17536
17537        // Determine the importance of the process, starting with most
17538        // important to least, and assign an appropriate OOM adjustment.
17539        int adj;
17540        int schedGroup;
17541        int procState;
17542        boolean foregroundActivities = false;
17543        BroadcastQueue queue;
17544        if (app == TOP_APP) {
17545            // The last app on the list is the foreground app.
17546            adj = ProcessList.FOREGROUND_APP_ADJ;
17547            schedGroup = Process.THREAD_GROUP_DEFAULT;
17548            app.adjType = "top-activity";
17549            foregroundActivities = true;
17550            procState = PROCESS_STATE_TOP;
17551        } else if (app.instrumentationClass != null) {
17552            // Don't want to kill running instrumentation.
17553            adj = ProcessList.FOREGROUND_APP_ADJ;
17554            schedGroup = Process.THREAD_GROUP_DEFAULT;
17555            app.adjType = "instrumentation";
17556            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17557        } else if ((queue = isReceivingBroadcast(app)) != null) {
17558            // An app that is currently receiving a broadcast also
17559            // counts as being in the foreground for OOM killer purposes.
17560            // It's placed in a sched group based on the nature of the
17561            // broadcast as reflected by which queue it's active in.
17562            adj = ProcessList.FOREGROUND_APP_ADJ;
17563            schedGroup = (queue == mFgBroadcastQueue)
17564                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17565            app.adjType = "broadcast";
17566            procState = ActivityManager.PROCESS_STATE_RECEIVER;
17567        } else if (app.executingServices.size() > 0) {
17568            // An app that is currently executing a service callback also
17569            // counts as being in the foreground.
17570            adj = ProcessList.FOREGROUND_APP_ADJ;
17571            schedGroup = app.execServicesFg ?
17572                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17573            app.adjType = "exec-service";
17574            procState = ActivityManager.PROCESS_STATE_SERVICE;
17575            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
17576        } else {
17577            // As far as we know the process is empty.  We may change our mind later.
17578            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17579            // At this point we don't actually know the adjustment.  Use the cached adj
17580            // value that the caller wants us to.
17581            adj = cachedAdj;
17582            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17583            app.cached = true;
17584            app.empty = true;
17585            app.adjType = "cch-empty";
17586        }
17587
17588        // Examine all activities if not already foreground.
17589        if (!foregroundActivities && activitiesSize > 0) {
17590            for (int j = 0; j < activitiesSize; j++) {
17591                final ActivityRecord r = app.activities.get(j);
17592                if (r.app != app) {
17593                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
17594                            + app + "?!? Using " + r.app + " instead.");
17595                    continue;
17596                }
17597                if (r.visible) {
17598                    // App has a visible activity; only upgrade adjustment.
17599                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17600                        adj = ProcessList.VISIBLE_APP_ADJ;
17601                        app.adjType = "visible";
17602                    }
17603                    if (procState > PROCESS_STATE_TOP) {
17604                        procState = PROCESS_STATE_TOP;
17605                    }
17606                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17607                    app.cached = false;
17608                    app.empty = false;
17609                    foregroundActivities = true;
17610                    break;
17611                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
17612                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17613                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17614                        app.adjType = "pausing";
17615                    }
17616                    if (procState > PROCESS_STATE_TOP) {
17617                        procState = PROCESS_STATE_TOP;
17618                    }
17619                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17620                    app.cached = false;
17621                    app.empty = false;
17622                    foregroundActivities = true;
17623                } else if (r.state == ActivityState.STOPPING) {
17624                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17625                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17626                        app.adjType = "stopping";
17627                    }
17628                    // For the process state, we will at this point consider the
17629                    // process to be cached.  It will be cached either as an activity
17630                    // or empty depending on whether the activity is finishing.  We do
17631                    // this so that we can treat the process as cached for purposes of
17632                    // memory trimming (determing current memory level, trim command to
17633                    // send to process) since there can be an arbitrary number of stopping
17634                    // processes and they should soon all go into the cached state.
17635                    if (!r.finishing) {
17636                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17637                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17638                        }
17639                    }
17640                    app.cached = false;
17641                    app.empty = false;
17642                    foregroundActivities = true;
17643                } else {
17644                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17645                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17646                        app.adjType = "cch-act";
17647                    }
17648                }
17649            }
17650        }
17651
17652        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17653            if (app.foregroundServices) {
17654                // The user is aware of this app, so make it visible.
17655                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17656                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17657                app.cached = false;
17658                app.adjType = "fg-service";
17659                schedGroup = Process.THREAD_GROUP_DEFAULT;
17660            } else if (app.forcingToForeground != null) {
17661                // The user is aware of this app, so make it visible.
17662                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17663                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17664                app.cached = false;
17665                app.adjType = "force-fg";
17666                app.adjSource = app.forcingToForeground;
17667                schedGroup = Process.THREAD_GROUP_DEFAULT;
17668            }
17669        }
17670
17671        if (app == mHeavyWeightProcess) {
17672            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
17673                // We don't want to kill the current heavy-weight process.
17674                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
17675                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17676                app.cached = false;
17677                app.adjType = "heavy";
17678            }
17679            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17680                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
17681            }
17682        }
17683
17684        if (app == mHomeProcess) {
17685            if (adj > ProcessList.HOME_APP_ADJ) {
17686                // This process is hosting what we currently consider to be the
17687                // home app, so we don't want to let it go into the background.
17688                adj = ProcessList.HOME_APP_ADJ;
17689                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17690                app.cached = false;
17691                app.adjType = "home";
17692            }
17693            if (procState > ActivityManager.PROCESS_STATE_HOME) {
17694                procState = ActivityManager.PROCESS_STATE_HOME;
17695            }
17696        }
17697
17698        if (app == mPreviousProcess && app.activities.size() > 0) {
17699            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
17700                // This was the previous process that showed UI to the user.
17701                // We want to try to keep it around more aggressively, to give
17702                // a good experience around switching between two apps.
17703                adj = ProcessList.PREVIOUS_APP_ADJ;
17704                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17705                app.cached = false;
17706                app.adjType = "previous";
17707            }
17708            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17709                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17710            }
17711        }
17712
17713        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
17714                + " reason=" + app.adjType);
17715
17716        // By default, we use the computed adjustment.  It may be changed if
17717        // there are applications dependent on our services or providers, but
17718        // this gives us a baseline and makes sure we don't get into an
17719        // infinite recursion.
17720        app.adjSeq = mAdjSeq;
17721        app.curRawAdj = adj;
17722        app.hasStartedServices = false;
17723
17724        if (mBackupTarget != null && app == mBackupTarget.app) {
17725            // If possible we want to avoid killing apps while they're being backed up
17726            if (adj > ProcessList.BACKUP_APP_ADJ) {
17727                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
17728                adj = ProcessList.BACKUP_APP_ADJ;
17729                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17730                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17731                }
17732                app.adjType = "backup";
17733                app.cached = false;
17734            }
17735            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
17736                procState = ActivityManager.PROCESS_STATE_BACKUP;
17737            }
17738        }
17739
17740        boolean mayBeTop = false;
17741
17742        for (int is = app.services.size()-1;
17743                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17744                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17745                        || procState > ActivityManager.PROCESS_STATE_TOP);
17746                is--) {
17747            ServiceRecord s = app.services.valueAt(is);
17748            if (s.startRequested) {
17749                app.hasStartedServices = true;
17750                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
17751                    procState = ActivityManager.PROCESS_STATE_SERVICE;
17752                }
17753                if (app.hasShownUi && app != mHomeProcess) {
17754                    // If this process has shown some UI, let it immediately
17755                    // go to the LRU list because it may be pretty heavy with
17756                    // UI stuff.  We'll tag it with a label just to help
17757                    // debug and understand what is going on.
17758                    if (adj > ProcessList.SERVICE_ADJ) {
17759                        app.adjType = "cch-started-ui-services";
17760                    }
17761                } else {
17762                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17763                        // This service has seen some activity within
17764                        // recent memory, so we will keep its process ahead
17765                        // of the background processes.
17766                        if (adj > ProcessList.SERVICE_ADJ) {
17767                            adj = ProcessList.SERVICE_ADJ;
17768                            app.adjType = "started-services";
17769                            app.cached = false;
17770                        }
17771                    }
17772                    // If we have let the service slide into the background
17773                    // state, still have some text describing what it is doing
17774                    // even though the service no longer has an impact.
17775                    if (adj > ProcessList.SERVICE_ADJ) {
17776                        app.adjType = "cch-started-services";
17777                    }
17778                }
17779            }
17780            for (int conni = s.connections.size()-1;
17781                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17782                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17783                            || procState > ActivityManager.PROCESS_STATE_TOP);
17784                    conni--) {
17785                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17786                for (int i = 0;
17787                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17788                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17789                                || procState > ActivityManager.PROCESS_STATE_TOP);
17790                        i++) {
17791                    // XXX should compute this based on the max of
17792                    // all connected clients.
17793                    ConnectionRecord cr = clist.get(i);
17794                    if (cr.binding.client == app) {
17795                        // Binding to ourself is not interesting.
17796                        continue;
17797                    }
17798                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17799                        ProcessRecord client = cr.binding.client;
17800                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
17801                                TOP_APP, doingAll, now);
17802                        int clientProcState = client.curProcState;
17803                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17804                            // If the other app is cached for any reason, for purposes here
17805                            // we are going to consider it empty.  The specific cached state
17806                            // doesn't propagate except under certain conditions.
17807                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17808                        }
17809                        String adjType = null;
17810                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17811                            // Not doing bind OOM management, so treat
17812                            // this guy more like a started service.
17813                            if (app.hasShownUi && app != mHomeProcess) {
17814                                // If this process has shown some UI, let it immediately
17815                                // go to the LRU list because it may be pretty heavy with
17816                                // UI stuff.  We'll tag it with a label just to help
17817                                // debug and understand what is going on.
17818                                if (adj > clientAdj) {
17819                                    adjType = "cch-bound-ui-services";
17820                                }
17821                                app.cached = false;
17822                                clientAdj = adj;
17823                                clientProcState = procState;
17824                            } else {
17825                                if (now >= (s.lastActivity
17826                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17827                                    // This service has not seen activity within
17828                                    // recent memory, so allow it to drop to the
17829                                    // LRU list if there is no other reason to keep
17830                                    // it around.  We'll also tag it with a label just
17831                                    // to help debug and undertand what is going on.
17832                                    if (adj > clientAdj) {
17833                                        adjType = "cch-bound-services";
17834                                    }
17835                                    clientAdj = adj;
17836                                }
17837                            }
17838                        }
17839                        if (adj > clientAdj) {
17840                            // If this process has recently shown UI, and
17841                            // the process that is binding to it is less
17842                            // important than being visible, then we don't
17843                            // care about the binding as much as we care
17844                            // about letting this process get into the LRU
17845                            // list to be killed and restarted if needed for
17846                            // memory.
17847                            if (app.hasShownUi && app != mHomeProcess
17848                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17849                                adjType = "cch-bound-ui-services";
17850                            } else {
17851                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17852                                        |Context.BIND_IMPORTANT)) != 0) {
17853                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17854                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17855                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17856                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17857                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17858                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17859                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17860                                    adj = clientAdj;
17861                                } else {
17862                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17863                                        adj = ProcessList.VISIBLE_APP_ADJ;
17864                                    }
17865                                }
17866                                if (!client.cached) {
17867                                    app.cached = false;
17868                                }
17869                                adjType = "service";
17870                            }
17871                        }
17872                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17873                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17874                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17875                            }
17876                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17877                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17878                                    // Special handling of clients who are in the top state.
17879                                    // We *may* want to consider this process to be in the
17880                                    // top state as well, but only if there is not another
17881                                    // reason for it to be running.  Being on the top is a
17882                                    // special state, meaning you are specifically running
17883                                    // for the current top app.  If the process is already
17884                                    // running in the background for some other reason, it
17885                                    // is more important to continue considering it to be
17886                                    // in the background state.
17887                                    mayBeTop = true;
17888                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17889                                } else {
17890                                    // Special handling for above-top states (persistent
17891                                    // processes).  These should not bring the current process
17892                                    // into the top state, since they are not on top.  Instead
17893                                    // give them the best state after that.
17894                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
17895                                        clientProcState =
17896                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
17897                                    } else if (mWakefulness
17898                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
17899                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
17900                                                    != 0) {
17901                                        clientProcState =
17902                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
17903                                    } else {
17904                                        clientProcState =
17905                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17906                                    }
17907                                }
17908                            }
17909                        } else {
17910                            if (clientProcState <
17911                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17912                                clientProcState =
17913                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17914                            }
17915                        }
17916                        if (procState > clientProcState) {
17917                            procState = clientProcState;
17918                        }
17919                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17920                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17921                            app.pendingUiClean = true;
17922                        }
17923                        if (adjType != null) {
17924                            app.adjType = adjType;
17925                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17926                                    .REASON_SERVICE_IN_USE;
17927                            app.adjSource = cr.binding.client;
17928                            app.adjSourceProcState = clientProcState;
17929                            app.adjTarget = s.name;
17930                        }
17931                    }
17932                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17933                        app.treatLikeActivity = true;
17934                    }
17935                    final ActivityRecord a = cr.activity;
17936                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17937                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17938                                (a.visible || a.state == ActivityState.RESUMED
17939                                 || a.state == ActivityState.PAUSING)) {
17940                            adj = ProcessList.FOREGROUND_APP_ADJ;
17941                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17942                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17943                            }
17944                            app.cached = false;
17945                            app.adjType = "service";
17946                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17947                                    .REASON_SERVICE_IN_USE;
17948                            app.adjSource = a;
17949                            app.adjSourceProcState = procState;
17950                            app.adjTarget = s.name;
17951                        }
17952                    }
17953                }
17954            }
17955        }
17956
17957        for (int provi = app.pubProviders.size()-1;
17958                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17959                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17960                        || procState > ActivityManager.PROCESS_STATE_TOP);
17961                provi--) {
17962            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17963            for (int i = cpr.connections.size()-1;
17964                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17965                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17966                            || procState > ActivityManager.PROCESS_STATE_TOP);
17967                    i--) {
17968                ContentProviderConnection conn = cpr.connections.get(i);
17969                ProcessRecord client = conn.client;
17970                if (client == app) {
17971                    // Being our own client is not interesting.
17972                    continue;
17973                }
17974                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17975                int clientProcState = client.curProcState;
17976                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17977                    // If the other app is cached for any reason, for purposes here
17978                    // we are going to consider it empty.
17979                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17980                }
17981                if (adj > clientAdj) {
17982                    if (app.hasShownUi && app != mHomeProcess
17983                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17984                        app.adjType = "cch-ui-provider";
17985                    } else {
17986                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17987                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17988                        app.adjType = "provider";
17989                    }
17990                    app.cached &= client.cached;
17991                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17992                            .REASON_PROVIDER_IN_USE;
17993                    app.adjSource = client;
17994                    app.adjSourceProcState = clientProcState;
17995                    app.adjTarget = cpr.name;
17996                }
17997                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17998                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17999                        // Special handling of clients who are in the top state.
18000                        // We *may* want to consider this process to be in the
18001                        // top state as well, but only if there is not another
18002                        // reason for it to be running.  Being on the top is a
18003                        // special state, meaning you are specifically running
18004                        // for the current top app.  If the process is already
18005                        // running in the background for some other reason, it
18006                        // is more important to continue considering it to be
18007                        // in the background state.
18008                        mayBeTop = true;
18009                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18010                    } else {
18011                        // Special handling for above-top states (persistent
18012                        // processes).  These should not bring the current process
18013                        // into the top state, since they are not on top.  Instead
18014                        // give them the best state after that.
18015                        clientProcState =
18016                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18017                    }
18018                }
18019                if (procState > clientProcState) {
18020                    procState = clientProcState;
18021                }
18022                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18023                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18024                }
18025            }
18026            // If the provider has external (non-framework) process
18027            // dependencies, ensure that its adjustment is at least
18028            // FOREGROUND_APP_ADJ.
18029            if (cpr.hasExternalProcessHandles()) {
18030                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
18031                    adj = ProcessList.FOREGROUND_APP_ADJ;
18032                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18033                    app.cached = false;
18034                    app.adjType = "provider";
18035                    app.adjTarget = cpr.name;
18036                }
18037                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18038                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18039                }
18040            }
18041        }
18042
18043        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
18044            // A client of one of our services or providers is in the top state.  We
18045            // *may* want to be in the top state, but not if we are already running in
18046            // the background for some other reason.  For the decision here, we are going
18047            // to pick out a few specific states that we want to remain in when a client
18048            // is top (states that tend to be longer-term) and otherwise allow it to go
18049            // to the top state.
18050            switch (procState) {
18051                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
18052                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
18053                case ActivityManager.PROCESS_STATE_SERVICE:
18054                    // These all are longer-term states, so pull them up to the top
18055                    // of the background states, but not all the way to the top state.
18056                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18057                    break;
18058                default:
18059                    // Otherwise, top is a better choice, so take it.
18060                    procState = ActivityManager.PROCESS_STATE_TOP;
18061                    break;
18062            }
18063        }
18064
18065        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
18066            if (app.hasClientActivities) {
18067                // This is a cached process, but with client activities.  Mark it so.
18068                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
18069                app.adjType = "cch-client-act";
18070            } else if (app.treatLikeActivity) {
18071                // This is a cached process, but somebody wants us to treat it like it has
18072                // an activity, okay!
18073                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18074                app.adjType = "cch-as-act";
18075            }
18076        }
18077
18078        if (adj == ProcessList.SERVICE_ADJ) {
18079            if (doingAll) {
18080                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
18081                mNewNumServiceProcs++;
18082                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
18083                if (!app.serviceb) {
18084                    // This service isn't far enough down on the LRU list to
18085                    // normally be a B service, but if we are low on RAM and it
18086                    // is large we want to force it down since we would prefer to
18087                    // keep launcher over it.
18088                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
18089                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
18090                        app.serviceHighRam = true;
18091                        app.serviceb = true;
18092                        //Slog.i(TAG, "ADJ " + app + " high ram!");
18093                    } else {
18094                        mNewNumAServiceProcs++;
18095                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
18096                    }
18097                } else {
18098                    app.serviceHighRam = false;
18099                }
18100            }
18101            if (app.serviceb) {
18102                adj = ProcessList.SERVICE_B_ADJ;
18103            }
18104        }
18105
18106        app.curRawAdj = adj;
18107
18108        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
18109        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
18110        if (adj > app.maxAdj) {
18111            adj = app.maxAdj;
18112            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
18113                schedGroup = Process.THREAD_GROUP_DEFAULT;
18114            }
18115        }
18116
18117        // Do final modification to adj.  Everything we do between here and applying
18118        // the final setAdj must be done in this function, because we will also use
18119        // it when computing the final cached adj later.  Note that we don't need to
18120        // worry about this for max adj above, since max adj will always be used to
18121        // keep it out of the cached vaues.
18122        app.curAdj = app.modifyRawOomAdj(adj);
18123        app.curSchedGroup = schedGroup;
18124        app.curProcState = procState;
18125        app.foregroundActivities = foregroundActivities;
18126
18127        return app.curRawAdj;
18128    }
18129
18130    /**
18131     * Record new PSS sample for a process.
18132     */
18133    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long now) {
18134        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024);
18135        proc.lastPssTime = now;
18136        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
18137        if (DEBUG_PSS) Slog.d(TAG_PSS,
18138                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
18139                + " state=" + ProcessList.makeProcStateString(procState));
18140        if (proc.initialIdlePss == 0) {
18141            proc.initialIdlePss = pss;
18142        }
18143        proc.lastPss = pss;
18144        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
18145            proc.lastCachedPss = pss;
18146        }
18147
18148        final SparseArray<Pair<Long, String>> watchUids
18149                = mMemWatchProcesses.getMap().get(proc.processName);
18150        Long check = null;
18151        if (watchUids != null) {
18152            Pair<Long, String> val = watchUids.get(proc.uid);
18153            if (val == null) {
18154                val = watchUids.get(0);
18155            }
18156            if (val != null) {
18157                check = val.first;
18158            }
18159        }
18160        if (check != null) {
18161            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
18162                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18163                if (!isDebuggable) {
18164                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
18165                        isDebuggable = true;
18166                    }
18167                }
18168                if (isDebuggable) {
18169                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
18170                    final ProcessRecord myProc = proc;
18171                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
18172                    mMemWatchDumpProcName = proc.processName;
18173                    mMemWatchDumpFile = heapdumpFile.toString();
18174                    mMemWatchDumpPid = proc.pid;
18175                    mMemWatchDumpUid = proc.uid;
18176                    BackgroundThread.getHandler().post(new Runnable() {
18177                        @Override
18178                        public void run() {
18179                            revokeUriPermission(ActivityThread.currentActivityThread()
18180                                            .getApplicationThread(),
18181                                    DumpHeapActivity.JAVA_URI,
18182                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
18183                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
18184                                    UserHandle.myUserId());
18185                            ParcelFileDescriptor fd = null;
18186                            try {
18187                                heapdumpFile.delete();
18188                                fd = ParcelFileDescriptor.open(heapdumpFile,
18189                                        ParcelFileDescriptor.MODE_CREATE |
18190                                                ParcelFileDescriptor.MODE_TRUNCATE |
18191                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
18192                                                ParcelFileDescriptor.MODE_APPEND);
18193                                IApplicationThread thread = myProc.thread;
18194                                if (thread != null) {
18195                                    try {
18196                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
18197                                                "Requesting dump heap from "
18198                                                + myProc + " to " + heapdumpFile);
18199                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
18200                                    } catch (RemoteException e) {
18201                                    }
18202                                }
18203                            } catch (FileNotFoundException e) {
18204                                e.printStackTrace();
18205                            } finally {
18206                                if (fd != null) {
18207                                    try {
18208                                        fd.close();
18209                                    } catch (IOException e) {
18210                                    }
18211                                }
18212                            }
18213                        }
18214                    });
18215                } else {
18216                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
18217                            + ", but debugging not enabled");
18218                }
18219            }
18220        }
18221    }
18222
18223    /**
18224     * Schedule PSS collection of a process.
18225     */
18226    void requestPssLocked(ProcessRecord proc, int procState) {
18227        if (mPendingPssProcesses.contains(proc)) {
18228            return;
18229        }
18230        if (mPendingPssProcesses.size() == 0) {
18231            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18232        }
18233        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
18234        proc.pssProcState = procState;
18235        mPendingPssProcesses.add(proc);
18236    }
18237
18238    /**
18239     * Schedule PSS collection of all processes.
18240     */
18241    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
18242        if (!always) {
18243            if (now < (mLastFullPssTime +
18244                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
18245                return;
18246            }
18247        }
18248        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
18249        mLastFullPssTime = now;
18250        mFullPssPending = true;
18251        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
18252        mPendingPssProcesses.clear();
18253        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18254            ProcessRecord app = mLruProcesses.get(i);
18255            if (app.thread == null
18256                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
18257                continue;
18258            }
18259            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
18260                app.pssProcState = app.setProcState;
18261                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18262                        mTestPssMode, isSleeping(), now);
18263                mPendingPssProcesses.add(app);
18264            }
18265        }
18266        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18267    }
18268
18269    public void setTestPssMode(boolean enabled) {
18270        synchronized (this) {
18271            mTestPssMode = enabled;
18272            if (enabled) {
18273                // Whenever we enable the mode, we want to take a snapshot all of current
18274                // process mem use.
18275                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
18276            }
18277        }
18278    }
18279
18280    /**
18281     * Ask a given process to GC right now.
18282     */
18283    final void performAppGcLocked(ProcessRecord app) {
18284        try {
18285            app.lastRequestedGc = SystemClock.uptimeMillis();
18286            if (app.thread != null) {
18287                if (app.reportLowMemory) {
18288                    app.reportLowMemory = false;
18289                    app.thread.scheduleLowMemory();
18290                } else {
18291                    app.thread.processInBackground();
18292                }
18293            }
18294        } catch (Exception e) {
18295            // whatever.
18296        }
18297    }
18298
18299    /**
18300     * Returns true if things are idle enough to perform GCs.
18301     */
18302    private final boolean canGcNowLocked() {
18303        boolean processingBroadcasts = false;
18304        for (BroadcastQueue q : mBroadcastQueues) {
18305            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
18306                processingBroadcasts = true;
18307            }
18308        }
18309        return !processingBroadcasts
18310                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
18311    }
18312
18313    /**
18314     * Perform GCs on all processes that are waiting for it, but only
18315     * if things are idle.
18316     */
18317    final void performAppGcsLocked() {
18318        final int N = mProcessesToGc.size();
18319        if (N <= 0) {
18320            return;
18321        }
18322        if (canGcNowLocked()) {
18323            while (mProcessesToGc.size() > 0) {
18324                ProcessRecord proc = mProcessesToGc.remove(0);
18325                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
18326                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
18327                            <= SystemClock.uptimeMillis()) {
18328                        // To avoid spamming the system, we will GC processes one
18329                        // at a time, waiting a few seconds between each.
18330                        performAppGcLocked(proc);
18331                        scheduleAppGcsLocked();
18332                        return;
18333                    } else {
18334                        // It hasn't been long enough since we last GCed this
18335                        // process...  put it in the list to wait for its time.
18336                        addProcessToGcListLocked(proc);
18337                        break;
18338                    }
18339                }
18340            }
18341
18342            scheduleAppGcsLocked();
18343        }
18344    }
18345
18346    /**
18347     * If all looks good, perform GCs on all processes waiting for them.
18348     */
18349    final void performAppGcsIfAppropriateLocked() {
18350        if (canGcNowLocked()) {
18351            performAppGcsLocked();
18352            return;
18353        }
18354        // Still not idle, wait some more.
18355        scheduleAppGcsLocked();
18356    }
18357
18358    /**
18359     * Schedule the execution of all pending app GCs.
18360     */
18361    final void scheduleAppGcsLocked() {
18362        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
18363
18364        if (mProcessesToGc.size() > 0) {
18365            // Schedule a GC for the time to the next process.
18366            ProcessRecord proc = mProcessesToGc.get(0);
18367            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
18368
18369            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
18370            long now = SystemClock.uptimeMillis();
18371            if (when < (now+GC_TIMEOUT)) {
18372                when = now + GC_TIMEOUT;
18373            }
18374            mHandler.sendMessageAtTime(msg, when);
18375        }
18376    }
18377
18378    /**
18379     * Add a process to the array of processes waiting to be GCed.  Keeps the
18380     * list in sorted order by the last GC time.  The process can't already be
18381     * on the list.
18382     */
18383    final void addProcessToGcListLocked(ProcessRecord proc) {
18384        boolean added = false;
18385        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
18386            if (mProcessesToGc.get(i).lastRequestedGc <
18387                    proc.lastRequestedGc) {
18388                added = true;
18389                mProcessesToGc.add(i+1, proc);
18390                break;
18391            }
18392        }
18393        if (!added) {
18394            mProcessesToGc.add(0, proc);
18395        }
18396    }
18397
18398    /**
18399     * Set up to ask a process to GC itself.  This will either do it
18400     * immediately, or put it on the list of processes to gc the next
18401     * time things are idle.
18402     */
18403    final void scheduleAppGcLocked(ProcessRecord app) {
18404        long now = SystemClock.uptimeMillis();
18405        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
18406            return;
18407        }
18408        if (!mProcessesToGc.contains(app)) {
18409            addProcessToGcListLocked(app);
18410            scheduleAppGcsLocked();
18411        }
18412    }
18413
18414    final void checkExcessivePowerUsageLocked(boolean doKills) {
18415        updateCpuStatsNow();
18416
18417        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18418        boolean doWakeKills = doKills;
18419        boolean doCpuKills = doKills;
18420        if (mLastPowerCheckRealtime == 0) {
18421            doWakeKills = false;
18422        }
18423        if (mLastPowerCheckUptime == 0) {
18424            doCpuKills = false;
18425        }
18426        if (stats.isScreenOn()) {
18427            doWakeKills = false;
18428        }
18429        final long curRealtime = SystemClock.elapsedRealtime();
18430        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
18431        final long curUptime = SystemClock.uptimeMillis();
18432        final long uptimeSince = curUptime - mLastPowerCheckUptime;
18433        mLastPowerCheckRealtime = curRealtime;
18434        mLastPowerCheckUptime = curUptime;
18435        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
18436            doWakeKills = false;
18437        }
18438        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
18439            doCpuKills = false;
18440        }
18441        int i = mLruProcesses.size();
18442        while (i > 0) {
18443            i--;
18444            ProcessRecord app = mLruProcesses.get(i);
18445            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18446                long wtime;
18447                synchronized (stats) {
18448                    wtime = stats.getProcessWakeTime(app.info.uid,
18449                            app.pid, curRealtime);
18450                }
18451                long wtimeUsed = wtime - app.lastWakeTime;
18452                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
18453                if (DEBUG_POWER) {
18454                    StringBuilder sb = new StringBuilder(128);
18455                    sb.append("Wake for ");
18456                    app.toShortString(sb);
18457                    sb.append(": over ");
18458                    TimeUtils.formatDuration(realtimeSince, sb);
18459                    sb.append(" used ");
18460                    TimeUtils.formatDuration(wtimeUsed, sb);
18461                    sb.append(" (");
18462                    sb.append((wtimeUsed*100)/realtimeSince);
18463                    sb.append("%)");
18464                    Slog.i(TAG_POWER, sb.toString());
18465                    sb.setLength(0);
18466                    sb.append("CPU for ");
18467                    app.toShortString(sb);
18468                    sb.append(": over ");
18469                    TimeUtils.formatDuration(uptimeSince, sb);
18470                    sb.append(" used ");
18471                    TimeUtils.formatDuration(cputimeUsed, sb);
18472                    sb.append(" (");
18473                    sb.append((cputimeUsed*100)/uptimeSince);
18474                    sb.append("%)");
18475                    Slog.i(TAG_POWER, sb.toString());
18476                }
18477                // If a process has held a wake lock for more
18478                // than 50% of the time during this period,
18479                // that sounds bad.  Kill!
18480                if (doWakeKills && realtimeSince > 0
18481                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
18482                    synchronized (stats) {
18483                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
18484                                realtimeSince, wtimeUsed);
18485                    }
18486                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
18487                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
18488                } else if (doCpuKills && uptimeSince > 0
18489                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
18490                    synchronized (stats) {
18491                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
18492                                uptimeSince, cputimeUsed);
18493                    }
18494                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
18495                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
18496                } else {
18497                    app.lastWakeTime = wtime;
18498                    app.lastCpuTime = app.curCpuTime;
18499                }
18500            }
18501        }
18502    }
18503
18504    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now) {
18505        boolean success = true;
18506
18507        if (app.curRawAdj != app.setRawAdj) {
18508            app.setRawAdj = app.curRawAdj;
18509        }
18510
18511        int changes = 0;
18512
18513        if (app.curAdj != app.setAdj) {
18514            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
18515            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18516                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
18517                    + app.adjType);
18518            app.setAdj = app.curAdj;
18519        }
18520
18521        if (app.setSchedGroup != app.curSchedGroup) {
18522            app.setSchedGroup = app.curSchedGroup;
18523            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18524                    "Setting process group of " + app.processName
18525                    + " to " + app.curSchedGroup);
18526            if (app.waitingToKill != null && app.curReceiver == null
18527                    && app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
18528                app.kill(app.waitingToKill, true);
18529                success = false;
18530            } else {
18531                if (true) {
18532                    long oldId = Binder.clearCallingIdentity();
18533                    try {
18534                        Process.setProcessGroup(app.pid, app.curSchedGroup);
18535                    } catch (Exception e) {
18536                        Slog.w(TAG, "Failed setting process group of " + app.pid
18537                                + " to " + app.curSchedGroup);
18538                        e.printStackTrace();
18539                    } finally {
18540                        Binder.restoreCallingIdentity(oldId);
18541                    }
18542                } else {
18543                    if (app.thread != null) {
18544                        try {
18545                            app.thread.setSchedulingGroup(app.curSchedGroup);
18546                        } catch (RemoteException e) {
18547                        }
18548                    }
18549                }
18550                Process.setSwappiness(app.pid,
18551                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
18552            }
18553        }
18554        if (app.repForegroundActivities != app.foregroundActivities) {
18555            app.repForegroundActivities = app.foregroundActivities;
18556            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
18557        }
18558        if (app.repProcState != app.curProcState) {
18559            app.repProcState = app.curProcState;
18560            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
18561            if (app.thread != null) {
18562                try {
18563                    if (false) {
18564                        //RuntimeException h = new RuntimeException("here");
18565                        Slog.i(TAG, "Sending new process state " + app.repProcState
18566                                + " to " + app /*, h*/);
18567                    }
18568                    app.thread.setProcessState(app.repProcState);
18569                } catch (RemoteException e) {
18570                }
18571            }
18572        }
18573        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
18574                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
18575            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
18576                // Experimental code to more aggressively collect pss while
18577                // running test...  the problem is that this tends to collect
18578                // the data right when a process is transitioning between process
18579                // states, which well tend to give noisy data.
18580                long start = SystemClock.uptimeMillis();
18581                long pss = Debug.getPss(app.pid, mTmpLong, null);
18582                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], now);
18583                mPendingPssProcesses.remove(app);
18584                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
18585                        + " to " + app.curProcState + ": "
18586                        + (SystemClock.uptimeMillis()-start) + "ms");
18587            }
18588            app.lastStateTime = now;
18589            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18590                    mTestPssMode, isSleeping(), now);
18591            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
18592                    + ProcessList.makeProcStateString(app.setProcState) + " to "
18593                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
18594                    + (app.nextPssTime-now) + ": " + app);
18595        } else {
18596            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
18597                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
18598                    mTestPssMode)))) {
18599                requestPssLocked(app, app.setProcState);
18600                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
18601                        mTestPssMode, isSleeping(), now);
18602            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
18603                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
18604        }
18605        if (app.setProcState != app.curProcState) {
18606            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18607                    "Proc state change of " + app.processName
18608                    + " to " + app.curProcState);
18609            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
18610            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
18611            if (setImportant && !curImportant) {
18612                // This app is no longer something we consider important enough to allow to
18613                // use arbitrary amounts of battery power.  Note
18614                // its current wake lock time to later know to kill it if
18615                // it is not behaving well.
18616                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18617                synchronized (stats) {
18618                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
18619                            app.pid, SystemClock.elapsedRealtime());
18620                }
18621                app.lastCpuTime = app.curCpuTime;
18622
18623            }
18624            // Inform UsageStats of important process state change
18625            // Must be called before updating setProcState
18626            maybeUpdateUsageStatsLocked(app);
18627
18628            app.setProcState = app.curProcState;
18629            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18630                app.notCachedSinceIdle = false;
18631            }
18632            if (!doingAll) {
18633                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
18634            } else {
18635                app.procStateChanged = true;
18636            }
18637        }
18638
18639        if (changes != 0) {
18640            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18641                    "Changes in " + app + ": " + changes);
18642            int i = mPendingProcessChanges.size()-1;
18643            ProcessChangeItem item = null;
18644            while (i >= 0) {
18645                item = mPendingProcessChanges.get(i);
18646                if (item.pid == app.pid) {
18647                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18648                            "Re-using existing item: " + item);
18649                    break;
18650                }
18651                i--;
18652            }
18653            if (i < 0) {
18654                // No existing item in pending changes; need a new one.
18655                final int NA = mAvailProcessChanges.size();
18656                if (NA > 0) {
18657                    item = mAvailProcessChanges.remove(NA-1);
18658                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18659                            "Retrieving available item: " + item);
18660                } else {
18661                    item = new ProcessChangeItem();
18662                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18663                            "Allocating new item: " + item);
18664                }
18665                item.changes = 0;
18666                item.pid = app.pid;
18667                item.uid = app.info.uid;
18668                if (mPendingProcessChanges.size() == 0) {
18669                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18670                            "*** Enqueueing dispatch processes changed!");
18671                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
18672                }
18673                mPendingProcessChanges.add(item);
18674            }
18675            item.changes |= changes;
18676            item.processState = app.repProcState;
18677            item.foregroundActivities = app.repForegroundActivities;
18678            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18679                    "Item " + Integer.toHexString(System.identityHashCode(item))
18680                    + " " + app.toShortString() + ": changes=" + item.changes
18681                    + " procState=" + item.processState
18682                    + " foreground=" + item.foregroundActivities
18683                    + " type=" + app.adjType + " source=" + app.adjSource
18684                    + " target=" + app.adjTarget);
18685        }
18686
18687        return success;
18688    }
18689
18690    private final void enqueueUidChangeLocked(UidRecord uidRec, boolean gone) {
18691        if (uidRec.pendingChange == null) {
18692            if (mPendingUidChanges.size() == 0) {
18693                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18694                        "*** Enqueueing dispatch uid changed!");
18695                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_MSG).sendToTarget();
18696            }
18697            final int NA = mAvailUidChanges.size();
18698            if (NA > 0) {
18699                uidRec.pendingChange = mAvailUidChanges.remove(NA-1);
18700                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18701                        "Retrieving available item: " + uidRec.pendingChange);
18702            } else {
18703                uidRec.pendingChange = new UidRecord.ChangeItem();
18704                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18705                        "Allocating new item: " + uidRec.pendingChange);
18706            }
18707            uidRec.pendingChange.uidRecord = uidRec;
18708            uidRec.pendingChange.uid = uidRec.uid;
18709            mPendingUidChanges.add(uidRec.pendingChange);
18710        }
18711        uidRec.pendingChange.gone = gone;
18712        uidRec.pendingChange.processState = uidRec.setProcState;
18713    }
18714
18715    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
18716            String authority) {
18717        if (app == null) return;
18718        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18719            UserState userState = mStartedUsers.get(app.userId);
18720            if (userState == null) return;
18721            final long now = SystemClock.elapsedRealtime();
18722            Long lastReported = userState.mProviderLastReportedFg.get(authority);
18723            if (lastReported == null || lastReported < now - 60 * 1000L) {
18724                mUsageStatsService.reportContentProviderUsage(
18725                        authority, providerPkgName, app.userId);
18726                userState.mProviderLastReportedFg.put(authority, now);
18727            }
18728        }
18729    }
18730
18731    private void maybeUpdateUsageStatsLocked(ProcessRecord app) {
18732        if (DEBUG_USAGE_STATS) {
18733            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
18734                    + "] state changes: old = " + app.setProcState + ", new = "
18735                    + app.curProcState);
18736        }
18737        if (mUsageStatsService == null) {
18738            return;
18739        }
18740        boolean isInteraction;
18741        // To avoid some abuse patterns, we are going to be careful about what we consider
18742        // to be an app interaction.  Being the top activity doesn't count while the display
18743        // is sleeping, nor do short foreground services.
18744        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
18745            isInteraction = true;
18746            app.fgInteractionTime = 0;
18747        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
18748            final long now = SystemClock.elapsedRealtime();
18749            if (app.fgInteractionTime == 0) {
18750                app.fgInteractionTime = now;
18751                isInteraction = false;
18752            } else {
18753                isInteraction = now > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
18754            }
18755        } else {
18756            isInteraction = app.curProcState
18757                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18758            app.fgInteractionTime = 0;
18759        }
18760        if (isInteraction && !app.reportedInteraction) {
18761            String[] packages = app.getPackageList();
18762            if (packages != null) {
18763                for (int i = 0; i < packages.length; i++) {
18764                    mUsageStatsService.reportEvent(packages[i], app.userId,
18765                            UsageEvents.Event.SYSTEM_INTERACTION);
18766                }
18767            }
18768        }
18769        app.reportedInteraction = isInteraction;
18770    }
18771
18772    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
18773        if (proc.thread != null) {
18774            if (proc.baseProcessTracker != null) {
18775                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
18776            }
18777            if (proc.repProcState >= 0) {
18778                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
18779                        proc.repProcState);
18780            }
18781        }
18782    }
18783
18784    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
18785            ProcessRecord TOP_APP, boolean doingAll, long now) {
18786        if (app.thread == null) {
18787            return false;
18788        }
18789
18790        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
18791
18792        return applyOomAdjLocked(app, doingAll, now);
18793    }
18794
18795    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
18796            boolean oomAdj) {
18797        if (isForeground != proc.foregroundServices) {
18798            proc.foregroundServices = isForeground;
18799            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
18800                    proc.info.uid);
18801            if (isForeground) {
18802                if (curProcs == null) {
18803                    curProcs = new ArrayList<ProcessRecord>();
18804                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
18805                }
18806                if (!curProcs.contains(proc)) {
18807                    curProcs.add(proc);
18808                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
18809                            proc.info.packageName, proc.info.uid);
18810                }
18811            } else {
18812                if (curProcs != null) {
18813                    if (curProcs.remove(proc)) {
18814                        mBatteryStatsService.noteEvent(
18815                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
18816                                proc.info.packageName, proc.info.uid);
18817                        if (curProcs.size() <= 0) {
18818                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
18819                        }
18820                    }
18821                }
18822            }
18823            if (oomAdj) {
18824                updateOomAdjLocked();
18825            }
18826        }
18827    }
18828
18829    private final ActivityRecord resumedAppLocked() {
18830        ActivityRecord act = mStackSupervisor.resumedAppLocked();
18831        String pkg;
18832        int uid;
18833        if (act != null) {
18834            pkg = act.packageName;
18835            uid = act.info.applicationInfo.uid;
18836        } else {
18837            pkg = null;
18838            uid = -1;
18839        }
18840        // Has the UID or resumed package name changed?
18841        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
18842                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
18843            if (mCurResumedPackage != null) {
18844                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
18845                        mCurResumedPackage, mCurResumedUid);
18846            }
18847            mCurResumedPackage = pkg;
18848            mCurResumedUid = uid;
18849            if (mCurResumedPackage != null) {
18850                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
18851                        mCurResumedPackage, mCurResumedUid);
18852            }
18853        }
18854        return act;
18855    }
18856
18857    final boolean updateOomAdjLocked(ProcessRecord app) {
18858        final ActivityRecord TOP_ACT = resumedAppLocked();
18859        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18860        final boolean wasCached = app.cached;
18861
18862        mAdjSeq++;
18863
18864        // This is the desired cached adjusment we want to tell it to use.
18865        // If our app is currently cached, we know it, and that is it.  Otherwise,
18866        // we don't know it yet, and it needs to now be cached we will then
18867        // need to do a complete oom adj.
18868        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
18869                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
18870        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
18871                SystemClock.uptimeMillis());
18872        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
18873            // Changed to/from cached state, so apps after it in the LRU
18874            // list may also be changed.
18875            updateOomAdjLocked();
18876        }
18877        return success;
18878    }
18879
18880    final void updateOomAdjLocked() {
18881        final ActivityRecord TOP_ACT = resumedAppLocked();
18882        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18883        final long now = SystemClock.uptimeMillis();
18884        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
18885        final int N = mLruProcesses.size();
18886
18887        if (false) {
18888            RuntimeException e = new RuntimeException();
18889            e.fillInStackTrace();
18890            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
18891        }
18892
18893        // Reset state in all uid records.
18894        for (int i=mActiveUids.size()-1; i>=0; i--) {
18895            final UidRecord uidRec = mActiveUids.valueAt(i);
18896            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18897                    "Starting update of " + uidRec);
18898            uidRec.reset();
18899        }
18900
18901        mAdjSeq++;
18902        mNewNumServiceProcs = 0;
18903        mNewNumAServiceProcs = 0;
18904
18905        final int emptyProcessLimit;
18906        final int cachedProcessLimit;
18907        if (mProcessLimit <= 0) {
18908            emptyProcessLimit = cachedProcessLimit = 0;
18909        } else if (mProcessLimit == 1) {
18910            emptyProcessLimit = 1;
18911            cachedProcessLimit = 0;
18912        } else {
18913            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
18914            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
18915        }
18916
18917        // Let's determine how many processes we have running vs.
18918        // how many slots we have for background processes; we may want
18919        // to put multiple processes in a slot of there are enough of
18920        // them.
18921        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
18922                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
18923        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
18924        if (numEmptyProcs > cachedProcessLimit) {
18925            // If there are more empty processes than our limit on cached
18926            // processes, then use the cached process limit for the factor.
18927            // This ensures that the really old empty processes get pushed
18928            // down to the bottom, so if we are running low on memory we will
18929            // have a better chance at keeping around more cached processes
18930            // instead of a gazillion empty processes.
18931            numEmptyProcs = cachedProcessLimit;
18932        }
18933        int emptyFactor = numEmptyProcs/numSlots;
18934        if (emptyFactor < 1) emptyFactor = 1;
18935        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
18936        if (cachedFactor < 1) cachedFactor = 1;
18937        int stepCached = 0;
18938        int stepEmpty = 0;
18939        int numCached = 0;
18940        int numEmpty = 0;
18941        int numTrimming = 0;
18942
18943        mNumNonCachedProcs = 0;
18944        mNumCachedHiddenProcs = 0;
18945
18946        // First update the OOM adjustment for each of the
18947        // application processes based on their current state.
18948        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
18949        int nextCachedAdj = curCachedAdj+1;
18950        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
18951        int nextEmptyAdj = curEmptyAdj+2;
18952        for (int i=N-1; i>=0; i--) {
18953            ProcessRecord app = mLruProcesses.get(i);
18954            if (!app.killedByAm && app.thread != null) {
18955                app.procStateChanged = false;
18956                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
18957
18958                // If we haven't yet assigned the final cached adj
18959                // to the process, do that now.
18960                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
18961                    switch (app.curProcState) {
18962                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18963                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18964                            // This process is a cached process holding activities...
18965                            // assign it the next cached value for that type, and then
18966                            // step that cached level.
18967                            app.curRawAdj = curCachedAdj;
18968                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
18969                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
18970                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
18971                                    + ")");
18972                            if (curCachedAdj != nextCachedAdj) {
18973                                stepCached++;
18974                                if (stepCached >= cachedFactor) {
18975                                    stepCached = 0;
18976                                    curCachedAdj = nextCachedAdj;
18977                                    nextCachedAdj += 2;
18978                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18979                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
18980                                    }
18981                                }
18982                            }
18983                            break;
18984                        default:
18985                            // For everything else, assign next empty cached process
18986                            // level and bump that up.  Note that this means that
18987                            // long-running services that have dropped down to the
18988                            // cached level will be treated as empty (since their process
18989                            // state is still as a service), which is what we want.
18990                            app.curRawAdj = curEmptyAdj;
18991                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
18992                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
18993                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
18994                                    + ")");
18995                            if (curEmptyAdj != nextEmptyAdj) {
18996                                stepEmpty++;
18997                                if (stepEmpty >= emptyFactor) {
18998                                    stepEmpty = 0;
18999                                    curEmptyAdj = nextEmptyAdj;
19000                                    nextEmptyAdj += 2;
19001                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19002                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
19003                                    }
19004                                }
19005                            }
19006                            break;
19007                    }
19008                }
19009
19010                applyOomAdjLocked(app, true, now);
19011
19012                // Count the number of process types.
19013                switch (app.curProcState) {
19014                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19015                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19016                        mNumCachedHiddenProcs++;
19017                        numCached++;
19018                        if (numCached > cachedProcessLimit) {
19019                            app.kill("cached #" + numCached, true);
19020                        }
19021                        break;
19022                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
19023                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
19024                                && app.lastActivityTime < oldTime) {
19025                            app.kill("empty for "
19026                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
19027                                    / 1000) + "s", true);
19028                        } else {
19029                            numEmpty++;
19030                            if (numEmpty > emptyProcessLimit) {
19031                                app.kill("empty #" + numEmpty, true);
19032                            }
19033                        }
19034                        break;
19035                    default:
19036                        mNumNonCachedProcs++;
19037                        break;
19038                }
19039
19040                if (app.isolated && app.services.size() <= 0) {
19041                    // If this is an isolated process, and there are no
19042                    // services running in it, then the process is no longer
19043                    // needed.  We agressively kill these because we can by
19044                    // definition not re-use the same process again, and it is
19045                    // good to avoid having whatever code was running in them
19046                    // left sitting around after no longer needed.
19047                    app.kill("isolated not needed", true);
19048                } else {
19049                    // Keeping this process, update its uid.
19050                    final UidRecord uidRec = app.uidRecord;
19051                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
19052                        uidRec.curProcState = app.curProcState;
19053                    }
19054                }
19055
19056                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19057                        && !app.killedByAm) {
19058                    numTrimming++;
19059                }
19060            }
19061        }
19062
19063        mNumServiceProcs = mNewNumServiceProcs;
19064
19065        // Now determine the memory trimming level of background processes.
19066        // Unfortunately we need to start at the back of the list to do this
19067        // properly.  We only do this if the number of background apps we
19068        // are managing to keep around is less than half the maximum we desire;
19069        // if we are keeping a good number around, we'll let them use whatever
19070        // memory they want.
19071        final int numCachedAndEmpty = numCached + numEmpty;
19072        int memFactor;
19073        if (numCached <= ProcessList.TRIM_CACHED_APPS
19074                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
19075            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
19076                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
19077            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
19078                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
19079            } else {
19080                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
19081            }
19082        } else {
19083            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
19084        }
19085        // We always allow the memory level to go up (better).  We only allow it to go
19086        // down if we are in a state where that is allowed, *and* the total number of processes
19087        // has gone down since last time.
19088        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
19089                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
19090                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
19091        if (memFactor > mLastMemoryLevel) {
19092            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
19093                memFactor = mLastMemoryLevel;
19094                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
19095            }
19096        }
19097        mLastMemoryLevel = memFactor;
19098        mLastNumProcesses = mLruProcesses.size();
19099        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
19100        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
19101        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
19102            if (mLowRamStartTime == 0) {
19103                mLowRamStartTime = now;
19104            }
19105            int step = 0;
19106            int fgTrimLevel;
19107            switch (memFactor) {
19108                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
19109                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
19110                    break;
19111                case ProcessStats.ADJ_MEM_FACTOR_LOW:
19112                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
19113                    break;
19114                default:
19115                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
19116                    break;
19117            }
19118            int factor = numTrimming/3;
19119            int minFactor = 2;
19120            if (mHomeProcess != null) minFactor++;
19121            if (mPreviousProcess != null) minFactor++;
19122            if (factor < minFactor) factor = minFactor;
19123            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
19124            for (int i=N-1; i>=0; i--) {
19125                ProcessRecord app = mLruProcesses.get(i);
19126                if (allChanged || app.procStateChanged) {
19127                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
19128                    app.procStateChanged = false;
19129                }
19130                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19131                        && !app.killedByAm) {
19132                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
19133                        try {
19134                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19135                                    "Trimming memory of " + app.processName + " to " + curLevel);
19136                            app.thread.scheduleTrimMemory(curLevel);
19137                        } catch (RemoteException e) {
19138                        }
19139                        if (false) {
19140                            // For now we won't do this; our memory trimming seems
19141                            // to be good enough at this point that destroying
19142                            // activities causes more harm than good.
19143                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
19144                                    && app != mHomeProcess && app != mPreviousProcess) {
19145                                // Need to do this on its own message because the stack may not
19146                                // be in a consistent state at this point.
19147                                // For these apps we will also finish their activities
19148                                // to help them free memory.
19149                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
19150                            }
19151                        }
19152                    }
19153                    app.trimMemoryLevel = curLevel;
19154                    step++;
19155                    if (step >= factor) {
19156                        step = 0;
19157                        switch (curLevel) {
19158                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
19159                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
19160                                break;
19161                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
19162                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19163                                break;
19164                        }
19165                    }
19166                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19167                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
19168                            && app.thread != null) {
19169                        try {
19170                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19171                                    "Trimming memory of heavy-weight " + app.processName
19172                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19173                            app.thread.scheduleTrimMemory(
19174                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19175                        } catch (RemoteException e) {
19176                        }
19177                    }
19178                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19179                } else {
19180                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19181                            || app.systemNoUi) && app.pendingUiClean) {
19182                        // If this application is now in the background and it
19183                        // had done UI, then give it the special trim level to
19184                        // have it free UI resources.
19185                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
19186                        if (app.trimMemoryLevel < level && app.thread != null) {
19187                            try {
19188                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19189                                        "Trimming memory of bg-ui " + app.processName
19190                                        + " to " + level);
19191                                app.thread.scheduleTrimMemory(level);
19192                            } catch (RemoteException e) {
19193                            }
19194                        }
19195                        app.pendingUiClean = false;
19196                    }
19197                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
19198                        try {
19199                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19200                                    "Trimming memory of fg " + app.processName
19201                                    + " to " + fgTrimLevel);
19202                            app.thread.scheduleTrimMemory(fgTrimLevel);
19203                        } catch (RemoteException e) {
19204                        }
19205                    }
19206                    app.trimMemoryLevel = fgTrimLevel;
19207                }
19208            }
19209        } else {
19210            if (mLowRamStartTime != 0) {
19211                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
19212                mLowRamStartTime = 0;
19213            }
19214            for (int i=N-1; i>=0; i--) {
19215                ProcessRecord app = mLruProcesses.get(i);
19216                if (allChanged || app.procStateChanged) {
19217                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
19218                    app.procStateChanged = false;
19219                }
19220                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19221                        || app.systemNoUi) && app.pendingUiClean) {
19222                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
19223                            && app.thread != null) {
19224                        try {
19225                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19226                                    "Trimming memory of ui hidden " + app.processName
19227                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19228                            app.thread.scheduleTrimMemory(
19229                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19230                        } catch (RemoteException e) {
19231                        }
19232                    }
19233                    app.pendingUiClean = false;
19234                }
19235                app.trimMemoryLevel = 0;
19236            }
19237        }
19238
19239        if (mAlwaysFinishActivities) {
19240            // Need to do this on its own message because the stack may not
19241            // be in a consistent state at this point.
19242            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
19243        }
19244
19245        if (allChanged) {
19246            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
19247        }
19248
19249        // Update from any uid changes.
19250        for (int i=mActiveUids.size()-1; i>=0; i--) {
19251            final UidRecord uidRec = mActiveUids.valueAt(i);
19252            if (uidRec.setProcState != uidRec.curProcState) {
19253                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19254                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
19255                        + " to " + uidRec.curProcState);
19256                uidRec.setProcState = uidRec.curProcState;
19257                enqueueUidChangeLocked(uidRec, false);
19258            }
19259        }
19260
19261        if (mProcessStats.shouldWriteNowLocked(now)) {
19262            mHandler.post(new Runnable() {
19263                @Override public void run() {
19264                    synchronized (ActivityManagerService.this) {
19265                        mProcessStats.writeStateAsyncLocked();
19266                    }
19267                }
19268            });
19269        }
19270
19271        if (DEBUG_OOM_ADJ) {
19272            final long duration = SystemClock.uptimeMillis() - now;
19273            if (false) {
19274                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
19275                        new RuntimeException("here").fillInStackTrace());
19276            } else {
19277                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
19278            }
19279        }
19280    }
19281
19282    final void trimApplications() {
19283        synchronized (this) {
19284            int i;
19285
19286            // First remove any unused application processes whose package
19287            // has been removed.
19288            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
19289                final ProcessRecord app = mRemovedProcesses.get(i);
19290                if (app.activities.size() == 0
19291                        && app.curReceiver == null && app.services.size() == 0) {
19292                    Slog.i(
19293                        TAG, "Exiting empty application process "
19294                        + app.processName + " ("
19295                        + (app.thread != null ? app.thread.asBinder() : null)
19296                        + ")\n");
19297                    if (app.pid > 0 && app.pid != MY_PID) {
19298                        app.kill("empty", false);
19299                    } else {
19300                        try {
19301                            app.thread.scheduleExit();
19302                        } catch (Exception e) {
19303                            // Ignore exceptions.
19304                        }
19305                    }
19306                    cleanUpApplicationRecordLocked(app, false, true, -1);
19307                    mRemovedProcesses.remove(i);
19308
19309                    if (app.persistent) {
19310                        addAppLocked(app.info, false, null /* ABI override */);
19311                    }
19312                }
19313            }
19314
19315            // Now update the oom adj for all processes.
19316            updateOomAdjLocked();
19317        }
19318    }
19319
19320    /** This method sends the specified signal to each of the persistent apps */
19321    public void signalPersistentProcesses(int sig) throws RemoteException {
19322        if (sig != Process.SIGNAL_USR1) {
19323            throw new SecurityException("Only SIGNAL_USR1 is allowed");
19324        }
19325
19326        synchronized (this) {
19327            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
19328                    != PackageManager.PERMISSION_GRANTED) {
19329                throw new SecurityException("Requires permission "
19330                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
19331            }
19332
19333            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
19334                ProcessRecord r = mLruProcesses.get(i);
19335                if (r.thread != null && r.persistent) {
19336                    Process.sendSignal(r.pid, sig);
19337                }
19338            }
19339        }
19340    }
19341
19342    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
19343        if (proc == null || proc == mProfileProc) {
19344            proc = mProfileProc;
19345            profileType = mProfileType;
19346            clearProfilerLocked();
19347        }
19348        if (proc == null) {
19349            return;
19350        }
19351        try {
19352            proc.thread.profilerControl(false, null, profileType);
19353        } catch (RemoteException e) {
19354            throw new IllegalStateException("Process disappeared");
19355        }
19356    }
19357
19358    private void clearProfilerLocked() {
19359        if (mProfileFd != null) {
19360            try {
19361                mProfileFd.close();
19362            } catch (IOException e) {
19363            }
19364        }
19365        mProfileApp = null;
19366        mProfileProc = null;
19367        mProfileFile = null;
19368        mProfileType = 0;
19369        mAutoStopProfiler = false;
19370        mSamplingInterval = 0;
19371    }
19372
19373    public boolean profileControl(String process, int userId, boolean start,
19374            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
19375
19376        try {
19377            synchronized (this) {
19378                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19379                // its own permission.
19380                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19381                        != PackageManager.PERMISSION_GRANTED) {
19382                    throw new SecurityException("Requires permission "
19383                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19384                }
19385
19386                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
19387                    throw new IllegalArgumentException("null profile info or fd");
19388                }
19389
19390                ProcessRecord proc = null;
19391                if (process != null) {
19392                    proc = findProcessLocked(process, userId, "profileControl");
19393                }
19394
19395                if (start && (proc == null || proc.thread == null)) {
19396                    throw new IllegalArgumentException("Unknown process: " + process);
19397                }
19398
19399                if (start) {
19400                    stopProfilerLocked(null, 0);
19401                    setProfileApp(proc.info, proc.processName, profilerInfo);
19402                    mProfileProc = proc;
19403                    mProfileType = profileType;
19404                    ParcelFileDescriptor fd = profilerInfo.profileFd;
19405                    try {
19406                        fd = fd.dup();
19407                    } catch (IOException e) {
19408                        fd = null;
19409                    }
19410                    profilerInfo.profileFd = fd;
19411                    proc.thread.profilerControl(start, profilerInfo, profileType);
19412                    fd = null;
19413                    mProfileFd = null;
19414                } else {
19415                    stopProfilerLocked(proc, profileType);
19416                    if (profilerInfo != null && profilerInfo.profileFd != null) {
19417                        try {
19418                            profilerInfo.profileFd.close();
19419                        } catch (IOException e) {
19420                        }
19421                    }
19422                }
19423
19424                return true;
19425            }
19426        } catch (RemoteException e) {
19427            throw new IllegalStateException("Process disappeared");
19428        } finally {
19429            if (profilerInfo != null && profilerInfo.profileFd != null) {
19430                try {
19431                    profilerInfo.profileFd.close();
19432                } catch (IOException e) {
19433                }
19434            }
19435        }
19436    }
19437
19438    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
19439        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19440                userId, true, ALLOW_FULL_ONLY, callName, null);
19441        ProcessRecord proc = null;
19442        try {
19443            int pid = Integer.parseInt(process);
19444            synchronized (mPidsSelfLocked) {
19445                proc = mPidsSelfLocked.get(pid);
19446            }
19447        } catch (NumberFormatException e) {
19448        }
19449
19450        if (proc == null) {
19451            ArrayMap<String, SparseArray<ProcessRecord>> all
19452                    = mProcessNames.getMap();
19453            SparseArray<ProcessRecord> procs = all.get(process);
19454            if (procs != null && procs.size() > 0) {
19455                proc = procs.valueAt(0);
19456                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
19457                    for (int i=1; i<procs.size(); i++) {
19458                        ProcessRecord thisProc = procs.valueAt(i);
19459                        if (thisProc.userId == userId) {
19460                            proc = thisProc;
19461                            break;
19462                        }
19463                    }
19464                }
19465            }
19466        }
19467
19468        return proc;
19469    }
19470
19471    public boolean dumpHeap(String process, int userId, boolean managed,
19472            String path, ParcelFileDescriptor fd) throws RemoteException {
19473
19474        try {
19475            synchronized (this) {
19476                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19477                // its own permission (same as profileControl).
19478                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19479                        != PackageManager.PERMISSION_GRANTED) {
19480                    throw new SecurityException("Requires permission "
19481                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19482                }
19483
19484                if (fd == null) {
19485                    throw new IllegalArgumentException("null fd");
19486                }
19487
19488                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
19489                if (proc == null || proc.thread == null) {
19490                    throw new IllegalArgumentException("Unknown process: " + process);
19491                }
19492
19493                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19494                if (!isDebuggable) {
19495                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19496                        throw new SecurityException("Process not debuggable: " + proc);
19497                    }
19498                }
19499
19500                proc.thread.dumpHeap(managed, path, fd);
19501                fd = null;
19502                return true;
19503            }
19504        } catch (RemoteException e) {
19505            throw new IllegalStateException("Process disappeared");
19506        } finally {
19507            if (fd != null) {
19508                try {
19509                    fd.close();
19510                } catch (IOException e) {
19511                }
19512            }
19513        }
19514    }
19515
19516    @Override
19517    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
19518            String reportPackage) {
19519        if (processName != null) {
19520            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
19521                    "setDumpHeapDebugLimit()");
19522        } else {
19523            synchronized (mPidsSelfLocked) {
19524                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
19525                if (proc == null) {
19526                    throw new SecurityException("No process found for calling pid "
19527                            + Binder.getCallingPid());
19528                }
19529                if (!Build.IS_DEBUGGABLE
19530                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19531                    throw new SecurityException("Not running a debuggable build");
19532                }
19533                processName = proc.processName;
19534                uid = proc.uid;
19535                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
19536                    throw new SecurityException("Package " + reportPackage + " is not running in "
19537                            + proc);
19538                }
19539            }
19540        }
19541        synchronized (this) {
19542            if (maxMemSize > 0) {
19543                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
19544            } else {
19545                if (uid != 0) {
19546                    mMemWatchProcesses.remove(processName, uid);
19547                } else {
19548                    mMemWatchProcesses.getMap().remove(processName);
19549                }
19550            }
19551        }
19552    }
19553
19554    @Override
19555    public void dumpHeapFinished(String path) {
19556        synchronized (this) {
19557            if (Binder.getCallingPid() != mMemWatchDumpPid) {
19558                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
19559                        + " does not match last pid " + mMemWatchDumpPid);
19560                return;
19561            }
19562            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
19563                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
19564                        + " does not match last path " + mMemWatchDumpFile);
19565                return;
19566            }
19567            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
19568            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
19569        }
19570    }
19571
19572    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
19573    public void monitor() {
19574        synchronized (this) { }
19575    }
19576
19577    void onCoreSettingsChange(Bundle settings) {
19578        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19579            ProcessRecord processRecord = mLruProcesses.get(i);
19580            try {
19581                if (processRecord.thread != null) {
19582                    processRecord.thread.setCoreSettings(settings);
19583                }
19584            } catch (RemoteException re) {
19585                /* ignore */
19586            }
19587        }
19588    }
19589
19590    // Multi-user methods
19591
19592    /**
19593     * Start user, if its not already running, but don't bring it to foreground.
19594     */
19595    @Override
19596    public boolean startUserInBackground(final int userId) {
19597        return startUser(userId, /* foreground */ false);
19598    }
19599
19600    /**
19601     * Start user, if its not already running, and bring it to foreground.
19602     */
19603    boolean startUserInForeground(final int userId, Dialog dlg) {
19604        boolean result = startUser(userId, /* foreground */ true);
19605        dlg.dismiss();
19606        return result;
19607    }
19608
19609    /**
19610     * Refreshes the list of users related to the current user when either a
19611     * user switch happens or when a new related user is started in the
19612     * background.
19613     */
19614    private void updateCurrentProfileIdsLocked() {
19615        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19616                mCurrentUserId, false /* enabledOnly */);
19617        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
19618        for (int i = 0; i < currentProfileIds.length; i++) {
19619            currentProfileIds[i] = profiles.get(i).id;
19620        }
19621        mCurrentProfileIds = currentProfileIds;
19622
19623        synchronized (mUserProfileGroupIdsSelfLocked) {
19624            mUserProfileGroupIdsSelfLocked.clear();
19625            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
19626            for (int i = 0; i < users.size(); i++) {
19627                UserInfo user = users.get(i);
19628                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
19629                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
19630                }
19631            }
19632        }
19633    }
19634
19635    private Set<Integer> getProfileIdsLocked(int userId) {
19636        Set<Integer> userIds = new HashSet<Integer>();
19637        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19638                userId, false /* enabledOnly */);
19639        for (UserInfo user : profiles) {
19640            userIds.add(Integer.valueOf(user.id));
19641        }
19642        return userIds;
19643    }
19644
19645    @Override
19646    public boolean switchUser(final int userId) {
19647        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19648        String userName;
19649        synchronized (this) {
19650            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19651            if (userInfo == null) {
19652                Slog.w(TAG, "No user info for user #" + userId);
19653                return false;
19654            }
19655            if (userInfo.isManagedProfile()) {
19656                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19657                return false;
19658            }
19659            userName = userInfo.name;
19660            mTargetUserId = userId;
19661        }
19662        mUiHandler.removeMessages(START_USER_SWITCH_MSG);
19663        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
19664        return true;
19665    }
19666
19667    private void showUserSwitchDialog(int userId, String userName) {
19668        // The dialog will show and then initiate the user switch by calling startUserInForeground
19669        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
19670                true /* above system */);
19671        d.show();
19672    }
19673
19674    private boolean startUser(final int userId, final boolean foreground) {
19675        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19676                != PackageManager.PERMISSION_GRANTED) {
19677            String msg = "Permission Denial: switchUser() from pid="
19678                    + Binder.getCallingPid()
19679                    + ", uid=" + Binder.getCallingUid()
19680                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19681            Slog.w(TAG, msg);
19682            throw new SecurityException(msg);
19683        }
19684
19685        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
19686
19687        final long ident = Binder.clearCallingIdentity();
19688        try {
19689            synchronized (this) {
19690                final int oldUserId = mCurrentUserId;
19691                if (oldUserId == userId) {
19692                    return true;
19693                }
19694
19695                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
19696                        "startUser", false);
19697
19698                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19699                if (userInfo == null) {
19700                    Slog.w(TAG, "No user info for user #" + userId);
19701                    return false;
19702                }
19703                if (foreground && userInfo.isManagedProfile()) {
19704                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19705                    return false;
19706                }
19707
19708                if (foreground) {
19709                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
19710                            R.anim.screen_user_enter);
19711                }
19712
19713                boolean needStart = false;
19714
19715                // If the user we are switching to is not currently started, then
19716                // we need to start it now.
19717                if (mStartedUsers.get(userId) == null) {
19718                    mStartedUsers.put(userId, new UserState(new UserHandle(userId), false));
19719                    updateStartedUserArrayLocked();
19720                    needStart = true;
19721                }
19722
19723                final Integer userIdInt = Integer.valueOf(userId);
19724                mUserLru.remove(userIdInt);
19725                mUserLru.add(userIdInt);
19726
19727                if (foreground) {
19728                    mCurrentUserId = userId;
19729                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
19730                    updateCurrentProfileIdsLocked();
19731                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
19732                    // Once the internal notion of the active user has switched, we lock the device
19733                    // with the option to show the user switcher on the keyguard.
19734                    mWindowManager.lockNow(null);
19735                } else {
19736                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
19737                    updateCurrentProfileIdsLocked();
19738                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
19739                    mUserLru.remove(currentUserIdInt);
19740                    mUserLru.add(currentUserIdInt);
19741                }
19742
19743                final UserState uss = mStartedUsers.get(userId);
19744
19745                // Make sure user is in the started state.  If it is currently
19746                // stopping, we need to knock that off.
19747                if (uss.mState == UserState.STATE_STOPPING) {
19748                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
19749                    // so we can just fairly silently bring the user back from
19750                    // the almost-dead.
19751                    uss.mState = UserState.STATE_RUNNING;
19752                    updateStartedUserArrayLocked();
19753                    needStart = true;
19754                } else if (uss.mState == UserState.STATE_SHUTDOWN) {
19755                    // This means ACTION_SHUTDOWN has been sent, so we will
19756                    // need to treat this as a new boot of the user.
19757                    uss.mState = UserState.STATE_BOOTING;
19758                    updateStartedUserArrayLocked();
19759                    needStart = true;
19760                }
19761
19762                if (uss.mState == UserState.STATE_BOOTING) {
19763                    // Booting up a new user, need to tell system services about it.
19764                    // Note that this is on the same handler as scheduling of broadcasts,
19765                    // which is important because it needs to go first.
19766                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
19767                }
19768
19769                if (foreground) {
19770                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
19771                            oldUserId));
19772                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
19773                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19774                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
19775                            oldUserId, userId, uss));
19776                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
19777                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
19778                }
19779
19780                if (needStart) {
19781                    // Send USER_STARTED broadcast
19782                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
19783                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19784                            | Intent.FLAG_RECEIVER_FOREGROUND);
19785                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19786                    broadcastIntentLocked(null, null, intent,
19787                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19788                            null, false, false, MY_PID, Process.SYSTEM_UID, userId);
19789                }
19790
19791                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
19792                    if (userId != UserHandle.USER_OWNER) {
19793                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
19794                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19795                        broadcastIntentLocked(null, null, intent, null,
19796                                new IIntentReceiver.Stub() {
19797                                    public void performReceive(Intent intent, int resultCode,
19798                                            String data, Bundle extras, boolean ordered,
19799                                            boolean sticky, int sendingUser) {
19800                                        onUserInitialized(uss, foreground, oldUserId, userId);
19801                                    }
19802                                }, 0, null, null, null, AppOpsManager.OP_NONE,
19803                                null, true, false, MY_PID, Process.SYSTEM_UID, userId);
19804                        uss.initializing = true;
19805                    } else {
19806                        getUserManagerLocked().makeInitialized(userInfo.id);
19807                    }
19808                }
19809
19810                if (foreground) {
19811                    if (!uss.initializing) {
19812                        moveUserToForeground(uss, oldUserId, userId);
19813                    }
19814                } else {
19815                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
19816                }
19817
19818                if (needStart) {
19819                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
19820                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19821                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19822                    broadcastIntentLocked(null, null, intent,
19823                            null, new IIntentReceiver.Stub() {
19824                                @Override
19825                                public void performReceive(Intent intent, int resultCode,
19826                                        String data, Bundle extras, boolean ordered, boolean sticky,
19827                                        int sendingUser) throws RemoteException {
19828                                }
19829                            }, 0, null, null,
19830                            new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
19831                            null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19832                }
19833            }
19834        } finally {
19835            Binder.restoreCallingIdentity(ident);
19836        }
19837
19838        return true;
19839    }
19840
19841    void dispatchForegroundProfileChanged(int userId) {
19842        final int N = mUserSwitchObservers.beginBroadcast();
19843        for (int i = 0; i < N; i++) {
19844            try {
19845                mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
19846            } catch (RemoteException e) {
19847                // Ignore
19848            }
19849        }
19850        mUserSwitchObservers.finishBroadcast();
19851    }
19852
19853    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
19854        long ident = Binder.clearCallingIdentity();
19855        try {
19856            Intent intent;
19857            if (oldUserId >= 0) {
19858                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
19859                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
19860                int count = profiles.size();
19861                for (int i = 0; i < count; i++) {
19862                    int profileUserId = profiles.get(i).id;
19863                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
19864                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19865                            | Intent.FLAG_RECEIVER_FOREGROUND);
19866                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19867                    broadcastIntentLocked(null, null, intent,
19868                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19869                            null, false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19870                }
19871            }
19872            if (newUserId >= 0) {
19873                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
19874                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, 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_FOREGROUND);
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                intent = new Intent(Intent.ACTION_USER_SWITCHED);
19887                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19888                        | Intent.FLAG_RECEIVER_FOREGROUND);
19889                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
19890                broadcastIntentLocked(null, null, intent,
19891                        null, null, 0, null, null,
19892                        new String[] {android.Manifest.permission.MANAGE_USERS},
19893                        AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
19894                        UserHandle.USER_ALL);
19895            }
19896        } finally {
19897            Binder.restoreCallingIdentity(ident);
19898        }
19899    }
19900
19901    void dispatchUserSwitch(final UserState uss, final int oldUserId,
19902            final int newUserId) {
19903        final int N = mUserSwitchObservers.beginBroadcast();
19904        if (N > 0) {
19905            final IRemoteCallback callback = new IRemoteCallback.Stub() {
19906                int mCount = 0;
19907                @Override
19908                public void sendResult(Bundle data) throws RemoteException {
19909                    synchronized (ActivityManagerService.this) {
19910                        if (mCurUserSwitchCallback == this) {
19911                            mCount++;
19912                            if (mCount == N) {
19913                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19914                            }
19915                        }
19916                    }
19917                }
19918            };
19919            synchronized (this) {
19920                uss.switching = true;
19921                mCurUserSwitchCallback = callback;
19922            }
19923            for (int i=0; i<N; i++) {
19924                try {
19925                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
19926                            newUserId, callback);
19927                } catch (RemoteException e) {
19928                }
19929            }
19930        } else {
19931            synchronized (this) {
19932                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19933            }
19934        }
19935        mUserSwitchObservers.finishBroadcast();
19936    }
19937
19938    void timeoutUserSwitch(UserState uss, int oldUserId, int newUserId) {
19939        synchronized (this) {
19940            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
19941            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19942        }
19943    }
19944
19945    void sendContinueUserSwitchLocked(UserState uss, int oldUserId, int newUserId) {
19946        mCurUserSwitchCallback = null;
19947        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19948        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
19949                oldUserId, newUserId, uss));
19950    }
19951
19952    void onUserInitialized(UserState uss, boolean foreground, int oldUserId, int newUserId) {
19953        synchronized (this) {
19954            if (foreground) {
19955                moveUserToForeground(uss, oldUserId, newUserId);
19956            }
19957        }
19958
19959        completeSwitchAndInitialize(uss, newUserId, true, false);
19960    }
19961
19962    void moveUserToForeground(UserState uss, int oldUserId, int newUserId) {
19963        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
19964        if (homeInFront) {
19965            startHomeActivityLocked(newUserId, "moveUserToFroreground");
19966        } else {
19967            mStackSupervisor.resumeTopActivitiesLocked();
19968        }
19969        EventLogTags.writeAmSwitchUser(newUserId);
19970        getUserManagerLocked().onUserForeground(newUserId);
19971        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
19972    }
19973
19974    void continueUserSwitch(UserState uss, int oldUserId, int newUserId) {
19975        completeSwitchAndInitialize(uss, newUserId, false, true);
19976    }
19977
19978    void completeSwitchAndInitialize(UserState uss, int newUserId,
19979            boolean clearInitializing, boolean clearSwitching) {
19980        boolean unfrozen = false;
19981        synchronized (this) {
19982            if (clearInitializing) {
19983                uss.initializing = false;
19984                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
19985            }
19986            if (clearSwitching) {
19987                uss.switching = false;
19988            }
19989            if (!uss.switching && !uss.initializing) {
19990                mWindowManager.stopFreezingScreen();
19991                unfrozen = true;
19992            }
19993        }
19994        if (unfrozen) {
19995            mHandler.removeMessages(REPORT_USER_SWITCH_COMPLETE_MSG);
19996            mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_COMPLETE_MSG,
19997                    newUserId, 0));
19998        }
19999        stopGuestUserIfBackground();
20000    }
20001
20002    /** Called on handler thread */
20003    void dispatchUserSwitchComplete(int userId) {
20004        final int observerCount = mUserSwitchObservers.beginBroadcast();
20005        for (int i = 0; i < observerCount; i++) {
20006            try {
20007                mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(userId);
20008            } catch (RemoteException e) {
20009            }
20010        }
20011        mUserSwitchObservers.finishBroadcast();
20012    }
20013
20014    /**
20015     * Stops the guest user if it has gone to the background.
20016     */
20017    private void stopGuestUserIfBackground() {
20018        synchronized (this) {
20019            final int num = mUserLru.size();
20020            for (int i = 0; i < num; i++) {
20021                Integer oldUserId = mUserLru.get(i);
20022                UserState oldUss = mStartedUsers.get(oldUserId);
20023                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
20024                        || oldUss.mState == UserState.STATE_STOPPING
20025                        || oldUss.mState == UserState.STATE_SHUTDOWN) {
20026                    continue;
20027                }
20028                UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
20029                if (userInfo.isGuest()) {
20030                    // This is a user to be stopped.
20031                    stopUserLocked(oldUserId, null);
20032                    break;
20033                }
20034            }
20035        }
20036    }
20037
20038    void scheduleStartProfilesLocked() {
20039        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20040            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20041                    DateUtils.SECOND_IN_MILLIS);
20042        }
20043    }
20044
20045    void startProfilesLocked() {
20046        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
20047        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
20048                mCurrentUserId, false /* enabledOnly */);
20049        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
20050        for (UserInfo user : profiles) {
20051            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
20052                    && user.id != mCurrentUserId) {
20053                toStart.add(user);
20054            }
20055        }
20056        final int n = toStart.size();
20057        int i = 0;
20058        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
20059            startUserInBackground(toStart.get(i).id);
20060        }
20061        if (i < n) {
20062            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
20063        }
20064    }
20065
20066    void finishUserBoot(UserState uss) {
20067        synchronized (this) {
20068            if (uss.mState == UserState.STATE_BOOTING
20069                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
20070                uss.mState = UserState.STATE_RUNNING;
20071                final int userId = uss.mHandle.getIdentifier();
20072                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
20073                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20074                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
20075                broadcastIntentLocked(null, null, intent,
20076                        null, null, 0, null, null,
20077                        new String[] {android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
20078                        AppOpsManager.OP_NONE, null, true, false, MY_PID, Process.SYSTEM_UID,
20079                        userId);
20080            }
20081        }
20082    }
20083
20084    void finishUserSwitch(UserState uss) {
20085        synchronized (this) {
20086            finishUserBoot(uss);
20087
20088            startProfilesLocked();
20089
20090            int num = mUserLru.size();
20091            int i = 0;
20092            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
20093                Integer oldUserId = mUserLru.get(i);
20094                UserState oldUss = mStartedUsers.get(oldUserId);
20095                if (oldUss == null) {
20096                    // Shouldn't happen, but be sane if it does.
20097                    mUserLru.remove(i);
20098                    num--;
20099                    continue;
20100                }
20101                if (oldUss.mState == UserState.STATE_STOPPING
20102                        || oldUss.mState == UserState.STATE_SHUTDOWN) {
20103                    // This user is already stopping, doesn't count.
20104                    num--;
20105                    i++;
20106                    continue;
20107                }
20108                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
20109                    // Owner and current can't be stopped, but count as running.
20110                    i++;
20111                    continue;
20112                }
20113                // This is a user to be stopped.
20114                stopUserLocked(oldUserId, null);
20115                num--;
20116                i++;
20117            }
20118        }
20119    }
20120
20121    @Override
20122    public int stopUser(final int userId, final IStopUserCallback callback) {
20123        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20124                != PackageManager.PERMISSION_GRANTED) {
20125            String msg = "Permission Denial: switchUser() from pid="
20126                    + Binder.getCallingPid()
20127                    + ", uid=" + Binder.getCallingUid()
20128                    + " requires " + INTERACT_ACROSS_USERS_FULL;
20129            Slog.w(TAG, msg);
20130            throw new SecurityException(msg);
20131        }
20132        if (userId < 0 || userId == UserHandle.USER_OWNER) {
20133            throw new IllegalArgumentException("Can't stop primary user " + userId);
20134        }
20135        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
20136        synchronized (this) {
20137            return stopUserLocked(userId, callback);
20138        }
20139    }
20140
20141    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
20142        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
20143        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
20144            return ActivityManager.USER_OP_IS_CURRENT;
20145        }
20146
20147        final UserState uss = mStartedUsers.get(userId);
20148        if (uss == null) {
20149            // User is not started, nothing to do...  but we do need to
20150            // callback if requested.
20151            if (callback != null) {
20152                mHandler.post(new Runnable() {
20153                    @Override
20154                    public void run() {
20155                        try {
20156                            callback.userStopped(userId);
20157                        } catch (RemoteException e) {
20158                        }
20159                    }
20160                });
20161            }
20162            return ActivityManager.USER_OP_SUCCESS;
20163        }
20164
20165        if (callback != null) {
20166            uss.mStopCallbacks.add(callback);
20167        }
20168
20169        if (uss.mState != UserState.STATE_STOPPING
20170                && uss.mState != UserState.STATE_SHUTDOWN) {
20171            uss.mState = UserState.STATE_STOPPING;
20172            updateStartedUserArrayLocked();
20173
20174            long ident = Binder.clearCallingIdentity();
20175            try {
20176                // We are going to broadcast ACTION_USER_STOPPING and then
20177                // once that is done send a final ACTION_SHUTDOWN and then
20178                // stop the user.
20179                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
20180                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20181                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20182                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
20183                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
20184                // This is the result receiver for the final shutdown broadcast.
20185                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
20186                    @Override
20187                    public void performReceive(Intent intent, int resultCode, String data,
20188                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
20189                        finishUserStop(uss);
20190                    }
20191                };
20192                // This is the result receiver for the initial stopping broadcast.
20193                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
20194                    @Override
20195                    public void performReceive(Intent intent, int resultCode, String data,
20196                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
20197                        // On to the next.
20198                        synchronized (ActivityManagerService.this) {
20199                            if (uss.mState != UserState.STATE_STOPPING) {
20200                                // Whoops, we are being started back up.  Abort, abort!
20201                                return;
20202                            }
20203                            uss.mState = UserState.STATE_SHUTDOWN;
20204                        }
20205                        mBatteryStatsService.noteEvent(
20206                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
20207                                Integer.toString(userId), userId);
20208                        mSystemServiceManager.stopUser(userId);
20209                        broadcastIntentLocked(null, null, shutdownIntent,
20210                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
20211                                null, true, false, MY_PID, Process.SYSTEM_UID, userId);
20212                    }
20213                };
20214                // Kick things off.
20215                broadcastIntentLocked(null, null, stoppingIntent,
20216                        null, stoppingReceiver, 0, null, null,
20217                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
20218                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
20219            } finally {
20220                Binder.restoreCallingIdentity(ident);
20221            }
20222        }
20223
20224        return ActivityManager.USER_OP_SUCCESS;
20225    }
20226
20227    void finishUserStop(UserState uss) {
20228        final int userId = uss.mHandle.getIdentifier();
20229        boolean stopped;
20230        ArrayList<IStopUserCallback> callbacks;
20231        synchronized (this) {
20232            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
20233            if (mStartedUsers.get(userId) != uss) {
20234                stopped = false;
20235            } else if (uss.mState != UserState.STATE_SHUTDOWN) {
20236                stopped = false;
20237            } else {
20238                stopped = true;
20239                // User can no longer run.
20240                mStartedUsers.remove(userId);
20241                mUserLru.remove(Integer.valueOf(userId));
20242                updateStartedUserArrayLocked();
20243
20244                // Clean up all state and processes associated with the user.
20245                // Kill all the processes for the user.
20246                forceStopUserLocked(userId, "finish user");
20247            }
20248
20249            // Explicitly remove the old information in mRecentTasks.
20250            mRecentTasks.removeTasksForUserLocked(userId);
20251        }
20252
20253        for (int i=0; i<callbacks.size(); i++) {
20254            try {
20255                if (stopped) callbacks.get(i).userStopped(userId);
20256                else callbacks.get(i).userStopAborted(userId);
20257            } catch (RemoteException e) {
20258            }
20259        }
20260
20261        if (stopped) {
20262            mSystemServiceManager.cleanupUser(userId);
20263            synchronized (this) {
20264                mStackSupervisor.removeUserLocked(userId);
20265            }
20266        }
20267    }
20268
20269    @Override
20270    public UserInfo getCurrentUser() {
20271        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
20272                != PackageManager.PERMISSION_GRANTED) && (
20273                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20274                != PackageManager.PERMISSION_GRANTED)) {
20275            String msg = "Permission Denial: getCurrentUser() from pid="
20276                    + Binder.getCallingPid()
20277                    + ", uid=" + Binder.getCallingUid()
20278                    + " requires " + INTERACT_ACROSS_USERS;
20279            Slog.w(TAG, msg);
20280            throw new SecurityException(msg);
20281        }
20282        synchronized (this) {
20283            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20284            return getUserManagerLocked().getUserInfo(userId);
20285        }
20286    }
20287
20288    int getCurrentUserIdLocked() {
20289        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20290    }
20291
20292    @Override
20293    public boolean isUserRunning(int userId, boolean orStopped) {
20294        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20295                != PackageManager.PERMISSION_GRANTED) {
20296            String msg = "Permission Denial: isUserRunning() from pid="
20297                    + Binder.getCallingPid()
20298                    + ", uid=" + Binder.getCallingUid()
20299                    + " requires " + INTERACT_ACROSS_USERS;
20300            Slog.w(TAG, msg);
20301            throw new SecurityException(msg);
20302        }
20303        synchronized (this) {
20304            return isUserRunningLocked(userId, orStopped);
20305        }
20306    }
20307
20308    boolean isUserRunningLocked(int userId, boolean orStopped) {
20309        UserState state = mStartedUsers.get(userId);
20310        if (state == null) {
20311            return false;
20312        }
20313        if (orStopped) {
20314            return true;
20315        }
20316        return state.mState != UserState.STATE_STOPPING
20317                && state.mState != UserState.STATE_SHUTDOWN;
20318    }
20319
20320    @Override
20321    public int[] getRunningUserIds() {
20322        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20323                != PackageManager.PERMISSION_GRANTED) {
20324            String msg = "Permission Denial: isUserRunning() from pid="
20325                    + Binder.getCallingPid()
20326                    + ", uid=" + Binder.getCallingUid()
20327                    + " requires " + INTERACT_ACROSS_USERS;
20328            Slog.w(TAG, msg);
20329            throw new SecurityException(msg);
20330        }
20331        synchronized (this) {
20332            return mStartedUserArray;
20333        }
20334    }
20335
20336    private void updateStartedUserArrayLocked() {
20337        int num = 0;
20338        for (int i=0; i<mStartedUsers.size();  i++) {
20339            UserState uss = mStartedUsers.valueAt(i);
20340            // This list does not include stopping users.
20341            if (uss.mState != UserState.STATE_STOPPING
20342                    && uss.mState != UserState.STATE_SHUTDOWN) {
20343                num++;
20344            }
20345        }
20346        mStartedUserArray = new int[num];
20347        num = 0;
20348        for (int i=0; i<mStartedUsers.size();  i++) {
20349            UserState uss = mStartedUsers.valueAt(i);
20350            if (uss.mState != UserState.STATE_STOPPING
20351                    && uss.mState != UserState.STATE_SHUTDOWN) {
20352                mStartedUserArray[num] = mStartedUsers.keyAt(i);
20353                num++;
20354            }
20355        }
20356    }
20357
20358    @Override
20359    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20360        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20361                != PackageManager.PERMISSION_GRANTED) {
20362            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
20363                    + Binder.getCallingPid()
20364                    + ", uid=" + Binder.getCallingUid()
20365                    + " requires " + INTERACT_ACROSS_USERS_FULL;
20366            Slog.w(TAG, msg);
20367            throw new SecurityException(msg);
20368        }
20369
20370        mUserSwitchObservers.register(observer);
20371    }
20372
20373    @Override
20374    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20375        mUserSwitchObservers.unregister(observer);
20376    }
20377
20378    int[] getUsersLocked() {
20379        UserManagerService ums = getUserManagerLocked();
20380        return ums != null ? ums.getUserIds() : new int[] { 0 };
20381    }
20382
20383    UserManagerService getUserManagerLocked() {
20384        if (mUserManager == null) {
20385            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
20386            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
20387        }
20388        return mUserManager;
20389    }
20390
20391    private int applyUserId(int uid, int userId) {
20392        return UserHandle.getUid(userId, uid);
20393    }
20394
20395    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20396        if (info == null) return null;
20397        ApplicationInfo newInfo = new ApplicationInfo(info);
20398        newInfo.uid = applyUserId(info.uid, userId);
20399        newInfo.dataDir = Environment
20400                .getDataUserPackageDirectory(info.volumeUuid, userId, info.packageName)
20401                .getAbsolutePath();
20402        return newInfo;
20403    }
20404
20405    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20406        if (aInfo == null
20407                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20408            return aInfo;
20409        }
20410
20411        ActivityInfo info = new ActivityInfo(aInfo);
20412        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20413        return info;
20414    }
20415
20416    private final class LocalService extends ActivityManagerInternal {
20417        @Override
20418        public void onWakefulnessChanged(int wakefulness) {
20419            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20420        }
20421
20422        @Override
20423        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20424                String processName, String abiOverride, int uid, Runnable crashHandler) {
20425            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20426                    processName, abiOverride, uid, crashHandler);
20427        }
20428
20429        @Override
20430        public SleepToken acquireSleepToken(String tag) {
20431            Preconditions.checkNotNull(tag);
20432
20433            synchronized (ActivityManagerService.this) {
20434                SleepTokenImpl token = new SleepTokenImpl(tag);
20435                mSleepTokens.add(token);
20436                updateSleepIfNeededLocked();
20437                return token;
20438            }
20439        }
20440
20441        @Override
20442        public ComponentName getHomeActivityForUser(int userId) {
20443            synchronized (ActivityManagerService.this) {
20444                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20445                return homeActivity == null ? null : homeActivity.realActivity;
20446            }
20447        }
20448    }
20449
20450    private final class SleepTokenImpl extends SleepToken {
20451        private final String mTag;
20452        private final long mAcquireTime;
20453
20454        public SleepTokenImpl(String tag) {
20455            mTag = tag;
20456            mAcquireTime = SystemClock.uptimeMillis();
20457        }
20458
20459        @Override
20460        public void release() {
20461            synchronized (ActivityManagerService.this) {
20462                if (mSleepTokens.remove(this)) {
20463                    updateSleepIfNeededLocked();
20464                }
20465            }
20466        }
20467
20468        @Override
20469        public String toString() {
20470            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20471        }
20472    }
20473
20474    /**
20475     * An implementation of IAppTask, that allows an app to manage its own tasks via
20476     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
20477     * only the process that calls getAppTasks() can call the AppTask methods.
20478     */
20479    class AppTaskImpl extends IAppTask.Stub {
20480        private int mTaskId;
20481        private int mCallingUid;
20482
20483        public AppTaskImpl(int taskId, int callingUid) {
20484            mTaskId = taskId;
20485            mCallingUid = callingUid;
20486        }
20487
20488        private void checkCaller() {
20489            if (mCallingUid != Binder.getCallingUid()) {
20490                throw new SecurityException("Caller " + mCallingUid
20491                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
20492            }
20493        }
20494
20495        @Override
20496        public void finishAndRemoveTask() {
20497            checkCaller();
20498
20499            synchronized (ActivityManagerService.this) {
20500                long origId = Binder.clearCallingIdentity();
20501                try {
20502                    if (!removeTaskByIdLocked(mTaskId, false)) {
20503                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20504                    }
20505                } finally {
20506                    Binder.restoreCallingIdentity(origId);
20507                }
20508            }
20509        }
20510
20511        @Override
20512        public ActivityManager.RecentTaskInfo getTaskInfo() {
20513            checkCaller();
20514
20515            synchronized (ActivityManagerService.this) {
20516                long origId = Binder.clearCallingIdentity();
20517                try {
20518                    TaskRecord tr = mRecentTasks.taskForIdLocked(mTaskId);
20519                    if (tr == null) {
20520                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20521                    }
20522                    return createRecentTaskInfoFromTaskRecord(tr);
20523                } finally {
20524                    Binder.restoreCallingIdentity(origId);
20525                }
20526            }
20527        }
20528
20529        @Override
20530        public void moveToFront() {
20531            checkCaller();
20532            // Will bring task to front if it already has a root activity.
20533            startActivityFromRecentsInner(mTaskId, null);
20534        }
20535
20536        @Override
20537        public int startActivity(IBinder whoThread, String callingPackage,
20538                Intent intent, String resolvedType, Bundle options) {
20539            checkCaller();
20540
20541            int callingUser = UserHandle.getCallingUserId();
20542            TaskRecord tr;
20543            IApplicationThread appThread;
20544            synchronized (ActivityManagerService.this) {
20545                tr = mRecentTasks.taskForIdLocked(mTaskId);
20546                if (tr == null) {
20547                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20548                }
20549                appThread = ApplicationThreadNative.asInterface(whoThread);
20550                if (appThread == null) {
20551                    throw new IllegalArgumentException("Bad app thread " + appThread);
20552                }
20553            }
20554            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
20555                    resolvedType, null, null, null, null, 0, 0, null, null,
20556                    null, options, callingUser, null, tr);
20557        }
20558
20559        @Override
20560        public void setExcludeFromRecents(boolean exclude) {
20561            checkCaller();
20562
20563            synchronized (ActivityManagerService.this) {
20564                long origId = Binder.clearCallingIdentity();
20565                try {
20566                    TaskRecord tr = mRecentTasks.taskForIdLocked(mTaskId);
20567                    if (tr == null) {
20568                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20569                    }
20570                    Intent intent = tr.getBaseIntent();
20571                    if (exclude) {
20572                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20573                    } else {
20574                        intent.setFlags(intent.getFlags()
20575                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20576                    }
20577                } finally {
20578                    Binder.restoreCallingIdentity(origId);
20579                }
20580            }
20581        }
20582    }
20583}
20584