ActivityManagerService.java revision 6ad2d66072795dd9836350b273dcde52910ab4c3
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static com.android.server.am.ActivityManagerDebugConfig.*;
31import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
32import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
33import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
34import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
35import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
36import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
37import static org.xmlpull.v1.XmlPullParser.START_TAG;
38
39import android.Manifest;
40import android.app.AppOpsManager;
41import android.app.ApplicationThreadNative;
42import android.app.BroadcastOptions;
43import android.app.IActivityContainer;
44import android.app.IActivityContainerCallback;
45import android.app.IAppTask;
46import android.app.ITaskStackListener;
47import android.app.ProfilerInfo;
48import android.app.assist.AssistContent;
49import android.app.assist.AssistStructure;
50import android.app.usage.UsageEvents;
51import android.app.usage.UsageStatsManagerInternal;
52import android.appwidget.AppWidgetManager;
53import android.content.pm.PermissionInfo;
54import android.content.res.Resources;
55import android.graphics.Bitmap;
56import android.graphics.Point;
57import android.graphics.Rect;
58import android.os.BatteryStats;
59import android.os.PersistableBundle;
60import android.os.PowerManager;
61import android.os.Trace;
62import android.os.TransactionTooLargeException;
63import android.os.WorkSource;
64import android.os.storage.IMountService;
65import android.os.storage.MountServiceInternal;
66import android.os.storage.StorageManager;
67import android.service.voice.IVoiceInteractionSession;
68import android.service.voice.VoiceInteractionSession;
69import android.util.ArrayMap;
70import android.util.ArraySet;
71import android.util.DebugUtils;
72import android.util.SparseIntArray;
73import android.view.Display;
74
75import com.android.internal.R;
76import com.android.internal.annotations.GuardedBy;
77import com.android.internal.app.AssistUtils;
78import com.android.internal.app.DumpHeapActivity;
79import com.android.internal.app.IAppOpsService;
80import com.android.internal.app.IVoiceInteractor;
81import com.android.internal.app.ProcessMap;
82import com.android.internal.app.ProcessStats;
83import com.android.internal.os.BackgroundThread;
84import com.android.internal.os.BatteryStatsImpl;
85import com.android.internal.os.IResultReceiver;
86import com.android.internal.os.ProcessCpuTracker;
87import com.android.internal.os.TransferPipe;
88import com.android.internal.os.Zygote;
89import com.android.internal.util.ArrayUtils;
90import com.android.internal.util.FastPrintWriter;
91import com.android.internal.util.FastXmlSerializer;
92import com.android.internal.util.MemInfoReader;
93import com.android.internal.util.Preconditions;
94import com.android.server.AppOpsService;
95import com.android.server.AttributeCache;
96import com.android.server.DeviceIdleController;
97import com.android.server.IntentResolver;
98import com.android.server.LocalServices;
99import com.android.server.ServiceThread;
100import com.android.server.SystemService;
101import com.android.server.SystemServiceManager;
102import com.android.server.Watchdog;
103import com.android.server.am.ActivityStack.ActivityState;
104import com.android.server.firewall.IntentFirewall;
105import com.android.server.pm.Installer;
106import com.android.server.pm.UserManagerService;
107import com.android.server.statusbar.StatusBarManagerInternal;
108import com.android.server.wm.AppTransition;
109import com.android.server.wm.WindowManagerService;
110import com.google.android.collect.Lists;
111import com.google.android.collect.Maps;
112
113import libcore.io.IoUtils;
114import libcore.util.EmptyArray;
115
116import org.xmlpull.v1.XmlPullParser;
117import org.xmlpull.v1.XmlPullParserException;
118import org.xmlpull.v1.XmlSerializer;
119
120import android.app.Activity;
121import android.app.ActivityManager;
122import android.app.ActivityManager.RunningTaskInfo;
123import android.app.ActivityManager.StackInfo;
124import android.app.ActivityManagerInternal;
125import android.app.ActivityManagerInternal.SleepToken;
126import android.app.ActivityManagerNative;
127import android.app.ActivityOptions;
128import android.app.ActivityThread;
129import android.app.AlertDialog;
130import android.app.AppGlobals;
131import android.app.ApplicationErrorReport;
132import android.app.Dialog;
133import android.app.IActivityController;
134import android.app.IApplicationThread;
135import android.app.IInstrumentationWatcher;
136import android.app.INotificationManager;
137import android.app.IProcessObserver;
138import android.app.IServiceConnection;
139import android.app.IStopUserCallback;
140import android.app.IUidObserver;
141import android.app.IUiAutomationConnection;
142import android.app.IUserSwitchObserver;
143import android.app.Instrumentation;
144import android.app.Notification;
145import android.app.NotificationManager;
146import android.app.PendingIntent;
147import android.app.backup.IBackupManager;
148import android.app.admin.DevicePolicyManager;
149import android.content.ActivityNotFoundException;
150import android.content.BroadcastReceiver;
151import android.content.ClipData;
152import android.content.ComponentCallbacks2;
153import android.content.ComponentName;
154import android.content.ContentProvider;
155import android.content.ContentResolver;
156import android.content.Context;
157import android.content.DialogInterface;
158import android.content.IContentProvider;
159import android.content.IIntentReceiver;
160import android.content.IIntentSender;
161import android.content.Intent;
162import android.content.IntentFilter;
163import android.content.IntentSender;
164import android.content.pm.ActivityInfo;
165import android.content.pm.ApplicationInfo;
166import android.content.pm.ConfigurationInfo;
167import android.content.pm.IPackageDataObserver;
168import android.content.pm.IPackageManager;
169import android.content.pm.InstrumentationInfo;
170import android.content.pm.PackageInfo;
171import android.content.pm.PackageManager;
172import android.content.pm.ParceledListSlice;
173import android.content.pm.UserInfo;
174import android.content.pm.PackageManager.NameNotFoundException;
175import android.content.pm.PathPermission;
176import android.content.pm.ProviderInfo;
177import android.content.pm.ResolveInfo;
178import android.content.pm.ServiceInfo;
179import android.content.res.CompatibilityInfo;
180import android.content.res.Configuration;
181import android.net.Proxy;
182import android.net.ProxyInfo;
183import android.net.Uri;
184import android.os.Binder;
185import android.os.Build;
186import android.os.Bundle;
187import android.os.Debug;
188import android.os.DropBoxManager;
189import android.os.Environment;
190import android.os.FactoryTest;
191import android.os.FileObserver;
192import android.os.FileUtils;
193import android.os.Handler;
194import android.os.IBinder;
195import android.os.IPermissionController;
196import android.os.IProcessInfoService;
197import android.os.IRemoteCallback;
198import android.os.IUserManager;
199import android.os.Looper;
200import android.os.Message;
201import android.os.Parcel;
202import android.os.ParcelFileDescriptor;
203import android.os.PowerManagerInternal;
204import android.os.Process;
205import android.os.RemoteCallbackList;
206import android.os.RemoteException;
207import android.os.SELinux;
208import android.os.ServiceManager;
209import android.os.StrictMode;
210import android.os.SystemClock;
211import android.os.SystemProperties;
212import android.os.UpdateLock;
213import android.os.UserHandle;
214import android.os.UserManager;
215import android.provider.Settings;
216import android.text.format.DateUtils;
217import android.text.format.Time;
218import android.util.AtomicFile;
219import android.util.EventLog;
220import android.util.Log;
221import android.util.Pair;
222import android.util.PrintWriterPrinter;
223import android.util.Slog;
224import android.util.SparseArray;
225import android.util.TimeUtils;
226import android.util.Xml;
227import android.view.Gravity;
228import android.view.LayoutInflater;
229import android.view.View;
230import android.view.WindowManager;
231
232import dalvik.system.VMRuntime;
233
234import java.io.BufferedInputStream;
235import java.io.BufferedOutputStream;
236import java.io.DataInputStream;
237import java.io.DataOutputStream;
238import java.io.File;
239import java.io.FileDescriptor;
240import java.io.FileInputStream;
241import java.io.FileNotFoundException;
242import java.io.FileOutputStream;
243import java.io.IOException;
244import java.io.InputStreamReader;
245import java.io.PrintWriter;
246import java.io.StringWriter;
247import java.lang.ref.WeakReference;
248import java.nio.charset.StandardCharsets;
249import java.util.ArrayList;
250import java.util.Arrays;
251import java.util.Collections;
252import java.util.Comparator;
253import java.util.HashMap;
254import java.util.HashSet;
255import java.util.Iterator;
256import java.util.List;
257import java.util.Locale;
258import java.util.Map;
259import java.util.Set;
260import java.util.concurrent.atomic.AtomicBoolean;
261import java.util.concurrent.atomic.AtomicLong;
262
263public final class ActivityManagerService extends ActivityManagerNative
264        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
265
266    // File that stores last updated system version and called preboot receivers
267    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
268
269    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
270    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
271    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
272    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
273    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
274    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
275    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
276    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
277    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
278    private static final String TAG_LRU = TAG + POSTFIX_LRU;
279    private static final String TAG_MU = TAG + POSTFIX_MU;
280    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
281    private static final String TAG_POWER = TAG + POSTFIX_POWER;
282    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
283    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
284    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
285    private static final String TAG_PSS = TAG + POSTFIX_PSS;
286    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
287    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
288    private static final String TAG_STACK = TAG + POSTFIX_STACK;
289    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
290    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
291    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
292    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
293    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
294
295    /** Control over CPU and battery monitoring */
296    // write battery stats every 30 minutes.
297    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
298    static final boolean MONITOR_CPU_USAGE = true;
299    // don't sample cpu less than every 5 seconds.
300    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
301    // wait possibly forever for next cpu sample.
302    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
303    static final boolean MONITOR_THREAD_CPU_USAGE = false;
304
305    // The flags that are set for all calls we make to the package manager.
306    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
307
308    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
309
310    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
311
312    // Amount of time after a call to stopAppSwitches() during which we will
313    // prevent further untrusted switches from happening.
314    static final long APP_SWITCH_DELAY_TIME = 5*1000;
315
316    // How long we wait for a launched process to attach to the activity manager
317    // before we decide it's never going to come up for real.
318    static final int PROC_START_TIMEOUT = 10*1000;
319
320    // How long we wait for a launched process to attach to the activity manager
321    // before we decide it's never going to come up for real, when the process was
322    // started with a wrapper for instrumentation (such as Valgrind) because it
323    // could take much longer than usual.
324    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
325
326    // How long to wait after going idle before forcing apps to GC.
327    static final int GC_TIMEOUT = 5*1000;
328
329    // The minimum amount of time between successive GC requests for a process.
330    static final int GC_MIN_INTERVAL = 60*1000;
331
332    // The minimum amount of time between successive PSS requests for a process.
333    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
334
335    // The minimum amount of time between successive PSS requests for a process
336    // when the request is due to the memory state being lowered.
337    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
338
339    // The rate at which we check for apps using excessive power -- 15 mins.
340    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
341
342    // The minimum sample duration we will allow before deciding we have
343    // enough data on wake locks to start killing things.
344    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
345
346    // The minimum sample duration we will allow before deciding we have
347    // enough data on CPU usage to start killing things.
348    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
349
350    // How long we allow a receiver to run before giving up on it.
351    static final int BROADCAST_FG_TIMEOUT = 10*1000;
352    static final int BROADCAST_BG_TIMEOUT = 60*1000;
353
354    // How long we wait until we timeout on key dispatching.
355    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
356
357    // How long we wait until we timeout on key dispatching during instrumentation.
358    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
359
360    // Amount of time we wait for observers to handle a user switch before
361    // giving up on them and unfreezing the screen.
362    static final int USER_SWITCH_TIMEOUT = 2*1000;
363
364    // This is the amount of time an app needs to be running a foreground service before
365    // we will consider it to be doing interaction for usage stats.
366    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
367
368    // Maximum number of users we allow to be running at a time.
369    static final int MAX_RUNNING_USERS = 3;
370
371    // How long to wait in getAssistContextExtras for the activity and foreground services
372    // to respond with the result.
373    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
374
375    // How long top wait when going through the modern assist (which doesn't need to block
376    // on getting this result before starting to launch its UI).
377    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
378
379    // Maximum number of persisted Uri grants a package is allowed
380    static final int MAX_PERSISTED_URI_GRANTS = 128;
381
382    static final int MY_PID = Process.myPid();
383
384    static final String[] EMPTY_STRING_ARRAY = new String[0];
385
386    // How many bytes to write into the dropbox log before truncating
387    static final int DROPBOX_MAX_SIZE = 256 * 1024;
388
389    // Access modes for handleIncomingUser.
390    static final int ALLOW_NON_FULL = 0;
391    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
392    static final int ALLOW_FULL_ONLY = 2;
393
394    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
395
396    // Delay in notifying task stack change listeners (in millis)
397    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
398
399    // Necessary ApplicationInfo flags to mark an app as persistent
400    private static final int PERSISTENT_MASK =
401            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
402
403    /** All system services */
404    SystemServiceManager mSystemServiceManager;
405
406    private Installer mInstaller;
407
408    /** Run all ActivityStacks through this */
409    ActivityStackSupervisor mStackSupervisor;
410
411    /** Task stack change listeners. */
412    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
413            new RemoteCallbackList<ITaskStackListener>();
414
415    public IntentFirewall mIntentFirewall;
416
417    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
418    // default actuion automatically.  Important for devices without direct input
419    // devices.
420    private boolean mShowDialogs = true;
421
422    BroadcastQueue mFgBroadcastQueue;
423    BroadcastQueue mBgBroadcastQueue;
424    // Convenient for easy iteration over the queues. Foreground is first
425    // so that dispatch of foreground broadcasts gets precedence.
426    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
427
428    BroadcastQueue broadcastQueueForIntent(Intent intent) {
429        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
430        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
431                "Broadcast intent " + intent + " on "
432                + (isFg ? "foreground" : "background") + " queue");
433        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
434    }
435
436    /**
437     * Activity we have told the window manager to have key focus.
438     */
439    ActivityRecord mFocusedActivity = null;
440
441    /**
442     * User id of the last activity mFocusedActivity was set to.
443     */
444    private int mLastFocusedUserId;
445
446    /**
447     * If non-null, we are tracking the time the user spends in the currently focused app.
448     */
449    private AppTimeTracker mCurAppTimeTracker;
450
451    /**
452     * List of intents that were used to start the most recent tasks.
453     */
454    private final RecentTasks mRecentTasks;
455
456    /**
457     * For addAppTask: cached of the last activity component that was added.
458     */
459    ComponentName mLastAddedTaskComponent;
460
461    /**
462     * For addAppTask: cached of the last activity uid that was added.
463     */
464    int mLastAddedTaskUid;
465
466    /**
467     * For addAppTask: cached of the last ActivityInfo that was added.
468     */
469    ActivityInfo mLastAddedTaskActivity;
470
471    /**
472     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
473     */
474    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
475
476    /**
477     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
478     */
479    String mDeviceOwnerName;
480
481    public class PendingAssistExtras extends Binder implements Runnable {
482        public final ActivityRecord activity;
483        public final Bundle extras;
484        public final Intent intent;
485        public final String hint;
486        public final IResultReceiver receiver;
487        public final int userHandle;
488        public boolean haveResult = false;
489        public Bundle result = null;
490        public AssistStructure structure = null;
491        public AssistContent content = null;
492        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
493                String _hint, IResultReceiver _receiver, int _userHandle) {
494            activity = _activity;
495            extras = _extras;
496            intent = _intent;
497            hint = _hint;
498            receiver = _receiver;
499            userHandle = _userHandle;
500        }
501        @Override
502        public void run() {
503            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
504            synchronized (this) {
505                haveResult = true;
506                notifyAll();
507            }
508            pendingAssistExtrasTimedOut(this);
509        }
510    }
511
512    final ArrayList<PendingAssistExtras> mPendingAssistExtras
513            = new ArrayList<PendingAssistExtras>();
514
515    /**
516     * Process management.
517     */
518    final ProcessList mProcessList = new ProcessList();
519
520    /**
521     * All of the applications we currently have running organized by name.
522     * The keys are strings of the application package name (as
523     * returned by the package manager), and the keys are ApplicationRecord
524     * objects.
525     */
526    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
527
528    /**
529     * Tracking long-term execution of processes to look for abuse and other
530     * bad app behavior.
531     */
532    final ProcessStatsService mProcessStats;
533
534    /**
535     * The currently running isolated processes.
536     */
537    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
538
539    /**
540     * Counter for assigning isolated process uids, to avoid frequently reusing the
541     * same ones.
542     */
543    int mNextIsolatedProcessUid = 0;
544
545    /**
546     * The currently running heavy-weight process, if any.
547     */
548    ProcessRecord mHeavyWeightProcess = null;
549
550    /**
551     * The last time that various processes have crashed.
552     */
553    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
554
555    /**
556     * Information about a process that is currently marked as bad.
557     */
558    static final class BadProcessInfo {
559        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
560            this.time = time;
561            this.shortMsg = shortMsg;
562            this.longMsg = longMsg;
563            this.stack = stack;
564        }
565
566        final long time;
567        final String shortMsg;
568        final String longMsg;
569        final String stack;
570    }
571
572    /**
573     * Set of applications that we consider to be bad, and will reject
574     * incoming broadcasts from (which the user has no control over).
575     * Processes are added to this set when they have crashed twice within
576     * a minimum amount of time; they are removed from it when they are
577     * later restarted (hopefully due to some user action).  The value is the
578     * time it was added to the list.
579     */
580    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
581
582    /**
583     * All of the processes we currently have running organized by pid.
584     * The keys are the pid running the application.
585     *
586     * <p>NOTE: This object is protected by its own lock, NOT the global
587     * activity manager lock!
588     */
589    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
590
591    /**
592     * All of the processes that have been forced to be foreground.  The key
593     * is the pid of the caller who requested it (we hold a death
594     * link on it).
595     */
596    abstract class ForegroundToken implements IBinder.DeathRecipient {
597        int pid;
598        IBinder token;
599    }
600    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
601
602    /**
603     * List of records for processes that someone had tried to start before the
604     * system was ready.  We don't start them at that point, but ensure they
605     * are started by the time booting is complete.
606     */
607    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
608
609    /**
610     * List of persistent applications that are in the process
611     * of being started.
612     */
613    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
614
615    /**
616     * Processes that are being forcibly torn down.
617     */
618    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
619
620    /**
621     * List of running applications, sorted by recent usage.
622     * The first entry in the list is the least recently used.
623     */
624    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
625
626    /**
627     * Where in mLruProcesses that the processes hosting activities start.
628     */
629    int mLruProcessActivityStart = 0;
630
631    /**
632     * Where in mLruProcesses that the processes hosting services start.
633     * This is after (lower index) than mLruProcessesActivityStart.
634     */
635    int mLruProcessServiceStart = 0;
636
637    /**
638     * List of processes that should gc as soon as things are idle.
639     */
640    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
641
642    /**
643     * Processes we want to collect PSS data from.
644     */
645    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
646
647    /**
648     * Last time we requested PSS data of all processes.
649     */
650    long mLastFullPssTime = SystemClock.uptimeMillis();
651
652    /**
653     * If set, the next time we collect PSS data we should do a full collection
654     * with data from native processes and the kernel.
655     */
656    boolean mFullPssPending = false;
657
658    /**
659     * This is the process holding what we currently consider to be
660     * the "home" activity.
661     */
662    ProcessRecord mHomeProcess;
663
664    /**
665     * This is the process holding the activity the user last visited that
666     * is in a different process from the one they are currently in.
667     */
668    ProcessRecord mPreviousProcess;
669
670    /**
671     * The time at which the previous process was last visible.
672     */
673    long mPreviousProcessVisibleTime;
674
675    /**
676     * Track all uids that have actively running processes.
677     */
678    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
679
680    /**
681     * Which users have been started, so are allowed to run code.
682     */
683    final SparseArray<UserState> mStartedUsers = new SparseArray<>();
684
685    /**
686     * LRU list of history of current users.  Most recently current is at the end.
687     */
688    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
689
690    /**
691     * Constant array of the users that are currently started.
692     */
693    int[] mStartedUserArray = new int[] { 0 };
694
695    /**
696     * Registered observers of the user switching mechanics.
697     */
698    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
699            = new RemoteCallbackList<IUserSwitchObserver>();
700
701    /**
702     * Currently active user switch.
703     */
704    Object mCurUserSwitchCallback;
705
706    /**
707     * Packages that the user has asked to have run in screen size
708     * compatibility mode instead of filling the screen.
709     */
710    final CompatModePackages mCompatModePackages;
711
712    /**
713     * Set of IntentSenderRecord objects that are currently active.
714     */
715    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
716            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
717
718    /**
719     * Fingerprints (hashCode()) of stack traces that we've
720     * already logged DropBox entries for.  Guarded by itself.  If
721     * something (rogue user app) forces this over
722     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
723     */
724    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
725    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
726
727    /**
728     * Strict Mode background batched logging state.
729     *
730     * The string buffer is guarded by itself, and its lock is also
731     * used to determine if another batched write is already
732     * in-flight.
733     */
734    private final StringBuilder mStrictModeBuffer = new StringBuilder();
735
736    /**
737     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
738     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
739     */
740    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
741
742    /**
743     * Resolver for broadcast intents to registered receivers.
744     * Holds BroadcastFilter (subclass of IntentFilter).
745     */
746    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
747            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
748        @Override
749        protected boolean allowFilterResult(
750                BroadcastFilter filter, List<BroadcastFilter> dest) {
751            IBinder target = filter.receiverList.receiver.asBinder();
752            for (int i = dest.size() - 1; i >= 0; i--) {
753                if (dest.get(i).receiverList.receiver.asBinder() == target) {
754                    return false;
755                }
756            }
757            return true;
758        }
759
760        @Override
761        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
762            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
763                    || userId == filter.owningUserId) {
764                return super.newResult(filter, match, userId);
765            }
766            return null;
767        }
768
769        @Override
770        protected BroadcastFilter[] newArray(int size) {
771            return new BroadcastFilter[size];
772        }
773
774        @Override
775        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
776            return packageName.equals(filter.packageName);
777        }
778    };
779
780    /**
781     * State of all active sticky broadcasts per user.  Keys are the action of the
782     * sticky Intent, values are an ArrayList of all broadcasted intents with
783     * that action (which should usually be one).  The SparseArray is keyed
784     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
785     * for stickies that are sent to all users.
786     */
787    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
788            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
789
790    final ActiveServices mServices;
791
792    final static class Association {
793        final int mSourceUid;
794        final String mSourceProcess;
795        final int mTargetUid;
796        final ComponentName mTargetComponent;
797        final String mTargetProcess;
798
799        int mCount;
800        long mTime;
801
802        int mNesting;
803        long mStartTime;
804
805        Association(int sourceUid, String sourceProcess, int targetUid,
806                ComponentName targetComponent, String targetProcess) {
807            mSourceUid = sourceUid;
808            mSourceProcess = sourceProcess;
809            mTargetUid = targetUid;
810            mTargetComponent = targetComponent;
811            mTargetProcess = targetProcess;
812        }
813    }
814
815    /**
816     * When service association tracking is enabled, this is all of the associations we
817     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
818     * -> association data.
819     */
820    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
821            mAssociations = new SparseArray<>();
822    boolean mTrackingAssociations;
823
824    /**
825     * Backup/restore process management
826     */
827    String mBackupAppName = null;
828    BackupRecord mBackupTarget = null;
829
830    final ProviderMap mProviderMap;
831
832    /**
833     * List of content providers who have clients waiting for them.  The
834     * application is currently being launched and the provider will be
835     * removed from this list once it is published.
836     */
837    final ArrayList<ContentProviderRecord> mLaunchingProviders
838            = new ArrayList<ContentProviderRecord>();
839
840    /**
841     * File storing persisted {@link #mGrantedUriPermissions}.
842     */
843    private final AtomicFile mGrantFile;
844
845    /** XML constants used in {@link #mGrantFile} */
846    private static final String TAG_URI_GRANTS = "uri-grants";
847    private static final String TAG_URI_GRANT = "uri-grant";
848    private static final String ATTR_USER_HANDLE = "userHandle";
849    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
850    private static final String ATTR_TARGET_USER_ID = "targetUserId";
851    private static final String ATTR_SOURCE_PKG = "sourcePkg";
852    private static final String ATTR_TARGET_PKG = "targetPkg";
853    private static final String ATTR_URI = "uri";
854    private static final String ATTR_MODE_FLAGS = "modeFlags";
855    private static final String ATTR_CREATED_TIME = "createdTime";
856    private static final String ATTR_PREFIX = "prefix";
857
858    /**
859     * Global set of specific {@link Uri} permissions that have been granted.
860     * This optimized lookup structure maps from {@link UriPermission#targetUid}
861     * to {@link UriPermission#uri} to {@link UriPermission}.
862     */
863    @GuardedBy("this")
864    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
865            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
866
867    public static class GrantUri {
868        public final int sourceUserId;
869        public final Uri uri;
870        public boolean prefix;
871
872        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
873            this.sourceUserId = sourceUserId;
874            this.uri = uri;
875            this.prefix = prefix;
876        }
877
878        @Override
879        public int hashCode() {
880            int hashCode = 1;
881            hashCode = 31 * hashCode + sourceUserId;
882            hashCode = 31 * hashCode + uri.hashCode();
883            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
884            return hashCode;
885        }
886
887        @Override
888        public boolean equals(Object o) {
889            if (o instanceof GrantUri) {
890                GrantUri other = (GrantUri) o;
891                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
892                        && prefix == other.prefix;
893            }
894            return false;
895        }
896
897        @Override
898        public String toString() {
899            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
900            if (prefix) result += " [prefix]";
901            return result;
902        }
903
904        public String toSafeString() {
905            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
906            if (prefix) result += " [prefix]";
907            return result;
908        }
909
910        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
911            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
912                    ContentProvider.getUriWithoutUserId(uri), false);
913        }
914    }
915
916    CoreSettingsObserver mCoreSettingsObserver;
917
918    /**
919     * Thread-local storage used to carry caller permissions over through
920     * indirect content-provider access.
921     */
922    private class Identity {
923        public final IBinder token;
924        public final int pid;
925        public final int uid;
926
927        Identity(IBinder _token, int _pid, int _uid) {
928            token = _token;
929            pid = _pid;
930            uid = _uid;
931        }
932    }
933
934    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
935
936    /**
937     * All information we have collected about the runtime performance of
938     * any user id that can impact battery performance.
939     */
940    final BatteryStatsService mBatteryStatsService;
941
942    /**
943     * Information about component usage
944     */
945    UsageStatsManagerInternal mUsageStatsService;
946
947    /**
948     * Access to DeviceIdleController service.
949     */
950    DeviceIdleController.LocalService mLocalDeviceIdleController;
951
952    /**
953     * Information about and control over application operations
954     */
955    final AppOpsService mAppOpsService;
956
957    /**
958     * Save recent tasks information across reboots.
959     */
960    final TaskPersister mTaskPersister;
961
962    /**
963     * Current configuration information.  HistoryRecord objects are given
964     * a reference to this object to indicate which configuration they are
965     * currently running in, so this object must be kept immutable.
966     */
967    Configuration mConfiguration = new Configuration();
968
969    /**
970     * Current sequencing integer of the configuration, for skipping old
971     * configurations.
972     */
973    int mConfigurationSeq = 0;
974
975    /**
976     * Hardware-reported OpenGLES version.
977     */
978    final int GL_ES_VERSION;
979
980    /**
981     * List of initialization arguments to pass to all processes when binding applications to them.
982     * For example, references to the commonly used services.
983     */
984    HashMap<String, IBinder> mAppBindArgs;
985
986    /**
987     * Temporary to avoid allocations.  Protected by main lock.
988     */
989    final StringBuilder mStringBuilder = new StringBuilder(256);
990
991    /**
992     * Used to control how we initialize the service.
993     */
994    ComponentName mTopComponent;
995    String mTopAction = Intent.ACTION_MAIN;
996    String mTopData;
997    boolean mProcessesReady = false;
998    boolean mSystemReady = false;
999    boolean mBooting = false;
1000    boolean mCallFinishBooting = false;
1001    boolean mBootAnimationComplete = false;
1002    boolean mWaitingUpdate = false;
1003    boolean mDidUpdate = false;
1004    boolean mOnBattery = false;
1005    boolean mLaunchWarningShown = false;
1006
1007    Context mContext;
1008
1009    int mFactoryTest;
1010
1011    boolean mCheckedForSetup;
1012
1013    /**
1014     * The time at which we will allow normal application switches again,
1015     * after a call to {@link #stopAppSwitches()}.
1016     */
1017    long mAppSwitchesAllowedTime;
1018
1019    /**
1020     * This is set to true after the first switch after mAppSwitchesAllowedTime
1021     * is set; any switches after that will clear the time.
1022     */
1023    boolean mDidAppSwitch;
1024
1025    /**
1026     * Last time (in realtime) at which we checked for power usage.
1027     */
1028    long mLastPowerCheckRealtime;
1029
1030    /**
1031     * Last time (in uptime) at which we checked for power usage.
1032     */
1033    long mLastPowerCheckUptime;
1034
1035    /**
1036     * Set while we are wanting to sleep, to prevent any
1037     * activities from being started/resumed.
1038     */
1039    private boolean mSleeping = false;
1040
1041    /**
1042     * The process state used for processes that are running the top activities.
1043     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1044     */
1045    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1046
1047    /**
1048     * Set while we are running a voice interaction.  This overrides
1049     * sleeping while it is active.
1050     */
1051    private IVoiceInteractionSession mRunningVoice;
1052
1053    /**
1054     * For some direct access we need to power manager.
1055     */
1056    PowerManagerInternal mLocalPowerManager;
1057
1058    /**
1059     * We want to hold a wake lock while running a voice interaction session, since
1060     * this may happen with the screen off and we need to keep the CPU running to
1061     * be able to continue to interact with the user.
1062     */
1063    PowerManager.WakeLock mVoiceWakeLock;
1064
1065    /**
1066     * State of external calls telling us if the device is awake or asleep.
1067     */
1068    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1069
1070    /**
1071     * A list of tokens that cause the top activity to be put to sleep.
1072     * They are used by components that may hide and block interaction with underlying
1073     * activities.
1074     */
1075    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1076
1077    static final int LOCK_SCREEN_HIDDEN = 0;
1078    static final int LOCK_SCREEN_LEAVING = 1;
1079    static final int LOCK_SCREEN_SHOWN = 2;
1080    /**
1081     * State of external call telling us if the lock screen is shown.
1082     */
1083    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1084
1085    /**
1086     * Set if we are shutting down the system, similar to sleeping.
1087     */
1088    boolean mShuttingDown = false;
1089
1090    /**
1091     * Current sequence id for oom_adj computation traversal.
1092     */
1093    int mAdjSeq = 0;
1094
1095    /**
1096     * Current sequence id for process LRU updating.
1097     */
1098    int mLruSeq = 0;
1099
1100    /**
1101     * Keep track of the non-cached/empty process we last found, to help
1102     * determine how to distribute cached/empty processes next time.
1103     */
1104    int mNumNonCachedProcs = 0;
1105
1106    /**
1107     * Keep track of the number of cached hidden procs, to balance oom adj
1108     * distribution between those and empty procs.
1109     */
1110    int mNumCachedHiddenProcs = 0;
1111
1112    /**
1113     * Keep track of the number of service processes we last found, to
1114     * determine on the next iteration which should be B services.
1115     */
1116    int mNumServiceProcs = 0;
1117    int mNewNumAServiceProcs = 0;
1118    int mNewNumServiceProcs = 0;
1119
1120    /**
1121     * Allow the current computed overall memory level of the system to go down?
1122     * This is set to false when we are killing processes for reasons other than
1123     * memory management, so that the now smaller process list will not be taken as
1124     * an indication that memory is tighter.
1125     */
1126    boolean mAllowLowerMemLevel = false;
1127
1128    /**
1129     * The last computed memory level, for holding when we are in a state that
1130     * processes are going away for other reasons.
1131     */
1132    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1133
1134    /**
1135     * The last total number of process we have, to determine if changes actually look
1136     * like a shrinking number of process due to lower RAM.
1137     */
1138    int mLastNumProcesses;
1139
1140    /**
1141     * The uptime of the last time we performed idle maintenance.
1142     */
1143    long mLastIdleTime = SystemClock.uptimeMillis();
1144
1145    /**
1146     * Total time spent with RAM that has been added in the past since the last idle time.
1147     */
1148    long mLowRamTimeSinceLastIdle = 0;
1149
1150    /**
1151     * If RAM is currently low, when that horrible situation started.
1152     */
1153    long mLowRamStartTime = 0;
1154
1155    /**
1156     * For reporting to battery stats the current top application.
1157     */
1158    private String mCurResumedPackage = null;
1159    private int mCurResumedUid = -1;
1160
1161    /**
1162     * For reporting to battery stats the apps currently running foreground
1163     * service.  The ProcessMap is package/uid tuples; each of these contain
1164     * an array of the currently foreground processes.
1165     */
1166    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1167            = new ProcessMap<ArrayList<ProcessRecord>>();
1168
1169    /**
1170     * This is set if we had to do a delayed dexopt of an app before launching
1171     * it, to increase the ANR timeouts in that case.
1172     */
1173    boolean mDidDexOpt;
1174
1175    /**
1176     * Set if the systemServer made a call to enterSafeMode.
1177     */
1178    boolean mSafeMode;
1179
1180    /**
1181     * If true, we are running under a test environment so will sample PSS from processes
1182     * much more rapidly to try to collect better data when the tests are rapidly
1183     * running through apps.
1184     */
1185    boolean mTestPssMode = false;
1186
1187    String mDebugApp = null;
1188    boolean mWaitForDebugger = false;
1189    boolean mDebugTransient = false;
1190    String mOrigDebugApp = null;
1191    boolean mOrigWaitForDebugger = false;
1192    boolean mAlwaysFinishActivities = false;
1193    IActivityController mController = null;
1194    String mProfileApp = null;
1195    ProcessRecord mProfileProc = null;
1196    String mProfileFile;
1197    ParcelFileDescriptor mProfileFd;
1198    int mSamplingInterval = 0;
1199    boolean mAutoStopProfiler = false;
1200    int mProfileType = 0;
1201    String mOpenGlTraceApp = null;
1202    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1203    String mMemWatchDumpProcName;
1204    String mMemWatchDumpFile;
1205    int mMemWatchDumpPid;
1206    int mMemWatchDumpUid;
1207
1208    final long[] mTmpLong = new long[1];
1209
1210    static final class ProcessChangeItem {
1211        static final int CHANGE_ACTIVITIES = 1<<0;
1212        static final int CHANGE_PROCESS_STATE = 1<<1;
1213        int changes;
1214        int uid;
1215        int pid;
1216        int processState;
1217        boolean foregroundActivities;
1218    }
1219
1220    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1221    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1222
1223    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1224    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1225
1226    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1227    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1228
1229    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1230    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1231
1232    /**
1233     * Runtime CPU use collection thread.  This object's lock is used to
1234     * perform synchronization with the thread (notifying it to run).
1235     */
1236    final Thread mProcessCpuThread;
1237
1238    /**
1239     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1240     * Must acquire this object's lock when accessing it.
1241     * NOTE: this lock will be held while doing long operations (trawling
1242     * through all processes in /proc), so it should never be acquired by
1243     * any critical paths such as when holding the main activity manager lock.
1244     */
1245    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1246            MONITOR_THREAD_CPU_USAGE);
1247    final AtomicLong mLastCpuTime = new AtomicLong(0);
1248    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1249
1250    long mLastWriteTime = 0;
1251
1252    /**
1253     * Used to retain an update lock when the foreground activity is in
1254     * immersive mode.
1255     */
1256    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1257
1258    /**
1259     * Set to true after the system has finished booting.
1260     */
1261    boolean mBooted = false;
1262
1263    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1264    int mProcessLimitOverride = -1;
1265
1266    WindowManagerService mWindowManager;
1267
1268    final ActivityThread mSystemThread;
1269
1270    // Holds the current foreground user's id
1271    int mCurrentUserId = 0;
1272    // Holds the target user's id during a user switch
1273    int mTargetUserId = UserHandle.USER_NULL;
1274    // If there are multiple profiles for the current user, their ids are here
1275    // Currently only the primary user can have managed profiles
1276    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1277
1278    /**
1279     * Mapping from each known user ID to the profile group ID it is associated with.
1280     */
1281    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1282
1283    private UserManagerService mUserManager;
1284
1285    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1286        final ProcessRecord mApp;
1287        final int mPid;
1288        final IApplicationThread mAppThread;
1289
1290        AppDeathRecipient(ProcessRecord app, int pid,
1291                IApplicationThread thread) {
1292            if (DEBUG_ALL) Slog.v(
1293                TAG, "New death recipient " + this
1294                + " for thread " + thread.asBinder());
1295            mApp = app;
1296            mPid = pid;
1297            mAppThread = thread;
1298        }
1299
1300        @Override
1301        public void binderDied() {
1302            if (DEBUG_ALL) Slog.v(
1303                TAG, "Death received in " + this
1304                + " for thread " + mAppThread.asBinder());
1305            synchronized(ActivityManagerService.this) {
1306                appDiedLocked(mApp, mPid, mAppThread, true);
1307            }
1308        }
1309    }
1310
1311    static final int SHOW_ERROR_MSG = 1;
1312    static final int SHOW_NOT_RESPONDING_MSG = 2;
1313    static final int SHOW_FACTORY_ERROR_MSG = 3;
1314    static final int UPDATE_CONFIGURATION_MSG = 4;
1315    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1316    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1317    static final int SERVICE_TIMEOUT_MSG = 12;
1318    static final int UPDATE_TIME_ZONE = 13;
1319    static final int SHOW_UID_ERROR_MSG = 14;
1320    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1321    static final int PROC_START_TIMEOUT_MSG = 20;
1322    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1323    static final int KILL_APPLICATION_MSG = 22;
1324    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1325    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1326    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1327    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1328    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1329    static final int CLEAR_DNS_CACHE_MSG = 28;
1330    static final int UPDATE_HTTP_PROXY_MSG = 29;
1331    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1332    static final int DISPATCH_PROCESSES_CHANGED = 31;
1333    static final int DISPATCH_PROCESS_DIED = 32;
1334    static final int REPORT_MEM_USAGE_MSG = 33;
1335    static final int REPORT_USER_SWITCH_MSG = 34;
1336    static final int CONTINUE_USER_SWITCH_MSG = 35;
1337    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1338    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1339    static final int PERSIST_URI_GRANTS_MSG = 38;
1340    static final int REQUEST_ALL_PSS_MSG = 39;
1341    static final int START_PROFILES_MSG = 40;
1342    static final int UPDATE_TIME = 41;
1343    static final int SYSTEM_USER_START_MSG = 42;
1344    static final int SYSTEM_USER_CURRENT_MSG = 43;
1345    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1346    static final int FINISH_BOOTING_MSG = 45;
1347    static final int START_USER_SWITCH_MSG = 46;
1348    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1349    static final int DISMISS_DIALOG_MSG = 48;
1350    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1351    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1352    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1353    static final int DELETE_DUMPHEAP_MSG = 52;
1354    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1355    static final int DISPATCH_UIDS_CHANGED_MSG = 54;
1356    static final int REPORT_TIME_TRACKER_MSG = 55;
1357    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1358    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1359
1360    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1361    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1362    static final int FIRST_COMPAT_MODE_MSG = 300;
1363    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1364
1365    CompatModeDialog mCompatModeDialog;
1366    long mLastMemUsageReportTime = 0;
1367
1368    /**
1369     * Flag whether the current user is a "monkey", i.e. whether
1370     * the UI is driven by a UI automation tool.
1371     */
1372    private boolean mUserIsMonkey;
1373
1374    /** Flag whether the device has a Recents UI */
1375    boolean mHasRecents;
1376
1377    /** The dimensions of the thumbnails in the Recents UI. */
1378    int mThumbnailWidth;
1379    int mThumbnailHeight;
1380
1381    final ServiceThread mHandlerThread;
1382    final MainHandler mHandler;
1383    final UiHandler mUiHandler;
1384
1385    final class UiHandler extends Handler {
1386        public UiHandler() {
1387            super(com.android.server.UiThread.get().getLooper(), null, true);
1388        }
1389
1390        @Override
1391        public void handleMessage(Message msg) {
1392            switch (msg.what) {
1393            case SHOW_ERROR_MSG: {
1394                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1395                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1396                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1397                synchronized (ActivityManagerService.this) {
1398                    ProcessRecord proc = (ProcessRecord)data.get("app");
1399                    AppErrorResult res = (AppErrorResult) data.get("result");
1400                    if (proc != null && proc.crashDialog != null) {
1401                        Slog.e(TAG, "App already has crash dialog: " + proc);
1402                        if (res != null) {
1403                            res.set(0);
1404                        }
1405                        return;
1406                    }
1407                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1408                            >= Process.FIRST_APPLICATION_UID
1409                            && proc.pid != MY_PID);
1410                    for (int userId : mCurrentProfileIds) {
1411                        isBackground &= (proc.userId != userId);
1412                    }
1413                    if (isBackground && !showBackground) {
1414                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1415                        if (res != null) {
1416                            res.set(0);
1417                        }
1418                        return;
1419                    }
1420                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1421                        Dialog d = new AppErrorDialog(mContext,
1422                                ActivityManagerService.this, res, proc);
1423                        d.show();
1424                        proc.crashDialog = d;
1425                    } else {
1426                        // The device is asleep, so just pretend that the user
1427                        // saw a crash dialog and hit "force quit".
1428                        if (res != null) {
1429                            res.set(0);
1430                        }
1431                    }
1432                }
1433
1434                ensureBootCompleted();
1435            } break;
1436            case SHOW_NOT_RESPONDING_MSG: {
1437                synchronized (ActivityManagerService.this) {
1438                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1439                    ProcessRecord proc = (ProcessRecord)data.get("app");
1440                    if (proc != null && proc.anrDialog != null) {
1441                        Slog.e(TAG, "App already has anr dialog: " + proc);
1442                        return;
1443                    }
1444
1445                    Intent intent = new Intent("android.intent.action.ANR");
1446                    if (!mProcessesReady) {
1447                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1448                                | Intent.FLAG_RECEIVER_FOREGROUND);
1449                    }
1450                    broadcastIntentLocked(null, null, intent,
1451                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1452                            null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1453
1454                    if (mShowDialogs) {
1455                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1456                                mContext, proc, (ActivityRecord)data.get("activity"),
1457                                msg.arg1 != 0);
1458                        d.show();
1459                        proc.anrDialog = d;
1460                    } else {
1461                        // Just kill the app if there is no dialog to be shown.
1462                        killAppAtUsersRequest(proc, null);
1463                    }
1464                }
1465
1466                ensureBootCompleted();
1467            } break;
1468            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1469                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1470                synchronized (ActivityManagerService.this) {
1471                    ProcessRecord proc = (ProcessRecord) data.get("app");
1472                    if (proc == null) {
1473                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1474                        break;
1475                    }
1476                    if (proc.crashDialog != null) {
1477                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1478                        return;
1479                    }
1480                    AppErrorResult res = (AppErrorResult) data.get("result");
1481                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1482                        Dialog d = new StrictModeViolationDialog(mContext,
1483                                ActivityManagerService.this, res, proc);
1484                        d.show();
1485                        proc.crashDialog = d;
1486                    } else {
1487                        // The device is asleep, so just pretend that the user
1488                        // saw a crash dialog and hit "force quit".
1489                        res.set(0);
1490                    }
1491                }
1492                ensureBootCompleted();
1493            } break;
1494            case SHOW_FACTORY_ERROR_MSG: {
1495                Dialog d = new FactoryErrorDialog(
1496                    mContext, msg.getData().getCharSequence("msg"));
1497                d.show();
1498                ensureBootCompleted();
1499            } break;
1500            case WAIT_FOR_DEBUGGER_MSG: {
1501                synchronized (ActivityManagerService.this) {
1502                    ProcessRecord app = (ProcessRecord)msg.obj;
1503                    if (msg.arg1 != 0) {
1504                        if (!app.waitedForDebugger) {
1505                            Dialog d = new AppWaitingForDebuggerDialog(
1506                                    ActivityManagerService.this,
1507                                    mContext, app);
1508                            app.waitDialog = d;
1509                            app.waitedForDebugger = true;
1510                            d.show();
1511                        }
1512                    } else {
1513                        if (app.waitDialog != null) {
1514                            app.waitDialog.dismiss();
1515                            app.waitDialog = null;
1516                        }
1517                    }
1518                }
1519            } break;
1520            case SHOW_UID_ERROR_MSG: {
1521                if (mShowDialogs) {
1522                    AlertDialog d = new BaseErrorDialog(mContext);
1523                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1524                    d.setCancelable(false);
1525                    d.setTitle(mContext.getText(R.string.android_system_label));
1526                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1527                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1528                            obtainMessage(DISMISS_DIALOG_MSG, d));
1529                    d.show();
1530                }
1531            } break;
1532            case SHOW_FINGERPRINT_ERROR_MSG: {
1533                if (mShowDialogs) {
1534                    AlertDialog d = new BaseErrorDialog(mContext);
1535                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1536                    d.setCancelable(false);
1537                    d.setTitle(mContext.getText(R.string.android_system_label));
1538                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1539                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1540                            obtainMessage(DISMISS_DIALOG_MSG, d));
1541                    d.show();
1542                }
1543            } break;
1544            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1545                synchronized (ActivityManagerService.this) {
1546                    ActivityRecord ar = (ActivityRecord) msg.obj;
1547                    if (mCompatModeDialog != null) {
1548                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1549                                ar.info.applicationInfo.packageName)) {
1550                            return;
1551                        }
1552                        mCompatModeDialog.dismiss();
1553                        mCompatModeDialog = null;
1554                    }
1555                    if (ar != null && false) {
1556                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1557                                ar.packageName)) {
1558                            int mode = mCompatModePackages.computeCompatModeLocked(
1559                                    ar.info.applicationInfo);
1560                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1561                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1562                                mCompatModeDialog = new CompatModeDialog(
1563                                        ActivityManagerService.this, mContext,
1564                                        ar.info.applicationInfo);
1565                                mCompatModeDialog.show();
1566                            }
1567                        }
1568                    }
1569                }
1570                break;
1571            }
1572            case START_USER_SWITCH_MSG: {
1573                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1574                break;
1575            }
1576            case DISMISS_DIALOG_MSG: {
1577                final Dialog d = (Dialog) msg.obj;
1578                d.dismiss();
1579                break;
1580            }
1581            case DISPATCH_PROCESSES_CHANGED: {
1582                dispatchProcessesChanged();
1583                break;
1584            }
1585            case DISPATCH_PROCESS_DIED: {
1586                final int pid = msg.arg1;
1587                final int uid = msg.arg2;
1588                dispatchProcessDied(pid, uid);
1589                break;
1590            }
1591            case DISPATCH_UIDS_CHANGED_MSG: {
1592                dispatchUidsChanged();
1593            } break;
1594            }
1595        }
1596    }
1597
1598    final class MainHandler extends Handler {
1599        public MainHandler(Looper looper) {
1600            super(looper, null, true);
1601        }
1602
1603        @Override
1604        public void handleMessage(Message msg) {
1605            switch (msg.what) {
1606            case UPDATE_CONFIGURATION_MSG: {
1607                final ContentResolver resolver = mContext.getContentResolver();
1608                Settings.System.putConfiguration(resolver, (Configuration) msg.obj);
1609            } break;
1610            case GC_BACKGROUND_PROCESSES_MSG: {
1611                synchronized (ActivityManagerService.this) {
1612                    performAppGcsIfAppropriateLocked();
1613                }
1614            } break;
1615            case SERVICE_TIMEOUT_MSG: {
1616                if (mDidDexOpt) {
1617                    mDidDexOpt = false;
1618                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1619                    nmsg.obj = msg.obj;
1620                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1621                    return;
1622                }
1623                mServices.serviceTimeout((ProcessRecord)msg.obj);
1624            } break;
1625            case UPDATE_TIME_ZONE: {
1626                synchronized (ActivityManagerService.this) {
1627                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1628                        ProcessRecord r = mLruProcesses.get(i);
1629                        if (r.thread != null) {
1630                            try {
1631                                r.thread.updateTimeZone();
1632                            } catch (RemoteException ex) {
1633                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1634                            }
1635                        }
1636                    }
1637                }
1638            } break;
1639            case CLEAR_DNS_CACHE_MSG: {
1640                synchronized (ActivityManagerService.this) {
1641                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1642                        ProcessRecord r = mLruProcesses.get(i);
1643                        if (r.thread != null) {
1644                            try {
1645                                r.thread.clearDnsCache();
1646                            } catch (RemoteException ex) {
1647                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1648                            }
1649                        }
1650                    }
1651                }
1652            } break;
1653            case UPDATE_HTTP_PROXY_MSG: {
1654                ProxyInfo proxy = (ProxyInfo)msg.obj;
1655                String host = "";
1656                String port = "";
1657                String exclList = "";
1658                Uri pacFileUrl = Uri.EMPTY;
1659                if (proxy != null) {
1660                    host = proxy.getHost();
1661                    port = Integer.toString(proxy.getPort());
1662                    exclList = proxy.getExclusionListAsString();
1663                    pacFileUrl = proxy.getPacFileUrl();
1664                }
1665                synchronized (ActivityManagerService.this) {
1666                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1667                        ProcessRecord r = mLruProcesses.get(i);
1668                        if (r.thread != null) {
1669                            try {
1670                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1671                            } catch (RemoteException ex) {
1672                                Slog.w(TAG, "Failed to update http proxy for: " +
1673                                        r.info.processName);
1674                            }
1675                        }
1676                    }
1677                }
1678            } break;
1679            case PROC_START_TIMEOUT_MSG: {
1680                if (mDidDexOpt) {
1681                    mDidDexOpt = false;
1682                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1683                    nmsg.obj = msg.obj;
1684                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1685                    return;
1686                }
1687                ProcessRecord app = (ProcessRecord)msg.obj;
1688                synchronized (ActivityManagerService.this) {
1689                    processStartTimedOutLocked(app);
1690                }
1691            } break;
1692            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1693                synchronized (ActivityManagerService.this) {
1694                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1695                }
1696            } break;
1697            case KILL_APPLICATION_MSG: {
1698                synchronized (ActivityManagerService.this) {
1699                    int appid = msg.arg1;
1700                    boolean restart = (msg.arg2 == 1);
1701                    Bundle bundle = (Bundle)msg.obj;
1702                    String pkg = bundle.getString("pkg");
1703                    String reason = bundle.getString("reason");
1704                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1705                            false, UserHandle.USER_ALL, reason);
1706                }
1707            } break;
1708            case FINALIZE_PENDING_INTENT_MSG: {
1709                ((PendingIntentRecord)msg.obj).completeFinalize();
1710            } break;
1711            case POST_HEAVY_NOTIFICATION_MSG: {
1712                INotificationManager inm = NotificationManager.getService();
1713                if (inm == null) {
1714                    return;
1715                }
1716
1717                ActivityRecord root = (ActivityRecord)msg.obj;
1718                ProcessRecord process = root.app;
1719                if (process == null) {
1720                    return;
1721                }
1722
1723                try {
1724                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1725                    String text = mContext.getString(R.string.heavy_weight_notification,
1726                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1727                    Notification notification = new Notification.Builder(context)
1728                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1729                            .setWhen(0)
1730                            .setOngoing(true)
1731                            .setTicker(text)
1732                            .setColor(mContext.getColor(
1733                                    com.android.internal.R.color.system_notification_accent_color))
1734                            .setContentTitle(text)
1735                            .setContentText(
1736                                    mContext.getText(R.string.heavy_weight_notification_detail))
1737                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1738                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1739                                    new UserHandle(root.userId)))
1740                            .build();
1741                    try {
1742                        int[] outId = new int[1];
1743                        inm.enqueueNotificationWithTag("android", "android", null,
1744                                R.string.heavy_weight_notification,
1745                                notification, outId, root.userId);
1746                    } catch (RuntimeException e) {
1747                        Slog.w(ActivityManagerService.TAG,
1748                                "Error showing notification for heavy-weight app", e);
1749                    } catch (RemoteException e) {
1750                    }
1751                } catch (NameNotFoundException e) {
1752                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1753                }
1754            } break;
1755            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1756                INotificationManager inm = NotificationManager.getService();
1757                if (inm == null) {
1758                    return;
1759                }
1760                try {
1761                    inm.cancelNotificationWithTag("android", null,
1762                            R.string.heavy_weight_notification,  msg.arg1);
1763                } catch (RuntimeException e) {
1764                    Slog.w(ActivityManagerService.TAG,
1765                            "Error canceling notification for service", e);
1766                } catch (RemoteException e) {
1767                }
1768            } break;
1769            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1770                synchronized (ActivityManagerService.this) {
1771                    checkExcessivePowerUsageLocked(true);
1772                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1773                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1774                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1775                }
1776            } break;
1777            case REPORT_MEM_USAGE_MSG: {
1778                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1779                Thread thread = new Thread() {
1780                    @Override public void run() {
1781                        reportMemUsage(memInfos);
1782                    }
1783                };
1784                thread.start();
1785                break;
1786            }
1787            case REPORT_USER_SWITCH_MSG: {
1788                dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1789                break;
1790            }
1791            case CONTINUE_USER_SWITCH_MSG: {
1792                continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1793                break;
1794            }
1795            case USER_SWITCH_TIMEOUT_MSG: {
1796                timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1797                break;
1798            }
1799            case IMMERSIVE_MODE_LOCK_MSG: {
1800                final boolean nextState = (msg.arg1 != 0);
1801                if (mUpdateLock.isHeld() != nextState) {
1802                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1803                            "Applying new update lock state '" + nextState
1804                            + "' for " + (ActivityRecord)msg.obj);
1805                    if (nextState) {
1806                        mUpdateLock.acquire();
1807                    } else {
1808                        mUpdateLock.release();
1809                    }
1810                }
1811                break;
1812            }
1813            case PERSIST_URI_GRANTS_MSG: {
1814                writeGrantedUriPermissions();
1815                break;
1816            }
1817            case REQUEST_ALL_PSS_MSG: {
1818                synchronized (ActivityManagerService.this) {
1819                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1820                }
1821                break;
1822            }
1823            case START_PROFILES_MSG: {
1824                synchronized (ActivityManagerService.this) {
1825                    startProfilesLocked();
1826                }
1827                break;
1828            }
1829            case UPDATE_TIME: {
1830                synchronized (ActivityManagerService.this) {
1831                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1832                        ProcessRecord r = mLruProcesses.get(i);
1833                        if (r.thread != null) {
1834                            try {
1835                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1836                            } catch (RemoteException ex) {
1837                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1838                            }
1839                        }
1840                    }
1841                }
1842                break;
1843            }
1844            case SYSTEM_USER_START_MSG: {
1845                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1846                        Integer.toString(msg.arg1), msg.arg1);
1847                mSystemServiceManager.startUser(msg.arg1);
1848                break;
1849            }
1850            case SYSTEM_USER_CURRENT_MSG: {
1851                mBatteryStatsService.noteEvent(
1852                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1853                        Integer.toString(msg.arg2), msg.arg2);
1854                mBatteryStatsService.noteEvent(
1855                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1856                        Integer.toString(msg.arg1), msg.arg1);
1857                mSystemServiceManager.switchUser(msg.arg1);
1858                break;
1859            }
1860            case ENTER_ANIMATION_COMPLETE_MSG: {
1861                synchronized (ActivityManagerService.this) {
1862                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1863                    if (r != null && r.app != null && r.app.thread != null) {
1864                        try {
1865                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1866                        } catch (RemoteException e) {
1867                        }
1868                    }
1869                }
1870                break;
1871            }
1872            case FINISH_BOOTING_MSG: {
1873                if (msg.arg1 != 0) {
1874                    finishBooting();
1875                }
1876                if (msg.arg2 != 0) {
1877                    enableScreenAfterBoot();
1878                }
1879                break;
1880            }
1881            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1882                try {
1883                    Locale l = (Locale) msg.obj;
1884                    IBinder service = ServiceManager.getService("mount");
1885                    IMountService mountService = IMountService.Stub.asInterface(service);
1886                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1887                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1888                } catch (RemoteException e) {
1889                    Log.e(TAG, "Error storing locale for decryption UI", e);
1890                }
1891                break;
1892            }
1893            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1894                synchronized (ActivityManagerService.this) {
1895                    int i = mTaskStackListeners.beginBroadcast();
1896                    while (i > 0) {
1897                        i--;
1898                        try {
1899                            // Make a one-way callback to the listener
1900                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1901                        } catch (RemoteException e){
1902                            // Handled by the RemoteCallbackList
1903                        }
1904                    }
1905                    mTaskStackListeners.finishBroadcast();
1906                }
1907                break;
1908            }
1909            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1910                final int uid = msg.arg1;
1911                final byte[] firstPacket = (byte[]) msg.obj;
1912
1913                synchronized (mPidsSelfLocked) {
1914                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
1915                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
1916                        if (p.uid == uid) {
1917                            try {
1918                                p.thread.notifyCleartextNetwork(firstPacket);
1919                            } catch (RemoteException ignored) {
1920                            }
1921                        }
1922                    }
1923                }
1924                break;
1925            }
1926            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
1927                final String procName;
1928                final int uid;
1929                final long memLimit;
1930                final String reportPackage;
1931                synchronized (ActivityManagerService.this) {
1932                    procName = mMemWatchDumpProcName;
1933                    uid = mMemWatchDumpUid;
1934                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
1935                    if (val == null) {
1936                        val = mMemWatchProcesses.get(procName, 0);
1937                    }
1938                    if (val != null) {
1939                        memLimit = val.first;
1940                        reportPackage = val.second;
1941                    } else {
1942                        memLimit = 0;
1943                        reportPackage = null;
1944                    }
1945                }
1946                if (procName == null) {
1947                    return;
1948                }
1949
1950                if (DEBUG_PSS) Slog.d(TAG_PSS,
1951                        "Showing dump heap notification from " + procName + "/" + uid);
1952
1953                INotificationManager inm = NotificationManager.getService();
1954                if (inm == null) {
1955                    return;
1956                }
1957
1958                String text = mContext.getString(R.string.dump_heap_notification, procName);
1959
1960
1961                Intent deleteIntent = new Intent();
1962                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
1963                Intent intent = new Intent();
1964                intent.setClassName("android", DumpHeapActivity.class.getName());
1965                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
1966                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
1967                if (reportPackage != null) {
1968                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
1969                }
1970                int userId = UserHandle.getUserId(uid);
1971                Notification notification = new Notification.Builder(mContext)
1972                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1973                        .setWhen(0)
1974                        .setOngoing(true)
1975                        .setAutoCancel(true)
1976                        .setTicker(text)
1977                        .setColor(mContext.getColor(
1978                                com.android.internal.R.color.system_notification_accent_color))
1979                        .setContentTitle(text)
1980                        .setContentText(
1981                                mContext.getText(R.string.dump_heap_notification_detail))
1982                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1983                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1984                                new UserHandle(userId)))
1985                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
1986                                deleteIntent, 0, UserHandle.OWNER))
1987                        .build();
1988
1989                try {
1990                    int[] outId = new int[1];
1991                    inm.enqueueNotificationWithTag("android", "android", null,
1992                            R.string.dump_heap_notification,
1993                            notification, outId, userId);
1994                } catch (RuntimeException e) {
1995                    Slog.w(ActivityManagerService.TAG,
1996                            "Error showing notification for dump heap", e);
1997                } catch (RemoteException e) {
1998                }
1999            } break;
2000            case DELETE_DUMPHEAP_MSG: {
2001                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2002                        DumpHeapActivity.JAVA_URI,
2003                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2004                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2005                        UserHandle.myUserId());
2006                synchronized (ActivityManagerService.this) {
2007                    mMemWatchDumpFile = null;
2008                    mMemWatchDumpProcName = null;
2009                    mMemWatchDumpPid = -1;
2010                    mMemWatchDumpUid = -1;
2011                }
2012            } break;
2013            case FOREGROUND_PROFILE_CHANGED_MSG: {
2014                dispatchForegroundProfileChanged(msg.arg1);
2015            } break;
2016            case REPORT_TIME_TRACKER_MSG: {
2017                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2018                tracker.deliverResult(mContext);
2019            } break;
2020            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2021                dispatchUserSwitchComplete(msg.arg1);
2022            } break;
2023            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2024                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2025                try {
2026                    connection.shutdown();
2027                } catch (RemoteException e) {
2028                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2029                }
2030                // Only a UiAutomation can set this flag and now that
2031                // it is finished we make sure it is reset to its default.
2032                mUserIsMonkey = false;
2033            } break;
2034            }
2035        }
2036    };
2037
2038    static final int COLLECT_PSS_BG_MSG = 1;
2039
2040    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2041        @Override
2042        public void handleMessage(Message msg) {
2043            switch (msg.what) {
2044            case COLLECT_PSS_BG_MSG: {
2045                long start = SystemClock.uptimeMillis();
2046                MemInfoReader memInfo = null;
2047                synchronized (ActivityManagerService.this) {
2048                    if (mFullPssPending) {
2049                        mFullPssPending = false;
2050                        memInfo = new MemInfoReader();
2051                    }
2052                }
2053                if (memInfo != null) {
2054                    updateCpuStatsNow();
2055                    long nativeTotalPss = 0;
2056                    synchronized (mProcessCpuTracker) {
2057                        final int N = mProcessCpuTracker.countStats();
2058                        for (int j=0; j<N; j++) {
2059                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2060                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2061                                // This is definitely an application process; skip it.
2062                                continue;
2063                            }
2064                            synchronized (mPidsSelfLocked) {
2065                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2066                                    // This is one of our own processes; skip it.
2067                                    continue;
2068                                }
2069                            }
2070                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2071                        }
2072                    }
2073                    memInfo.readMemInfo();
2074                    synchronized (ActivityManagerService.this) {
2075                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2076                                + (SystemClock.uptimeMillis()-start) + "ms");
2077                        final long cachedKb = memInfo.getCachedSizeKb();
2078                        final long freeKb = memInfo.getFreeSizeKb();
2079                        final long zramKb = memInfo.getZramTotalSizeKb();
2080                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2081                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2082                                kernelKb*1024, nativeTotalPss*1024);
2083                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2084                                nativeTotalPss);
2085                    }
2086                }
2087
2088                int num = 0;
2089                long[] tmp = new long[1];
2090                do {
2091                    ProcessRecord proc;
2092                    int procState;
2093                    int pid;
2094                    long lastPssTime;
2095                    synchronized (ActivityManagerService.this) {
2096                        if (mPendingPssProcesses.size() <= 0) {
2097                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2098                                    "Collected PSS of " + num + " processes in "
2099                                    + (SystemClock.uptimeMillis() - start) + "ms");
2100                            mPendingPssProcesses.clear();
2101                            return;
2102                        }
2103                        proc = mPendingPssProcesses.remove(0);
2104                        procState = proc.pssProcState;
2105                        lastPssTime = proc.lastPssTime;
2106                        if (proc.thread != null && procState == proc.setProcState
2107                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2108                                        < SystemClock.uptimeMillis()) {
2109                            pid = proc.pid;
2110                        } else {
2111                            proc = null;
2112                            pid = 0;
2113                        }
2114                    }
2115                    if (proc != null) {
2116                        long pss = Debug.getPss(pid, tmp, null);
2117                        synchronized (ActivityManagerService.this) {
2118                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2119                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2120                                num++;
2121                                recordPssSampleLocked(proc, procState, pss, tmp[0],
2122                                        SystemClock.uptimeMillis());
2123                            }
2124                        }
2125                    }
2126                } while (true);
2127            }
2128            }
2129        }
2130    };
2131
2132    public void setSystemProcess() {
2133        try {
2134            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2135            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2136            ServiceManager.addService("meminfo", new MemBinder(this));
2137            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2138            ServiceManager.addService("dbinfo", new DbBinder(this));
2139            if (MONITOR_CPU_USAGE) {
2140                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2141            }
2142            ServiceManager.addService("permission", new PermissionController(this));
2143            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2144
2145            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2146                    "android", STOCK_PM_FLAGS);
2147            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2148
2149            synchronized (this) {
2150                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2151                app.persistent = true;
2152                app.pid = MY_PID;
2153                app.maxAdj = ProcessList.SYSTEM_ADJ;
2154                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2155                synchronized (mPidsSelfLocked) {
2156                    mPidsSelfLocked.put(app.pid, app);
2157                }
2158                updateLruProcessLocked(app, false, null);
2159                updateOomAdjLocked();
2160            }
2161        } catch (PackageManager.NameNotFoundException e) {
2162            throw new RuntimeException(
2163                    "Unable to find android system package", e);
2164        }
2165    }
2166
2167    public void setWindowManager(WindowManagerService wm) {
2168        mWindowManager = wm;
2169        mStackSupervisor.setWindowManager(wm);
2170    }
2171
2172    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2173        mUsageStatsService = usageStatsManager;
2174    }
2175
2176    public void startObservingNativeCrashes() {
2177        final NativeCrashListener ncl = new NativeCrashListener(this);
2178        ncl.start();
2179    }
2180
2181    public IAppOpsService getAppOpsService() {
2182        return mAppOpsService;
2183    }
2184
2185    static class MemBinder extends Binder {
2186        ActivityManagerService mActivityManagerService;
2187        MemBinder(ActivityManagerService activityManagerService) {
2188            mActivityManagerService = activityManagerService;
2189        }
2190
2191        @Override
2192        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2193            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2194                    != PackageManager.PERMISSION_GRANTED) {
2195                pw.println("Permission Denial: can't dump meminfo from from pid="
2196                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2197                        + " without permission " + android.Manifest.permission.DUMP);
2198                return;
2199            }
2200
2201            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2202        }
2203    }
2204
2205    static class GraphicsBinder extends Binder {
2206        ActivityManagerService mActivityManagerService;
2207        GraphicsBinder(ActivityManagerService activityManagerService) {
2208            mActivityManagerService = activityManagerService;
2209        }
2210
2211        @Override
2212        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2213            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2214                    != PackageManager.PERMISSION_GRANTED) {
2215                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2216                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2217                        + " without permission " + android.Manifest.permission.DUMP);
2218                return;
2219            }
2220
2221            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2222        }
2223    }
2224
2225    static class DbBinder extends Binder {
2226        ActivityManagerService mActivityManagerService;
2227        DbBinder(ActivityManagerService activityManagerService) {
2228            mActivityManagerService = activityManagerService;
2229        }
2230
2231        @Override
2232        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2233            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2234                    != PackageManager.PERMISSION_GRANTED) {
2235                pw.println("Permission Denial: can't dump dbinfo from from pid="
2236                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2237                        + " without permission " + android.Manifest.permission.DUMP);
2238                return;
2239            }
2240
2241            mActivityManagerService.dumpDbInfo(fd, pw, args);
2242        }
2243    }
2244
2245    static class CpuBinder extends Binder {
2246        ActivityManagerService mActivityManagerService;
2247        CpuBinder(ActivityManagerService activityManagerService) {
2248            mActivityManagerService = activityManagerService;
2249        }
2250
2251        @Override
2252        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2253            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2254                    != PackageManager.PERMISSION_GRANTED) {
2255                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2256                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2257                        + " without permission " + android.Manifest.permission.DUMP);
2258                return;
2259            }
2260
2261            synchronized (mActivityManagerService.mProcessCpuTracker) {
2262                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2263                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2264                        SystemClock.uptimeMillis()));
2265            }
2266        }
2267    }
2268
2269    public static final class Lifecycle extends SystemService {
2270        private final ActivityManagerService mService;
2271
2272        public Lifecycle(Context context) {
2273            super(context);
2274            mService = new ActivityManagerService(context);
2275        }
2276
2277        @Override
2278        public void onStart() {
2279            mService.start();
2280        }
2281
2282        public ActivityManagerService getService() {
2283            return mService;
2284        }
2285    }
2286
2287    // Note: This method is invoked on the main thread but may need to attach various
2288    // handlers to other threads.  So take care to be explicit about the looper.
2289    public ActivityManagerService(Context systemContext) {
2290        mContext = systemContext;
2291        mFactoryTest = FactoryTest.getMode();
2292        mSystemThread = ActivityThread.currentActivityThread();
2293
2294        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2295
2296        mHandlerThread = new ServiceThread(TAG,
2297                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2298        mHandlerThread.start();
2299        mHandler = new MainHandler(mHandlerThread.getLooper());
2300        mUiHandler = new UiHandler();
2301
2302        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2303                "foreground", BROADCAST_FG_TIMEOUT, false);
2304        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2305                "background", BROADCAST_BG_TIMEOUT, true);
2306        mBroadcastQueues[0] = mFgBroadcastQueue;
2307        mBroadcastQueues[1] = mBgBroadcastQueue;
2308
2309        mServices = new ActiveServices(this);
2310        mProviderMap = new ProviderMap(this);
2311
2312        // TODO: Move creation of battery stats service outside of activity manager service.
2313        File dataDir = Environment.getDataDirectory();
2314        File systemDir = new File(dataDir, "system");
2315        systemDir.mkdirs();
2316        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2317        mBatteryStatsService.getActiveStatistics().readLocked();
2318        mBatteryStatsService.scheduleWriteToDisk();
2319        mOnBattery = DEBUG_POWER ? true
2320                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2321        mBatteryStatsService.getActiveStatistics().setCallback(this);
2322
2323        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2324
2325        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2326
2327        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2328
2329        // User 0 is the first and only user that runs at boot.
2330        mStartedUsers.put(UserHandle.USER_OWNER, new UserState(UserHandle.OWNER, true));
2331        mUserLru.add(UserHandle.USER_OWNER);
2332        updateStartedUserArrayLocked();
2333
2334        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2335            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2336
2337        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2338
2339        mConfiguration.setToDefaults();
2340        mConfiguration.setLocale(Locale.getDefault());
2341
2342        mConfigurationSeq = mConfiguration.seq = 1;
2343        mProcessCpuTracker.init();
2344
2345        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2346        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2347        mRecentTasks = new RecentTasks(this);
2348        mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
2349        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
2350
2351        mProcessCpuThread = new Thread("CpuTracker") {
2352            @Override
2353            public void run() {
2354                while (true) {
2355                    try {
2356                        try {
2357                            synchronized(this) {
2358                                final long now = SystemClock.uptimeMillis();
2359                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2360                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2361                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2362                                //        + ", write delay=" + nextWriteDelay);
2363                                if (nextWriteDelay < nextCpuDelay) {
2364                                    nextCpuDelay = nextWriteDelay;
2365                                }
2366                                if (nextCpuDelay > 0) {
2367                                    mProcessCpuMutexFree.set(true);
2368                                    this.wait(nextCpuDelay);
2369                                }
2370                            }
2371                        } catch (InterruptedException e) {
2372                        }
2373                        updateCpuStatsNow();
2374                    } catch (Exception e) {
2375                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2376                    }
2377                }
2378            }
2379        };
2380
2381        Watchdog.getInstance().addMonitor(this);
2382        Watchdog.getInstance().addThread(mHandler);
2383    }
2384
2385    public void setSystemServiceManager(SystemServiceManager mgr) {
2386        mSystemServiceManager = mgr;
2387    }
2388
2389    public void setInstaller(Installer installer) {
2390        mInstaller = installer;
2391    }
2392
2393    private void start() {
2394        Process.removeAllProcessGroups();
2395        mProcessCpuThread.start();
2396
2397        mBatteryStatsService.publish(mContext);
2398        mAppOpsService.publish(mContext);
2399        Slog.d("AppOps", "AppOpsService published");
2400        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2401    }
2402
2403    public void initPowerManagement() {
2404        mStackSupervisor.initPowerManagement();
2405        mBatteryStatsService.initPowerManagement();
2406        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2407        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2408        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2409        mVoiceWakeLock.setReferenceCounted(false);
2410    }
2411
2412    @Override
2413    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2414            throws RemoteException {
2415        if (code == SYSPROPS_TRANSACTION) {
2416            // We need to tell all apps about the system property change.
2417            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2418            synchronized(this) {
2419                final int NP = mProcessNames.getMap().size();
2420                for (int ip=0; ip<NP; ip++) {
2421                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2422                    final int NA = apps.size();
2423                    for (int ia=0; ia<NA; ia++) {
2424                        ProcessRecord app = apps.valueAt(ia);
2425                        if (app.thread != null) {
2426                            procs.add(app.thread.asBinder());
2427                        }
2428                    }
2429                }
2430            }
2431
2432            int N = procs.size();
2433            for (int i=0; i<N; i++) {
2434                Parcel data2 = Parcel.obtain();
2435                try {
2436                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2437                } catch (RemoteException e) {
2438                }
2439                data2.recycle();
2440            }
2441        }
2442        try {
2443            return super.onTransact(code, data, reply, flags);
2444        } catch (RuntimeException e) {
2445            // The activity manager only throws security exceptions, so let's
2446            // log all others.
2447            if (!(e instanceof SecurityException)) {
2448                Slog.wtf(TAG, "Activity Manager Crash", e);
2449            }
2450            throw e;
2451        }
2452    }
2453
2454    void updateCpuStats() {
2455        final long now = SystemClock.uptimeMillis();
2456        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2457            return;
2458        }
2459        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2460            synchronized (mProcessCpuThread) {
2461                mProcessCpuThread.notify();
2462            }
2463        }
2464    }
2465
2466    void updateCpuStatsNow() {
2467        synchronized (mProcessCpuTracker) {
2468            mProcessCpuMutexFree.set(false);
2469            final long now = SystemClock.uptimeMillis();
2470            boolean haveNewCpuStats = false;
2471
2472            if (MONITOR_CPU_USAGE &&
2473                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2474                mLastCpuTime.set(now);
2475                mProcessCpuTracker.update();
2476                if (mProcessCpuTracker.hasGoodLastStats()) {
2477                    haveNewCpuStats = true;
2478                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2479                    //Slog.i(TAG, "Total CPU usage: "
2480                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2481
2482                    // Slog the cpu usage if the property is set.
2483                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2484                        int user = mProcessCpuTracker.getLastUserTime();
2485                        int system = mProcessCpuTracker.getLastSystemTime();
2486                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2487                        int irq = mProcessCpuTracker.getLastIrqTime();
2488                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2489                        int idle = mProcessCpuTracker.getLastIdleTime();
2490
2491                        int total = user + system + iowait + irq + softIrq + idle;
2492                        if (total == 0) total = 1;
2493
2494                        EventLog.writeEvent(EventLogTags.CPU,
2495                                ((user+system+iowait+irq+softIrq) * 100) / total,
2496                                (user * 100) / total,
2497                                (system * 100) / total,
2498                                (iowait * 100) / total,
2499                                (irq * 100) / total,
2500                                (softIrq * 100) / total);
2501                    }
2502                }
2503            }
2504
2505            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2506            synchronized(bstats) {
2507                synchronized(mPidsSelfLocked) {
2508                    if (haveNewCpuStats) {
2509                        if (bstats.startAddingCpuLocked()) {
2510                            int totalUTime = 0;
2511                            int totalSTime = 0;
2512                            final int N = mProcessCpuTracker.countStats();
2513                            for (int i=0; i<N; i++) {
2514                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2515                                if (!st.working) {
2516                                    continue;
2517                                }
2518                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2519                                totalUTime += st.rel_utime;
2520                                totalSTime += st.rel_stime;
2521                                if (pr != null) {
2522                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2523                                    if (ps == null || !ps.isActive()) {
2524                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2525                                                pr.info.uid, pr.processName);
2526                                    }
2527                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2528                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2529                                } else {
2530                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2531                                    if (ps == null || !ps.isActive()) {
2532                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2533                                                bstats.mapUid(st.uid), st.name);
2534                                    }
2535                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2536                                }
2537                            }
2538                            final int userTime = mProcessCpuTracker.getLastUserTime();
2539                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2540                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2541                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2542                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2543                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2544                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2545                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2546                        }
2547                    }
2548                }
2549
2550                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2551                    mLastWriteTime = now;
2552                    mBatteryStatsService.scheduleWriteToDisk();
2553                }
2554            }
2555        }
2556    }
2557
2558    @Override
2559    public void batteryNeedsCpuUpdate() {
2560        updateCpuStatsNow();
2561    }
2562
2563    @Override
2564    public void batteryPowerChanged(boolean onBattery) {
2565        // When plugging in, update the CPU stats first before changing
2566        // the plug state.
2567        updateCpuStatsNow();
2568        synchronized (this) {
2569            synchronized(mPidsSelfLocked) {
2570                mOnBattery = DEBUG_POWER ? true : onBattery;
2571            }
2572        }
2573    }
2574
2575    @Override
2576    public void batterySendBroadcast(Intent intent) {
2577        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2578                AppOpsManager.OP_NONE, null, false, false,
2579                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2580    }
2581
2582    /**
2583     * Initialize the application bind args. These are passed to each
2584     * process when the bindApplication() IPC is sent to the process. They're
2585     * lazily setup to make sure the services are running when they're asked for.
2586     */
2587    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2588        if (mAppBindArgs == null) {
2589            mAppBindArgs = new HashMap<>();
2590
2591            // Isolated processes won't get this optimization, so that we don't
2592            // violate the rules about which services they have access to.
2593            if (!isolated) {
2594                // Setup the application init args
2595                mAppBindArgs.put("package", ServiceManager.getService("package"));
2596                mAppBindArgs.put("window", ServiceManager.getService("window"));
2597                mAppBindArgs.put(Context.ALARM_SERVICE,
2598                        ServiceManager.getService(Context.ALARM_SERVICE));
2599            }
2600        }
2601        return mAppBindArgs;
2602    }
2603
2604    final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2605        if (r != null && mFocusedActivity != r) {
2606            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2607            ActivityRecord last = mFocusedActivity;
2608            mFocusedActivity = r;
2609            if (r.task.taskType != ActivityRecord.HOME_ACTIVITY_TYPE
2610                    && r.task.taskType != ActivityRecord.RECENTS_ACTIVITY_TYPE) {
2611                if (mCurAppTimeTracker != r.appTimeTracker) {
2612                    // We are switching app tracking.  Complete the current one.
2613                    if (mCurAppTimeTracker != null) {
2614                        mCurAppTimeTracker.stop();
2615                        mHandler.obtainMessage(REPORT_TIME_TRACKER_MSG,
2616                                mCurAppTimeTracker).sendToTarget();
2617                        mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2618                        mCurAppTimeTracker = null;
2619                    }
2620                    if (r.appTimeTracker != null) {
2621                        mCurAppTimeTracker = r.appTimeTracker;
2622                        startTimeTrackingFocusedActivityLocked();
2623                    }
2624                } else {
2625                    startTimeTrackingFocusedActivityLocked();
2626                }
2627            } else {
2628                r.appTimeTracker = null;
2629            }
2630            if (r.task != null && r.task.voiceInteractor != null) {
2631                startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2632            } else {
2633                finishRunningVoiceLocked();
2634                if (last != null && last.task.voiceSession != null) {
2635                    // We had been in a voice interaction session, but now focused has
2636                    // move to something different.  Just finish the session, we can't
2637                    // return to it and retain the proper state and synchronization with
2638                    // the voice interaction service.
2639                    finishVoiceTask(last.task.voiceSession);
2640                }
2641            }
2642            if (mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
2643                mWindowManager.setFocusedApp(r.appToken, true);
2644            }
2645            applyUpdateLockStateLocked(r);
2646            if (mFocusedActivity.userId != mLastFocusedUserId) {
2647                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2648                mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2649                        mFocusedActivity.userId, 0));
2650                mLastFocusedUserId = mFocusedActivity.userId;
2651            }
2652        }
2653        EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY,
2654                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2655                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2656    }
2657
2658    final void clearFocusedActivity(ActivityRecord r) {
2659        if (mFocusedActivity == r) {
2660            ActivityStack stack = mStackSupervisor.getFocusedStack();
2661            if (stack != null) {
2662                ActivityRecord top = stack.topActivity();
2663                if (top != null && top.userId != mLastFocusedUserId) {
2664                    mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2665                    mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2666                                    top.userId, 0));
2667                    mLastFocusedUserId = top.userId;
2668                }
2669            }
2670            mFocusedActivity = null;
2671            EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, -1, "NULL");
2672        }
2673    }
2674
2675    @Override
2676    public void setFocusedStack(int stackId) {
2677        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2678        synchronized (ActivityManagerService.this) {
2679            ActivityStack stack = mStackSupervisor.getStack(stackId);
2680            if (stack != null) {
2681                ActivityRecord r = stack.topRunningActivityLocked(null);
2682                if (r != null) {
2683                    setFocusedActivityLocked(r, "setFocusedStack");
2684                    mStackSupervisor.resumeTopActivitiesLocked(stack, null, null);
2685                }
2686            }
2687        }
2688    }
2689
2690    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2691    @Override
2692    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2693        synchronized (ActivityManagerService.this) {
2694            if (listener != null) {
2695                mTaskStackListeners.register(listener);
2696            }
2697        }
2698    }
2699
2700    @Override
2701    public void notifyActivityDrawn(IBinder token) {
2702        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2703        synchronized (this) {
2704            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2705            if (r != null) {
2706                r.task.stack.notifyActivityDrawnLocked(r);
2707            }
2708        }
2709    }
2710
2711    final void applyUpdateLockStateLocked(ActivityRecord r) {
2712        // Modifications to the UpdateLock state are done on our handler, outside
2713        // the activity manager's locks.  The new state is determined based on the
2714        // state *now* of the relevant activity record.  The object is passed to
2715        // the handler solely for logging detail, not to be consulted/modified.
2716        final boolean nextState = r != null && r.immersive;
2717        mHandler.sendMessage(
2718                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2719    }
2720
2721    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2722        Message msg = Message.obtain();
2723        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2724        msg.obj = r.task.askedCompatMode ? null : r;
2725        mUiHandler.sendMessage(msg);
2726    }
2727
2728    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2729            String what, Object obj, ProcessRecord srcApp) {
2730        app.lastActivityTime = now;
2731
2732        if (app.activities.size() > 0) {
2733            // Don't want to touch dependent processes that are hosting activities.
2734            return index;
2735        }
2736
2737        int lrui = mLruProcesses.lastIndexOf(app);
2738        if (lrui < 0) {
2739            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2740                    + what + " " + obj + " from " + srcApp);
2741            return index;
2742        }
2743
2744        if (lrui >= index) {
2745            // Don't want to cause this to move dependent processes *back* in the
2746            // list as if they were less frequently used.
2747            return index;
2748        }
2749
2750        if (lrui >= mLruProcessActivityStart) {
2751            // Don't want to touch dependent processes that are hosting activities.
2752            return index;
2753        }
2754
2755        mLruProcesses.remove(lrui);
2756        if (index > 0) {
2757            index--;
2758        }
2759        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2760                + " in LRU list: " + app);
2761        mLruProcesses.add(index, app);
2762        return index;
2763    }
2764
2765    private static void killProcessGroup(int uid, int pid) {
2766        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
2767        Process.killProcessGroup(uid, pid);
2768        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2769    }
2770
2771    final void removeLruProcessLocked(ProcessRecord app) {
2772        int lrui = mLruProcesses.lastIndexOf(app);
2773        if (lrui >= 0) {
2774            if (!app.killed) {
2775                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2776                Process.killProcessQuiet(app.pid);
2777                killProcessGroup(app.info.uid, app.pid);
2778            }
2779            if (lrui <= mLruProcessActivityStart) {
2780                mLruProcessActivityStart--;
2781            }
2782            if (lrui <= mLruProcessServiceStart) {
2783                mLruProcessServiceStart--;
2784            }
2785            mLruProcesses.remove(lrui);
2786        }
2787    }
2788
2789    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2790            ProcessRecord client) {
2791        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2792                || app.treatLikeActivity;
2793        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2794        if (!activityChange && hasActivity) {
2795            // The process has activities, so we are only allowing activity-based adjustments
2796            // to move it.  It should be kept in the front of the list with other
2797            // processes that have activities, and we don't want those to change their
2798            // order except due to activity operations.
2799            return;
2800        }
2801
2802        mLruSeq++;
2803        final long now = SystemClock.uptimeMillis();
2804        app.lastActivityTime = now;
2805
2806        // First a quick reject: if the app is already at the position we will
2807        // put it, then there is nothing to do.
2808        if (hasActivity) {
2809            final int N = mLruProcesses.size();
2810            if (N > 0 && mLruProcesses.get(N-1) == app) {
2811                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
2812                return;
2813            }
2814        } else {
2815            if (mLruProcessServiceStart > 0
2816                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2817                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
2818                return;
2819            }
2820        }
2821
2822        int lrui = mLruProcesses.lastIndexOf(app);
2823
2824        if (app.persistent && lrui >= 0) {
2825            // We don't care about the position of persistent processes, as long as
2826            // they are in the list.
2827            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
2828            return;
2829        }
2830
2831        /* In progress: compute new position first, so we can avoid doing work
2832           if the process is not actually going to move.  Not yet working.
2833        int addIndex;
2834        int nextIndex;
2835        boolean inActivity = false, inService = false;
2836        if (hasActivity) {
2837            // Process has activities, put it at the very tipsy-top.
2838            addIndex = mLruProcesses.size();
2839            nextIndex = mLruProcessServiceStart;
2840            inActivity = true;
2841        } else if (hasService) {
2842            // Process has services, put it at the top of the service list.
2843            addIndex = mLruProcessActivityStart;
2844            nextIndex = mLruProcessServiceStart;
2845            inActivity = true;
2846            inService = true;
2847        } else  {
2848            // Process not otherwise of interest, it goes to the top of the non-service area.
2849            addIndex = mLruProcessServiceStart;
2850            if (client != null) {
2851                int clientIndex = mLruProcesses.lastIndexOf(client);
2852                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2853                        + app);
2854                if (clientIndex >= 0 && addIndex > clientIndex) {
2855                    addIndex = clientIndex;
2856                }
2857            }
2858            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2859        }
2860
2861        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2862                + mLruProcessActivityStart + "): " + app);
2863        */
2864
2865        if (lrui >= 0) {
2866            if (lrui < mLruProcessActivityStart) {
2867                mLruProcessActivityStart--;
2868            }
2869            if (lrui < mLruProcessServiceStart) {
2870                mLruProcessServiceStart--;
2871            }
2872            /*
2873            if (addIndex > lrui) {
2874                addIndex--;
2875            }
2876            if (nextIndex > lrui) {
2877                nextIndex--;
2878            }
2879            */
2880            mLruProcesses.remove(lrui);
2881        }
2882
2883        /*
2884        mLruProcesses.add(addIndex, app);
2885        if (inActivity) {
2886            mLruProcessActivityStart++;
2887        }
2888        if (inService) {
2889            mLruProcessActivityStart++;
2890        }
2891        */
2892
2893        int nextIndex;
2894        if (hasActivity) {
2895            final int N = mLruProcesses.size();
2896            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
2897                // Process doesn't have activities, but has clients with
2898                // activities...  move it up, but one below the top (the top
2899                // should always have a real activity).
2900                if (DEBUG_LRU) Slog.d(TAG_LRU,
2901                        "Adding to second-top of LRU activity list: " + app);
2902                mLruProcesses.add(N - 1, app);
2903                // To keep it from spamming the LRU list (by making a bunch of clients),
2904                // we will push down any other entries owned by the app.
2905                final int uid = app.info.uid;
2906                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
2907                    ProcessRecord subProc = mLruProcesses.get(i);
2908                    if (subProc.info.uid == uid) {
2909                        // We want to push this one down the list.  If the process after
2910                        // it is for the same uid, however, don't do so, because we don't
2911                        // want them internally to be re-ordered.
2912                        if (mLruProcesses.get(i - 1).info.uid != uid) {
2913                            if (DEBUG_LRU) Slog.d(TAG_LRU,
2914                                    "Pushing uid " + uid + " swapping at " + i + ": "
2915                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
2916                            ProcessRecord tmp = mLruProcesses.get(i);
2917                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
2918                            mLruProcesses.set(i - 1, tmp);
2919                            i--;
2920                        }
2921                    } else {
2922                        // A gap, we can stop here.
2923                        break;
2924                    }
2925                }
2926            } else {
2927                // Process has activities, put it at the very tipsy-top.
2928                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
2929                mLruProcesses.add(app);
2930            }
2931            nextIndex = mLruProcessServiceStart;
2932        } else if (hasService) {
2933            // Process has services, put it at the top of the service list.
2934            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
2935            mLruProcesses.add(mLruProcessActivityStart, app);
2936            nextIndex = mLruProcessServiceStart;
2937            mLruProcessActivityStart++;
2938        } else  {
2939            // Process not otherwise of interest, it goes to the top of the non-service area.
2940            int index = mLruProcessServiceStart;
2941            if (client != null) {
2942                // If there is a client, don't allow the process to be moved up higher
2943                // in the list than that client.
2944                int clientIndex = mLruProcesses.lastIndexOf(client);
2945                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
2946                        + " when updating " + app);
2947                if (clientIndex <= lrui) {
2948                    // Don't allow the client index restriction to push it down farther in the
2949                    // list than it already is.
2950                    clientIndex = lrui;
2951                }
2952                if (clientIndex >= 0 && index > clientIndex) {
2953                    index = clientIndex;
2954                }
2955            }
2956            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
2957            mLruProcesses.add(index, app);
2958            nextIndex = index-1;
2959            mLruProcessActivityStart++;
2960            mLruProcessServiceStart++;
2961        }
2962
2963        // If the app is currently using a content provider or service,
2964        // bump those processes as well.
2965        for (int j=app.connections.size()-1; j>=0; j--) {
2966            ConnectionRecord cr = app.connections.valueAt(j);
2967            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2968                    && cr.binding.service.app != null
2969                    && cr.binding.service.app.lruSeq != mLruSeq
2970                    && !cr.binding.service.app.persistent) {
2971                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2972                        "service connection", cr, app);
2973            }
2974        }
2975        for (int j=app.conProviders.size()-1; j>=0; j--) {
2976            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2977            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2978                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2979                        "provider reference", cpr, app);
2980            }
2981        }
2982    }
2983
2984    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2985        if (uid == Process.SYSTEM_UID) {
2986            // The system gets to run in any process.  If there are multiple
2987            // processes with the same uid, just pick the first (this
2988            // should never happen).
2989            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2990            if (procs == null) return null;
2991            final int procCount = procs.size();
2992            for (int i = 0; i < procCount; i++) {
2993                final int procUid = procs.keyAt(i);
2994                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
2995                    // Don't use an app process or different user process for system component.
2996                    continue;
2997                }
2998                return procs.valueAt(i);
2999            }
3000        }
3001        ProcessRecord proc = mProcessNames.get(processName, uid);
3002        if (false && proc != null && !keepIfLarge
3003                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3004                && proc.lastCachedPss >= 4000) {
3005            // Turn this condition on to cause killing to happen regularly, for testing.
3006            if (proc.baseProcessTracker != null) {
3007                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3008            }
3009            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3010        } else if (proc != null && !keepIfLarge
3011                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3012                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3013            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3014            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3015                if (proc.baseProcessTracker != null) {
3016                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3017                }
3018                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3019            }
3020        }
3021        return proc;
3022    }
3023
3024    void ensurePackageDexOpt(String packageName) {
3025        IPackageManager pm = AppGlobals.getPackageManager();
3026        try {
3027            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
3028                mDidDexOpt = true;
3029            }
3030        } catch (RemoteException e) {
3031        }
3032    }
3033
3034    boolean isNextTransitionForward() {
3035        int transit = mWindowManager.getPendingAppTransition();
3036        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
3037                || transit == AppTransition.TRANSIT_TASK_OPEN
3038                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
3039    }
3040
3041    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3042            String processName, String abiOverride, int uid, Runnable crashHandler) {
3043        synchronized(this) {
3044            ApplicationInfo info = new ApplicationInfo();
3045            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3046            // For isolated processes, the former contains the parent's uid and the latter the
3047            // actual uid of the isolated process.
3048            // In the special case introduced by this method (which is, starting an isolated
3049            // process directly from the SystemServer without an actual parent app process) the
3050            // closest thing to a parent's uid is SYSTEM_UID.
3051            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3052            // the |isolated| logic in the ProcessRecord constructor.
3053            info.uid = Process.SYSTEM_UID;
3054            info.processName = processName;
3055            info.className = entryPoint;
3056            info.packageName = "android";
3057            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3058                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3059                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3060                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3061                    crashHandler);
3062            return proc != null ? proc.pid : 0;
3063        }
3064    }
3065
3066    final ProcessRecord startProcessLocked(String processName,
3067            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3068            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3069            boolean isolated, boolean keepIfLarge) {
3070        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3071                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3072                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3073                null /* crashHandler */);
3074    }
3075
3076    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3077            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3078            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3079            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3080        long startTime = SystemClock.elapsedRealtime();
3081        ProcessRecord app;
3082        if (!isolated) {
3083            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3084            checkTime(startTime, "startProcess: after getProcessRecord");
3085
3086            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3087                // If we are in the background, then check to see if this process
3088                // is bad.  If so, we will just silently fail.
3089                if (mBadProcesses.get(info.processName, info.uid) != null) {
3090                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3091                            + "/" + info.processName);
3092                    return null;
3093                }
3094            } else {
3095                // When the user is explicitly starting a process, then clear its
3096                // crash count so that we won't make it bad until they see at
3097                // least one crash dialog again, and make the process good again
3098                // if it had been bad.
3099                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3100                        + "/" + info.processName);
3101                mProcessCrashTimes.remove(info.processName, info.uid);
3102                if (mBadProcesses.get(info.processName, info.uid) != null) {
3103                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3104                            UserHandle.getUserId(info.uid), info.uid,
3105                            info.processName);
3106                    mBadProcesses.remove(info.processName, info.uid);
3107                    if (app != null) {
3108                        app.bad = false;
3109                    }
3110                }
3111            }
3112        } else {
3113            // If this is an isolated process, it can't re-use an existing process.
3114            app = null;
3115        }
3116
3117        // We don't have to do anything more if:
3118        // (1) There is an existing application record; and
3119        // (2) The caller doesn't think it is dead, OR there is no thread
3120        //     object attached to it so we know it couldn't have crashed; and
3121        // (3) There is a pid assigned to it, so it is either starting or
3122        //     already running.
3123        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3124                + " app=" + app + " knownToBeDead=" + knownToBeDead
3125                + " thread=" + (app != null ? app.thread : null)
3126                + " pid=" + (app != null ? app.pid : -1));
3127        if (app != null && app.pid > 0) {
3128            if (!knownToBeDead || app.thread == null) {
3129                // We already have the app running, or are waiting for it to
3130                // come up (we have a pid but not yet its thread), so keep it.
3131                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3132                // If this is a new package in the process, add the package to the list
3133                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3134                checkTime(startTime, "startProcess: done, added package to proc");
3135                return app;
3136            }
3137
3138            // An application record is attached to a previous process,
3139            // clean it up now.
3140            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3141            checkTime(startTime, "startProcess: bad proc running, killing");
3142            killProcessGroup(app.info.uid, app.pid);
3143            handleAppDiedLocked(app, true, true);
3144            checkTime(startTime, "startProcess: done killing old proc");
3145        }
3146
3147        String hostingNameStr = hostingName != null
3148                ? hostingName.flattenToShortString() : null;
3149
3150        if (app == null) {
3151            checkTime(startTime, "startProcess: creating new process record");
3152            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3153            if (app == null) {
3154                Slog.w(TAG, "Failed making new process record for "
3155                        + processName + "/" + info.uid + " isolated=" + isolated);
3156                return null;
3157            }
3158            app.crashHandler = crashHandler;
3159            checkTime(startTime, "startProcess: done creating new process record");
3160        } else {
3161            // If this is a new package in the process, add the package to the list
3162            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3163            checkTime(startTime, "startProcess: added package to existing proc");
3164        }
3165
3166        // If the system is not ready yet, then hold off on starting this
3167        // process until it is.
3168        if (!mProcessesReady
3169                && !isAllowedWhileBooting(info)
3170                && !allowWhileBooting) {
3171            if (!mProcessesOnHold.contains(app)) {
3172                mProcessesOnHold.add(app);
3173            }
3174            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3175                    "System not ready, putting on hold: " + app);
3176            checkTime(startTime, "startProcess: returning with proc on hold");
3177            return app;
3178        }
3179
3180        checkTime(startTime, "startProcess: stepping in to startProcess");
3181        startProcessLocked(
3182                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3183        checkTime(startTime, "startProcess: done starting proc!");
3184        return (app.pid != 0) ? app : null;
3185    }
3186
3187    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3188        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3189    }
3190
3191    private final void startProcessLocked(ProcessRecord app,
3192            String hostingType, String hostingNameStr) {
3193        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3194                null /* entryPoint */, null /* entryPointArgs */);
3195    }
3196
3197    private final void startProcessLocked(ProcessRecord app, String hostingType,
3198            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3199        long startTime = SystemClock.elapsedRealtime();
3200        if (app.pid > 0 && app.pid != MY_PID) {
3201            checkTime(startTime, "startProcess: removing from pids map");
3202            synchronized (mPidsSelfLocked) {
3203                mPidsSelfLocked.remove(app.pid);
3204                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3205            }
3206            checkTime(startTime, "startProcess: done removing from pids map");
3207            app.setPid(0);
3208        }
3209
3210        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3211                "startProcessLocked removing on hold: " + app);
3212        mProcessesOnHold.remove(app);
3213
3214        checkTime(startTime, "startProcess: starting to update cpu stats");
3215        updateCpuStats();
3216        checkTime(startTime, "startProcess: done updating cpu stats");
3217
3218        try {
3219            try {
3220                if (AppGlobals.getPackageManager().isPackageFrozen(app.info.packageName)) {
3221                    // This is caught below as if we had failed to fork zygote
3222                    throw new RuntimeException("Package " + app.info.packageName + " is frozen!");
3223                }
3224            } catch (RemoteException e) {
3225                throw e.rethrowAsRuntimeException();
3226            }
3227
3228            int uid = app.uid;
3229            int[] gids = null;
3230            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3231            if (!app.isolated) {
3232                int[] permGids = null;
3233                try {
3234                    checkTime(startTime, "startProcess: getting gids from package manager");
3235                    final IPackageManager pm = AppGlobals.getPackageManager();
3236                    permGids = pm.getPackageGids(app.info.packageName, app.userId);
3237                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3238                            MountServiceInternal.class);
3239                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3240                            app.info.packageName);
3241                } catch (RemoteException e) {
3242                    throw e.rethrowAsRuntimeException();
3243                }
3244
3245                /*
3246                 * Add shared application and profile GIDs so applications can share some
3247                 * resources like shared libraries and access user-wide resources
3248                 */
3249                if (ArrayUtils.isEmpty(permGids)) {
3250                    gids = new int[2];
3251                } else {
3252                    gids = new int[permGids.length + 2];
3253                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3254                }
3255                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3256                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3257            }
3258            checkTime(startTime, "startProcess: building args");
3259            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3260                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3261                        && mTopComponent != null
3262                        && app.processName.equals(mTopComponent.getPackageName())) {
3263                    uid = 0;
3264                }
3265                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3266                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3267                    uid = 0;
3268                }
3269            }
3270            int debugFlags = 0;
3271            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3272                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3273                // Also turn on CheckJNI for debuggable apps. It's quite
3274                // awkward to turn on otherwise.
3275                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3276            }
3277            // Run the app in safe mode if its manifest requests so or the
3278            // system is booted in safe mode.
3279            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3280                mSafeMode == true) {
3281                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3282            }
3283            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3284                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3285            }
3286            String jitDebugProperty = SystemProperties.get("debug.usejit");
3287            if ("true".equals(jitDebugProperty)) {
3288                debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3289            } else if (!"false".equals(jitDebugProperty)) {
3290                // If we didn't force disable by setting false, defer to the dalvik vm options.
3291                if ("true".equals(SystemProperties.get("dalvik.vm.usejit"))) {
3292                    debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3293                }
3294            }
3295            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3296            if ("true".equals(genDebugInfoProperty)) {
3297                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3298            }
3299            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3300                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3301            }
3302            if ("1".equals(SystemProperties.get("debug.assert"))) {
3303                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3304            }
3305
3306            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3307            if (requiredAbi == null) {
3308                requiredAbi = Build.SUPPORTED_ABIS[0];
3309            }
3310
3311            String instructionSet = null;
3312            if (app.info.primaryCpuAbi != null) {
3313                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3314            }
3315
3316            app.gids = gids;
3317            app.requiredAbi = requiredAbi;
3318            app.instructionSet = instructionSet;
3319
3320            // Start the process.  It will either succeed and return a result containing
3321            // the PID of the new process, or else throw a RuntimeException.
3322            boolean isActivityProcess = (entryPoint == null);
3323            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3324            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3325                    app.processName);
3326            checkTime(startTime, "startProcess: asking zygote to start proc");
3327            Process.ProcessStartResult startResult = Process.start(entryPoint,
3328                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3329                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3330                    app.info.dataDir, entryPointArgs);
3331            checkTime(startTime, "startProcess: returned from zygote!");
3332            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3333
3334            if (app.isolated) {
3335                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3336            }
3337            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3338            checkTime(startTime, "startProcess: done updating battery stats");
3339
3340            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3341                    UserHandle.getUserId(uid), startResult.pid, uid,
3342                    app.processName, hostingType,
3343                    hostingNameStr != null ? hostingNameStr : "");
3344
3345            if (app.persistent) {
3346                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3347            }
3348
3349            checkTime(startTime, "startProcess: building log message");
3350            StringBuilder buf = mStringBuilder;
3351            buf.setLength(0);
3352            buf.append("Start proc ");
3353            buf.append(startResult.pid);
3354            buf.append(':');
3355            buf.append(app.processName);
3356            buf.append('/');
3357            UserHandle.formatUid(buf, uid);
3358            if (!isActivityProcess) {
3359                buf.append(" [");
3360                buf.append(entryPoint);
3361                buf.append("]");
3362            }
3363            buf.append(" for ");
3364            buf.append(hostingType);
3365            if (hostingNameStr != null) {
3366                buf.append(" ");
3367                buf.append(hostingNameStr);
3368            }
3369            Slog.i(TAG, buf.toString());
3370            app.setPid(startResult.pid);
3371            app.usingWrapper = startResult.usingWrapper;
3372            app.removed = false;
3373            app.killed = false;
3374            app.killedByAm = false;
3375            checkTime(startTime, "startProcess: starting to update pids map");
3376            synchronized (mPidsSelfLocked) {
3377                this.mPidsSelfLocked.put(startResult.pid, app);
3378                if (isActivityProcess) {
3379                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3380                    msg.obj = app;
3381                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3382                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3383                }
3384            }
3385            checkTime(startTime, "startProcess: done updating pids map");
3386        } catch (RuntimeException e) {
3387            // XXX do better error recovery.
3388            app.setPid(0);
3389            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3390            if (app.isolated) {
3391                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3392            }
3393            Slog.e(TAG, "Failure starting process " + app.processName, e);
3394        }
3395    }
3396
3397    void updateUsageStats(ActivityRecord component, boolean resumed) {
3398        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3399                "updateUsageStats: comp=" + component + "res=" + resumed);
3400        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3401        if (resumed) {
3402            if (mUsageStatsService != null) {
3403                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3404                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3405            }
3406            synchronized (stats) {
3407                stats.noteActivityResumedLocked(component.app.uid);
3408            }
3409        } else {
3410            if (mUsageStatsService != null) {
3411                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3412                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3413            }
3414            synchronized (stats) {
3415                stats.noteActivityPausedLocked(component.app.uid);
3416            }
3417        }
3418    }
3419
3420    Intent getHomeIntent() {
3421        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3422        intent.setComponent(mTopComponent);
3423        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3424            intent.addCategory(Intent.CATEGORY_HOME);
3425        }
3426        return intent;
3427    }
3428
3429    boolean startHomeActivityLocked(int userId, String reason) {
3430        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3431                && mTopAction == null) {
3432            // We are running in factory test mode, but unable to find
3433            // the factory test app, so just sit around displaying the
3434            // error message and don't try to start anything.
3435            return false;
3436        }
3437        Intent intent = getHomeIntent();
3438        ActivityInfo aInfo =
3439            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3440        if (aInfo != null) {
3441            intent.setComponent(new ComponentName(
3442                    aInfo.applicationInfo.packageName, aInfo.name));
3443            // Don't do this if the home app is currently being
3444            // instrumented.
3445            aInfo = new ActivityInfo(aInfo);
3446            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3447            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3448                    aInfo.applicationInfo.uid, true);
3449            if (app == null || app.instrumentationClass == null) {
3450                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3451                mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3452            }
3453        }
3454
3455        return true;
3456    }
3457
3458    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3459        ActivityInfo ai = null;
3460        ComponentName comp = intent.getComponent();
3461        try {
3462            if (comp != null) {
3463                // Factory test.
3464                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3465            } else {
3466                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3467                        intent,
3468                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3469                        flags, userId);
3470
3471                if (info != null) {
3472                    ai = info.activityInfo;
3473                }
3474            }
3475        } catch (RemoteException e) {
3476            // ignore
3477        }
3478
3479        return ai;
3480    }
3481
3482    /**
3483     * Starts the "new version setup screen" if appropriate.
3484     */
3485    void startSetupActivityLocked() {
3486        // Only do this once per boot.
3487        if (mCheckedForSetup) {
3488            return;
3489        }
3490
3491        // We will show this screen if the current one is a different
3492        // version than the last one shown, and we are not running in
3493        // low-level factory test mode.
3494        final ContentResolver resolver = mContext.getContentResolver();
3495        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3496                Settings.Global.getInt(resolver,
3497                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3498            mCheckedForSetup = true;
3499
3500            // See if we should be showing the platform update setup UI.
3501            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3502            List<ResolveInfo> ris = mContext.getPackageManager()
3503                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3504
3505            // We don't allow third party apps to replace this.
3506            ResolveInfo ri = null;
3507            for (int i=0; ris != null && i<ris.size(); i++) {
3508                if ((ris.get(i).activityInfo.applicationInfo.flags
3509                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3510                    ri = ris.get(i);
3511                    break;
3512                }
3513            }
3514
3515            if (ri != null) {
3516                String vers = ri.activityInfo.metaData != null
3517                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3518                        : null;
3519                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3520                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3521                            Intent.METADATA_SETUP_VERSION);
3522                }
3523                String lastVers = Settings.Secure.getString(
3524                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3525                if (vers != null && !vers.equals(lastVers)) {
3526                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3527                    intent.setComponent(new ComponentName(
3528                            ri.activityInfo.packageName, ri.activityInfo.name));
3529                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3530                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, false,
3531                            null, null, null);
3532                }
3533            }
3534        }
3535    }
3536
3537    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3538        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3539    }
3540
3541    void enforceNotIsolatedCaller(String caller) {
3542        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3543            throw new SecurityException("Isolated process not allowed to call " + caller);
3544        }
3545    }
3546
3547    void enforceShellRestriction(String restriction, int userHandle) {
3548        if (Binder.getCallingUid() == Process.SHELL_UID) {
3549            if (userHandle < 0
3550                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3551                throw new SecurityException("Shell does not have permission to access user "
3552                        + userHandle);
3553            }
3554        }
3555    }
3556
3557    @Override
3558    public int getFrontActivityScreenCompatMode() {
3559        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3560        synchronized (this) {
3561            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3562        }
3563    }
3564
3565    @Override
3566    public void setFrontActivityScreenCompatMode(int mode) {
3567        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3568                "setFrontActivityScreenCompatMode");
3569        synchronized (this) {
3570            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3571        }
3572    }
3573
3574    @Override
3575    public int getPackageScreenCompatMode(String packageName) {
3576        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3577        synchronized (this) {
3578            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3579        }
3580    }
3581
3582    @Override
3583    public void setPackageScreenCompatMode(String packageName, int mode) {
3584        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3585                "setPackageScreenCompatMode");
3586        synchronized (this) {
3587            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3588        }
3589    }
3590
3591    @Override
3592    public boolean getPackageAskScreenCompat(String packageName) {
3593        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3594        synchronized (this) {
3595            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3596        }
3597    }
3598
3599    @Override
3600    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3601        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3602                "setPackageAskScreenCompat");
3603        synchronized (this) {
3604            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3605        }
3606    }
3607
3608    private boolean hasUsageStatsPermission(String callingPackage) {
3609        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3610                Binder.getCallingUid(), callingPackage);
3611        if (mode == AppOpsManager.MODE_DEFAULT) {
3612            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3613                    == PackageManager.PERMISSION_GRANTED;
3614        }
3615        return mode == AppOpsManager.MODE_ALLOWED;
3616    }
3617
3618    @Override
3619    public int getPackageProcessState(String packageName, String callingPackage) {
3620        if (!hasUsageStatsPermission(callingPackage)) {
3621            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3622                    "getPackageProcessState");
3623        }
3624
3625        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3626        synchronized (this) {
3627            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3628                final ProcessRecord proc = mLruProcesses.get(i);
3629                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3630                        || procState > proc.setProcState) {
3631                    boolean found = false;
3632                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3633                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3634                            procState = proc.setProcState;
3635                            found = true;
3636                        }
3637                    }
3638                    if (proc.pkgDeps != null && !found) {
3639                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3640                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3641                                procState = proc.setProcState;
3642                                break;
3643                            }
3644                        }
3645                    }
3646                }
3647            }
3648        }
3649        return procState;
3650    }
3651
3652    @Override
3653    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3654        synchronized (this) {
3655            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3656            if (app == null) {
3657                return false;
3658            }
3659            if (app.trimMemoryLevel < level && app.thread != null &&
3660                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3661                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3662                try {
3663                    app.thread.scheduleTrimMemory(level);
3664                    app.trimMemoryLevel = level;
3665                    return true;
3666                } catch (RemoteException e) {
3667                    // Fallthrough to failure case.
3668                }
3669            }
3670        }
3671        return false;
3672    }
3673
3674    private void dispatchProcessesChanged() {
3675        int N;
3676        synchronized (this) {
3677            N = mPendingProcessChanges.size();
3678            if (mActiveProcessChanges.length < N) {
3679                mActiveProcessChanges = new ProcessChangeItem[N];
3680            }
3681            mPendingProcessChanges.toArray(mActiveProcessChanges);
3682            mPendingProcessChanges.clear();
3683            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3684                    "*** Delivering " + N + " process changes");
3685        }
3686
3687        int i = mProcessObservers.beginBroadcast();
3688        while (i > 0) {
3689            i--;
3690            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3691            if (observer != null) {
3692                try {
3693                    for (int j=0; j<N; j++) {
3694                        ProcessChangeItem item = mActiveProcessChanges[j];
3695                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3696                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3697                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3698                                    + item.uid + ": " + item.foregroundActivities);
3699                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3700                                    item.foregroundActivities);
3701                        }
3702                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3703                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3704                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3705                                    + ": " + item.processState);
3706                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3707                        }
3708                    }
3709                } catch (RemoteException e) {
3710                }
3711            }
3712        }
3713        mProcessObservers.finishBroadcast();
3714
3715        synchronized (this) {
3716            for (int j=0; j<N; j++) {
3717                mAvailProcessChanges.add(mActiveProcessChanges[j]);
3718            }
3719        }
3720    }
3721
3722    private void dispatchProcessDied(int pid, int uid) {
3723        int i = mProcessObservers.beginBroadcast();
3724        while (i > 0) {
3725            i--;
3726            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3727            if (observer != null) {
3728                try {
3729                    observer.onProcessDied(pid, uid);
3730                } catch (RemoteException e) {
3731                }
3732            }
3733        }
3734        mProcessObservers.finishBroadcast();
3735    }
3736
3737    private void dispatchUidsChanged() {
3738        int N;
3739        synchronized (this) {
3740            N = mPendingUidChanges.size();
3741            if (mActiveUidChanges.length < N) {
3742                mActiveUidChanges = new UidRecord.ChangeItem[N];
3743            }
3744            for (int i=0; i<N; i++) {
3745                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3746                mActiveUidChanges[i] = change;
3747                change.uidRecord.pendingChange = null;
3748                change.uidRecord = null;
3749            }
3750            mPendingUidChanges.clear();
3751            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3752                    "*** Delivering " + N + " uid changes");
3753        }
3754
3755        if (mLocalPowerManager != null) {
3756            for (int j=0; j<N; j++) {
3757                UidRecord.ChangeItem item = mActiveUidChanges[j];
3758                if (item.gone) {
3759                    mLocalPowerManager.uidGone(item.uid);
3760                } else {
3761                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
3762                }
3763            }
3764        }
3765
3766        int i = mUidObservers.beginBroadcast();
3767        while (i > 0) {
3768            i--;
3769            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
3770            if (observer != null) {
3771                try {
3772                    for (int j=0; j<N; j++) {
3773                        UidRecord.ChangeItem item = mActiveUidChanges[j];
3774                        if (item.gone) {
3775                            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3776                                    "UID gone uid=" + item.uid);
3777                            observer.onUidGone(item.uid);
3778                        } else {
3779                            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3780                                    "UID CHANGED uid=" + item.uid
3781                                    + ": " + item.processState);
3782                            observer.onUidStateChanged(item.uid, item.processState);
3783                        }
3784                    }
3785                } catch (RemoteException e) {
3786                }
3787            }
3788        }
3789        mUidObservers.finishBroadcast();
3790
3791        synchronized (this) {
3792            for (int j=0; j<N; j++) {
3793                mAvailUidChanges.add(mActiveUidChanges[j]);
3794            }
3795        }
3796    }
3797
3798    @Override
3799    public final int startActivity(IApplicationThread caller, String callingPackage,
3800            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3801            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3802        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3803            resultWho, requestCode, startFlags, profilerInfo, options,
3804            UserHandle.getCallingUserId());
3805    }
3806
3807    @Override
3808    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3809            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3810            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3811        enforceNotIsolatedCaller("startActivity");
3812        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3813                false, ALLOW_FULL_ONLY, "startActivity", null);
3814        // TODO: Switch to user app stacks here.
3815        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3816                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3817                profilerInfo, null, null, options, false, userId, null, null);
3818    }
3819
3820    @Override
3821    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3822            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3823            int startFlags, ProfilerInfo profilerInfo, Bundle options, boolean ignoreTargetSecurity,
3824            int userId) {
3825
3826        // This is very dangerous -- it allows you to perform a start activity (including
3827        // permission grants) as any app that may launch one of your own activities.  So
3828        // we will only allow this to be done from activities that are part of the core framework,
3829        // and then only when they are running as the system.
3830        final ActivityRecord sourceRecord;
3831        final int targetUid;
3832        final String targetPackage;
3833        synchronized (this) {
3834            if (resultTo == null) {
3835                throw new SecurityException("Must be called from an activity");
3836            }
3837            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3838            if (sourceRecord == null) {
3839                throw new SecurityException("Called with bad activity token: " + resultTo);
3840            }
3841            if (!sourceRecord.info.packageName.equals("android")) {
3842                throw new SecurityException(
3843                        "Must be called from an activity that is declared in the android package");
3844            }
3845            if (sourceRecord.app == null) {
3846                throw new SecurityException("Called without a process attached to activity");
3847            }
3848            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3849                // This is still okay, as long as this activity is running under the
3850                // uid of the original calling activity.
3851                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3852                    throw new SecurityException(
3853                            "Calling activity in uid " + sourceRecord.app.uid
3854                                    + " must be system uid or original calling uid "
3855                                    + sourceRecord.launchedFromUid);
3856                }
3857            }
3858            if (ignoreTargetSecurity) {
3859                if (intent.getComponent() == null) {
3860                    throw new SecurityException(
3861                            "Component must be specified with ignoreTargetSecurity");
3862                }
3863                if (intent.getSelector() != null) {
3864                    throw new SecurityException(
3865                            "Selector not allowed with ignoreTargetSecurity");
3866                }
3867            }
3868            targetUid = sourceRecord.launchedFromUid;
3869            targetPackage = sourceRecord.launchedFromPackage;
3870        }
3871
3872        if (userId == UserHandle.USER_NULL) {
3873            userId = UserHandle.getUserId(sourceRecord.app.uid);
3874        }
3875
3876        // TODO: Switch to user app stacks here.
3877        try {
3878            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3879                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3880                    null, null, options, ignoreTargetSecurity, userId, null, null);
3881            return ret;
3882        } catch (SecurityException e) {
3883            // XXX need to figure out how to propagate to original app.
3884            // A SecurityException here is generally actually a fault of the original
3885            // calling activity (such as a fairly granting permissions), so propagate it
3886            // back to them.
3887            /*
3888            StringBuilder msg = new StringBuilder();
3889            msg.append("While launching");
3890            msg.append(intent.toString());
3891            msg.append(": ");
3892            msg.append(e.getMessage());
3893            */
3894            throw e;
3895        }
3896    }
3897
3898    @Override
3899    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3900            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3901            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3902        enforceNotIsolatedCaller("startActivityAndWait");
3903        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3904                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3905        WaitResult res = new WaitResult();
3906        // TODO: Switch to user app stacks here.
3907        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3908                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3909                options, false, userId, null, null);
3910        return res;
3911    }
3912
3913    @Override
3914    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3915            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3916            int startFlags, Configuration config, Bundle options, int userId) {
3917        enforceNotIsolatedCaller("startActivityWithConfig");
3918        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3919                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3920        // TODO: Switch to user app stacks here.
3921        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3922                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3923                null, null, config, options, false, userId, null, null);
3924        return ret;
3925    }
3926
3927    @Override
3928    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
3929            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
3930            int requestCode, int flagsMask, int flagsValues, Bundle options)
3931            throws TransactionTooLargeException {
3932        enforceNotIsolatedCaller("startActivityIntentSender");
3933        // Refuse possible leaked file descriptors
3934        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3935            throw new IllegalArgumentException("File descriptors passed in Intent");
3936        }
3937
3938        IIntentSender sender = intent.getTarget();
3939        if (!(sender instanceof PendingIntentRecord)) {
3940            throw new IllegalArgumentException("Bad PendingIntent object");
3941        }
3942
3943        PendingIntentRecord pir = (PendingIntentRecord)sender;
3944
3945        synchronized (this) {
3946            // If this is coming from the currently resumed activity, it is
3947            // effectively saying that app switches are allowed at this point.
3948            final ActivityStack stack = getFocusedStack();
3949            if (stack.mResumedActivity != null &&
3950                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3951                mAppSwitchesAllowedTime = 0;
3952            }
3953        }
3954        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3955                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3956        return ret;
3957    }
3958
3959    @Override
3960    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3961            Intent intent, String resolvedType, IVoiceInteractionSession session,
3962            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3963            Bundle options, int userId) {
3964        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3965                != PackageManager.PERMISSION_GRANTED) {
3966            String msg = "Permission Denial: startVoiceActivity() from pid="
3967                    + Binder.getCallingPid()
3968                    + ", uid=" + Binder.getCallingUid()
3969                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3970            Slog.w(TAG, msg);
3971            throw new SecurityException(msg);
3972        }
3973        if (session == null || interactor == null) {
3974            throw new NullPointerException("null session or interactor");
3975        }
3976        userId = handleIncomingUser(callingPid, callingUid, userId,
3977                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3978        // TODO: Switch to user app stacks here.
3979        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3980                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3981                null, options, false, userId, null, null);
3982    }
3983
3984    @Override
3985    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
3986        synchronized (this) {
3987            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
3988                if (keepAwake) {
3989                    mVoiceWakeLock.acquire();
3990                } else {
3991                    mVoiceWakeLock.release();
3992                }
3993            }
3994        }
3995    }
3996
3997    @Override
3998    public boolean startNextMatchingActivity(IBinder callingActivity,
3999            Intent intent, Bundle options) {
4000        // Refuse possible leaked file descriptors
4001        if (intent != null && intent.hasFileDescriptors() == true) {
4002            throw new IllegalArgumentException("File descriptors passed in Intent");
4003        }
4004
4005        synchronized (this) {
4006            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4007            if (r == null) {
4008                ActivityOptions.abort(options);
4009                return false;
4010            }
4011            if (r.app == null || r.app.thread == null) {
4012                // The caller is not running...  d'oh!
4013                ActivityOptions.abort(options);
4014                return false;
4015            }
4016            intent = new Intent(intent);
4017            // The caller is not allowed to change the data.
4018            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4019            // And we are resetting to find the next component...
4020            intent.setComponent(null);
4021
4022            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4023
4024            ActivityInfo aInfo = null;
4025            try {
4026                List<ResolveInfo> resolves =
4027                    AppGlobals.getPackageManager().queryIntentActivities(
4028                            intent, r.resolvedType,
4029                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4030                            UserHandle.getCallingUserId());
4031
4032                // Look for the original activity in the list...
4033                final int N = resolves != null ? resolves.size() : 0;
4034                for (int i=0; i<N; i++) {
4035                    ResolveInfo rInfo = resolves.get(i);
4036                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4037                            && rInfo.activityInfo.name.equals(r.info.name)) {
4038                        // We found the current one...  the next matching is
4039                        // after it.
4040                        i++;
4041                        if (i<N) {
4042                            aInfo = resolves.get(i).activityInfo;
4043                        }
4044                        if (debug) {
4045                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4046                                    + "/" + r.info.name);
4047                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
4048                                    + "/" + aInfo.name);
4049                        }
4050                        break;
4051                    }
4052                }
4053            } catch (RemoteException e) {
4054            }
4055
4056            if (aInfo == null) {
4057                // Nobody who is next!
4058                ActivityOptions.abort(options);
4059                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4060                return false;
4061            }
4062
4063            intent.setComponent(new ComponentName(
4064                    aInfo.applicationInfo.packageName, aInfo.name));
4065            intent.setFlags(intent.getFlags()&~(
4066                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4067                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4068                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4069                    Intent.FLAG_ACTIVITY_NEW_TASK));
4070
4071            // Okay now we need to start the new activity, replacing the
4072            // currently running activity.  This is a little tricky because
4073            // we want to start the new one as if the current one is finished,
4074            // but not finish the current one first so that there is no flicker.
4075            // And thus...
4076            final boolean wasFinishing = r.finishing;
4077            r.finishing = true;
4078
4079            // Propagate reply information over to the new activity.
4080            final ActivityRecord resultTo = r.resultTo;
4081            final String resultWho = r.resultWho;
4082            final int requestCode = r.requestCode;
4083            r.resultTo = null;
4084            if (resultTo != null) {
4085                resultTo.removeResultsLocked(r, resultWho, requestCode);
4086            }
4087
4088            final long origId = Binder.clearCallingIdentity();
4089            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
4090                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
4091                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
4092                    -1, r.launchedFromUid, 0, options, false, false, null, null, null);
4093            Binder.restoreCallingIdentity(origId);
4094
4095            r.finishing = wasFinishing;
4096            if (res != ActivityManager.START_SUCCESS) {
4097                return false;
4098            }
4099            return true;
4100        }
4101    }
4102
4103    @Override
4104    public final int startActivityFromRecents(int taskId, Bundle options) {
4105        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4106            String msg = "Permission Denial: startActivityFromRecents called without " +
4107                    START_TASKS_FROM_RECENTS;
4108            Slog.w(TAG, msg);
4109            throw new SecurityException(msg);
4110        }
4111        return startActivityFromRecentsInner(taskId, options);
4112    }
4113
4114    final int startActivityFromRecentsInner(int taskId, Bundle options) {
4115        final TaskRecord task;
4116        final int callingUid;
4117        final String callingPackage;
4118        final Intent intent;
4119        final int userId;
4120        synchronized (this) {
4121            task = mRecentTasks.taskForIdLocked(taskId);
4122            if (task == null) {
4123                throw new IllegalArgumentException("Task " + taskId + " not found.");
4124            }
4125            if (task.getRootActivity() != null) {
4126                moveTaskToFrontLocked(task.taskId, 0, null);
4127                return ActivityManager.START_TASK_TO_FRONT;
4128            }
4129            callingUid = task.mCallingUid;
4130            callingPackage = task.mCallingPackage;
4131            intent = task.intent;
4132            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4133            userId = task.userId;
4134        }
4135        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4136                options, userId, null, task);
4137    }
4138
4139    final int startActivityInPackage(int uid, String callingPackage,
4140            Intent intent, String resolvedType, IBinder resultTo,
4141            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
4142            IActivityContainer container, TaskRecord inTask) {
4143
4144        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4145                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4146
4147        // TODO: Switch to user app stacks here.
4148        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
4149                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4150                null, null, null, options, false, userId, container, inTask);
4151        return ret;
4152    }
4153
4154    @Override
4155    public final int startActivities(IApplicationThread caller, String callingPackage,
4156            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
4157            int userId) {
4158        enforceNotIsolatedCaller("startActivities");
4159        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4160                false, ALLOW_FULL_ONLY, "startActivity", null);
4161        // TODO: Switch to user app stacks here.
4162        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
4163                resolvedTypes, resultTo, options, userId);
4164        return ret;
4165    }
4166
4167    final int startActivitiesInPackage(int uid, String callingPackage,
4168            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4169            Bundle options, int userId) {
4170
4171        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4172                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4173        // TODO: Switch to user app stacks here.
4174        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4175                resultTo, options, userId);
4176        return ret;
4177    }
4178
4179    @Override
4180    public void reportActivityFullyDrawn(IBinder token) {
4181        synchronized (this) {
4182            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4183            if (r == null) {
4184                return;
4185            }
4186            r.reportFullyDrawnLocked();
4187        }
4188    }
4189
4190    @Override
4191    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4192        synchronized (this) {
4193            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4194            if (r == null) {
4195                return;
4196            }
4197            if (r.task != null && r.task.mResizeable) {
4198                // Fixed screen orientation isn't supported with resizeable activities.
4199                return;
4200            }
4201            final long origId = Binder.clearCallingIdentity();
4202            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4203            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4204                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4205            if (config != null) {
4206                r.frozenBeforeDestroy = true;
4207                if (!updateConfigurationLocked(config, r, false, false)) {
4208                    mStackSupervisor.resumeTopActivitiesLocked();
4209                }
4210            }
4211            Binder.restoreCallingIdentity(origId);
4212        }
4213    }
4214
4215    @Override
4216    public int getRequestedOrientation(IBinder token) {
4217        synchronized (this) {
4218            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4219            if (r == null) {
4220                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4221            }
4222            return mWindowManager.getAppOrientation(r.appToken);
4223        }
4224    }
4225
4226    /**
4227     * This is the internal entry point for handling Activity.finish().
4228     *
4229     * @param token The Binder token referencing the Activity we want to finish.
4230     * @param resultCode Result code, if any, from this Activity.
4231     * @param resultData Result data (Intent), if any, from this Activity.
4232     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4233     *            the root Activity in the task.
4234     *
4235     * @return Returns true if the activity successfully finished, or false if it is still running.
4236     */
4237    @Override
4238    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4239            boolean finishTask) {
4240        // Refuse possible leaked file descriptors
4241        if (resultData != null && resultData.hasFileDescriptors() == true) {
4242            throw new IllegalArgumentException("File descriptors passed in Intent");
4243        }
4244
4245        synchronized(this) {
4246            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4247            if (r == null) {
4248                return true;
4249            }
4250            // Keep track of the root activity of the task before we finish it
4251            TaskRecord tr = r.task;
4252            ActivityRecord rootR = tr.getRootActivity();
4253            if (rootR == null) {
4254                Slog.w(TAG, "Finishing task with all activities already finished");
4255            }
4256            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4257            // finish.
4258            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4259                    mStackSupervisor.isLastLockedTask(tr)) {
4260                Slog.i(TAG, "Not finishing task in lock task mode");
4261                mStackSupervisor.showLockTaskToast();
4262                return false;
4263            }
4264            if (mController != null) {
4265                // Find the first activity that is not finishing.
4266                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4267                if (next != null) {
4268                    // ask watcher if this is allowed
4269                    boolean resumeOK = true;
4270                    try {
4271                        resumeOK = mController.activityResuming(next.packageName);
4272                    } catch (RemoteException e) {
4273                        mController = null;
4274                        Watchdog.getInstance().setActivityController(null);
4275                    }
4276
4277                    if (!resumeOK) {
4278                        Slog.i(TAG, "Not finishing activity because controller resumed");
4279                        return false;
4280                    }
4281                }
4282            }
4283            final long origId = Binder.clearCallingIdentity();
4284            try {
4285                boolean res;
4286                if (finishTask && r == rootR) {
4287                    // If requested, remove the task that is associated to this activity only if it
4288                    // was the root activity in the task. The result code and data is ignored
4289                    // because we don't support returning them across task boundaries.
4290                    res = removeTaskByIdLocked(tr.taskId, false);
4291                    if (!res) {
4292                        Slog.i(TAG, "Removing task failed to finish activity");
4293                    }
4294                } else {
4295                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4296                            resultData, "app-request", true);
4297                    if (!res) {
4298                        Slog.i(TAG, "Failed to finish by app-request");
4299                    }
4300                }
4301                return res;
4302            } finally {
4303                Binder.restoreCallingIdentity(origId);
4304            }
4305        }
4306    }
4307
4308    @Override
4309    public final void finishHeavyWeightApp() {
4310        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4311                != PackageManager.PERMISSION_GRANTED) {
4312            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4313                    + Binder.getCallingPid()
4314                    + ", uid=" + Binder.getCallingUid()
4315                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4316            Slog.w(TAG, msg);
4317            throw new SecurityException(msg);
4318        }
4319
4320        synchronized(this) {
4321            if (mHeavyWeightProcess == null) {
4322                return;
4323            }
4324
4325            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4326            for (int i = 0; i < activities.size(); i++) {
4327                ActivityRecord r = activities.get(i);
4328                if (!r.finishing && r.isInStackLocked()) {
4329                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4330                            null, "finish-heavy", true);
4331                }
4332            }
4333
4334            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4335                    mHeavyWeightProcess.userId, 0));
4336            mHeavyWeightProcess = null;
4337        }
4338    }
4339
4340    @Override
4341    public void crashApplication(int uid, int initialPid, String packageName,
4342            String message) {
4343        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4344                != PackageManager.PERMISSION_GRANTED) {
4345            String msg = "Permission Denial: crashApplication() from pid="
4346                    + Binder.getCallingPid()
4347                    + ", uid=" + Binder.getCallingUid()
4348                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4349            Slog.w(TAG, msg);
4350            throw new SecurityException(msg);
4351        }
4352
4353        synchronized(this) {
4354            ProcessRecord proc = null;
4355
4356            // Figure out which process to kill.  We don't trust that initialPid
4357            // still has any relation to current pids, so must scan through the
4358            // list.
4359            synchronized (mPidsSelfLocked) {
4360                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4361                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4362                    if (p.uid != uid) {
4363                        continue;
4364                    }
4365                    if (p.pid == initialPid) {
4366                        proc = p;
4367                        break;
4368                    }
4369                    if (p.pkgList.containsKey(packageName)) {
4370                        proc = p;
4371                    }
4372                }
4373            }
4374
4375            if (proc == null) {
4376                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4377                        + " initialPid=" + initialPid
4378                        + " packageName=" + packageName);
4379                return;
4380            }
4381
4382            if (proc.thread != null) {
4383                if (proc.pid == Process.myPid()) {
4384                    Log.w(TAG, "crashApplication: trying to crash self!");
4385                    return;
4386                }
4387                long ident = Binder.clearCallingIdentity();
4388                try {
4389                    proc.thread.scheduleCrash(message);
4390                } catch (RemoteException e) {
4391                }
4392                Binder.restoreCallingIdentity(ident);
4393            }
4394        }
4395    }
4396
4397    @Override
4398    public final void finishSubActivity(IBinder token, String resultWho,
4399            int requestCode) {
4400        synchronized(this) {
4401            final long origId = Binder.clearCallingIdentity();
4402            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4403            if (r != null) {
4404                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4405            }
4406            Binder.restoreCallingIdentity(origId);
4407        }
4408    }
4409
4410    @Override
4411    public boolean finishActivityAffinity(IBinder token) {
4412        synchronized(this) {
4413            final long origId = Binder.clearCallingIdentity();
4414            try {
4415                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4416                if (r == null) {
4417                    return false;
4418                }
4419
4420                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4421                // can finish.
4422                final TaskRecord task = r.task;
4423                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4424                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4425                    mStackSupervisor.showLockTaskToast();
4426                    return false;
4427                }
4428                return task.stack.finishActivityAffinityLocked(r);
4429            } finally {
4430                Binder.restoreCallingIdentity(origId);
4431            }
4432        }
4433    }
4434
4435    @Override
4436    public void finishVoiceTask(IVoiceInteractionSession session) {
4437        synchronized(this) {
4438            final long origId = Binder.clearCallingIdentity();
4439            try {
4440                mStackSupervisor.finishVoiceTask(session);
4441            } finally {
4442                Binder.restoreCallingIdentity(origId);
4443            }
4444        }
4445
4446    }
4447
4448    @Override
4449    public boolean releaseActivityInstance(IBinder token) {
4450        synchronized(this) {
4451            final long origId = Binder.clearCallingIdentity();
4452            try {
4453                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4454                if (r == null) {
4455                    return false;
4456                }
4457                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4458            } finally {
4459                Binder.restoreCallingIdentity(origId);
4460            }
4461        }
4462    }
4463
4464    @Override
4465    public void releaseSomeActivities(IApplicationThread appInt) {
4466        synchronized(this) {
4467            final long origId = Binder.clearCallingIdentity();
4468            try {
4469                ProcessRecord app = getRecordForAppLocked(appInt);
4470                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4471            } finally {
4472                Binder.restoreCallingIdentity(origId);
4473            }
4474        }
4475    }
4476
4477    @Override
4478    public boolean willActivityBeVisible(IBinder token) {
4479        synchronized(this) {
4480            ActivityStack stack = ActivityRecord.getStackLocked(token);
4481            if (stack != null) {
4482                return stack.willActivityBeVisibleLocked(token);
4483            }
4484            return false;
4485        }
4486    }
4487
4488    @Override
4489    public void overridePendingTransition(IBinder token, String packageName,
4490            int enterAnim, int exitAnim) {
4491        synchronized(this) {
4492            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4493            if (self == null) {
4494                return;
4495            }
4496
4497            final long origId = Binder.clearCallingIdentity();
4498
4499            if (self.state == ActivityState.RESUMED
4500                    || self.state == ActivityState.PAUSING) {
4501                mWindowManager.overridePendingAppTransition(packageName,
4502                        enterAnim, exitAnim, null);
4503            }
4504
4505            Binder.restoreCallingIdentity(origId);
4506        }
4507    }
4508
4509    /**
4510     * Main function for removing an existing process from the activity manager
4511     * as a result of that process going away.  Clears out all connections
4512     * to the process.
4513     */
4514    private final void handleAppDiedLocked(ProcessRecord app,
4515            boolean restarting, boolean allowRestart) {
4516        int pid = app.pid;
4517        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4518        if (!kept && !restarting) {
4519            removeLruProcessLocked(app);
4520            if (pid > 0) {
4521                ProcessList.remove(pid);
4522            }
4523        }
4524
4525        if (mProfileProc == app) {
4526            clearProfilerLocked();
4527        }
4528
4529        // Remove this application's activities from active lists.
4530        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4531
4532        app.activities.clear();
4533
4534        if (app.instrumentationClass != null) {
4535            Slog.w(TAG, "Crash of app " + app.processName
4536                  + " running instrumentation " + app.instrumentationClass);
4537            Bundle info = new Bundle();
4538            info.putString("shortMsg", "Process crashed.");
4539            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4540        }
4541
4542        if (!restarting && hasVisibleActivities && !mStackSupervisor.resumeTopActivitiesLocked()) {
4543            // If there was nothing to resume, and we are not already
4544            // restarting this process, but there is a visible activity that
4545            // is hosted by the process...  then make sure all visible
4546            // activities are running, taking care of restarting this
4547            // process.
4548            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4549        }
4550    }
4551
4552    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4553        IBinder threadBinder = thread.asBinder();
4554        // Find the application record.
4555        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4556            ProcessRecord rec = mLruProcesses.get(i);
4557            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4558                return i;
4559            }
4560        }
4561        return -1;
4562    }
4563
4564    final ProcessRecord getRecordForAppLocked(
4565            IApplicationThread thread) {
4566        if (thread == null) {
4567            return null;
4568        }
4569
4570        int appIndex = getLRURecordIndexForAppLocked(thread);
4571        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4572    }
4573
4574    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4575        // If there are no longer any background processes running,
4576        // and the app that died was not running instrumentation,
4577        // then tell everyone we are now low on memory.
4578        boolean haveBg = false;
4579        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4580            ProcessRecord rec = mLruProcesses.get(i);
4581            if (rec.thread != null
4582                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4583                haveBg = true;
4584                break;
4585            }
4586        }
4587
4588        if (!haveBg) {
4589            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4590            if (doReport) {
4591                long now = SystemClock.uptimeMillis();
4592                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4593                    doReport = false;
4594                } else {
4595                    mLastMemUsageReportTime = now;
4596                }
4597            }
4598            final ArrayList<ProcessMemInfo> memInfos
4599                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4600            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4601            long now = SystemClock.uptimeMillis();
4602            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4603                ProcessRecord rec = mLruProcesses.get(i);
4604                if (rec == dyingProc || rec.thread == null) {
4605                    continue;
4606                }
4607                if (doReport) {
4608                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4609                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4610                }
4611                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4612                    // The low memory report is overriding any current
4613                    // state for a GC request.  Make sure to do
4614                    // heavy/important/visible/foreground processes first.
4615                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4616                        rec.lastRequestedGc = 0;
4617                    } else {
4618                        rec.lastRequestedGc = rec.lastLowMemory;
4619                    }
4620                    rec.reportLowMemory = true;
4621                    rec.lastLowMemory = now;
4622                    mProcessesToGc.remove(rec);
4623                    addProcessToGcListLocked(rec);
4624                }
4625            }
4626            if (doReport) {
4627                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4628                mHandler.sendMessage(msg);
4629            }
4630            scheduleAppGcsLocked();
4631        }
4632    }
4633
4634    final void appDiedLocked(ProcessRecord app) {
4635       appDiedLocked(app, app.pid, app.thread, false);
4636    }
4637
4638    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4639            boolean fromBinderDied) {
4640        // First check if this ProcessRecord is actually active for the pid.
4641        synchronized (mPidsSelfLocked) {
4642            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4643            if (curProc != app) {
4644                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4645                return;
4646            }
4647        }
4648
4649        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4650        synchronized (stats) {
4651            stats.noteProcessDiedLocked(app.info.uid, pid);
4652        }
4653
4654        if (!app.killed) {
4655            if (!fromBinderDied) {
4656                Process.killProcessQuiet(pid);
4657            }
4658            killProcessGroup(app.info.uid, pid);
4659            app.killed = true;
4660        }
4661
4662        // Clean up already done if the process has been re-started.
4663        if (app.pid == pid && app.thread != null &&
4664                app.thread.asBinder() == thread.asBinder()) {
4665            boolean doLowMem = app.instrumentationClass == null;
4666            boolean doOomAdj = doLowMem;
4667            if (!app.killedByAm) {
4668                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4669                        + ") has died");
4670                mAllowLowerMemLevel = true;
4671            } else {
4672                // Note that we always want to do oom adj to update our state with the
4673                // new number of procs.
4674                mAllowLowerMemLevel = false;
4675                doLowMem = false;
4676            }
4677            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4678            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4679                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
4680            handleAppDiedLocked(app, false, true);
4681
4682            if (doOomAdj) {
4683                updateOomAdjLocked();
4684            }
4685            if (doLowMem) {
4686                doLowMemReportIfNeededLocked(app);
4687            }
4688        } else if (app.pid != pid) {
4689            // A new process has already been started.
4690            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4691                    + ") has died and restarted (pid " + app.pid + ").");
4692            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4693        } else if (DEBUG_PROCESSES) {
4694            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
4695                    + thread.asBinder());
4696        }
4697    }
4698
4699    /**
4700     * If a stack trace dump file is configured, dump process stack traces.
4701     * @param clearTraces causes the dump file to be erased prior to the new
4702     *    traces being written, if true; when false, the new traces will be
4703     *    appended to any existing file content.
4704     * @param firstPids of dalvik VM processes to dump stack traces for first
4705     * @param lastPids of dalvik VM processes to dump stack traces for last
4706     * @param nativeProcs optional list of native process names to dump stack crawls
4707     * @return file containing stack traces, or null if no dump file is configured
4708     */
4709    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4710            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4711        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4712        if (tracesPath == null || tracesPath.length() == 0) {
4713            return null;
4714        }
4715
4716        File tracesFile = new File(tracesPath);
4717        try {
4718            File tracesDir = tracesFile.getParentFile();
4719            if (!tracesDir.exists()) {
4720                tracesDir.mkdirs();
4721                if (!SELinux.restorecon(tracesDir)) {
4722                    return null;
4723                }
4724            }
4725            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4726
4727            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4728            tracesFile.createNewFile();
4729            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4730        } catch (IOException e) {
4731            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4732            return null;
4733        }
4734
4735        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4736        return tracesFile;
4737    }
4738
4739    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4740            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4741        // Use a FileObserver to detect when traces finish writing.
4742        // The order of traces is considered important to maintain for legibility.
4743        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4744            @Override
4745            public synchronized void onEvent(int event, String path) { notify(); }
4746        };
4747
4748        try {
4749            observer.startWatching();
4750
4751            // First collect all of the stacks of the most important pids.
4752            if (firstPids != null) {
4753                try {
4754                    int num = firstPids.size();
4755                    for (int i = 0; i < num; i++) {
4756                        synchronized (observer) {
4757                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4758                            observer.wait(200);  // Wait for write-close, give up after 200msec
4759                        }
4760                    }
4761                } catch (InterruptedException e) {
4762                    Slog.wtf(TAG, e);
4763                }
4764            }
4765
4766            // Next collect the stacks of the native pids
4767            if (nativeProcs != null) {
4768                int[] pids = Process.getPidsForCommands(nativeProcs);
4769                if (pids != null) {
4770                    for (int pid : pids) {
4771                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4772                    }
4773                }
4774            }
4775
4776            // Lastly, measure CPU usage.
4777            if (processCpuTracker != null) {
4778                processCpuTracker.init();
4779                System.gc();
4780                processCpuTracker.update();
4781                try {
4782                    synchronized (processCpuTracker) {
4783                        processCpuTracker.wait(500); // measure over 1/2 second.
4784                    }
4785                } catch (InterruptedException e) {
4786                }
4787                processCpuTracker.update();
4788
4789                // We'll take the stack crawls of just the top apps using CPU.
4790                final int N = processCpuTracker.countWorkingStats();
4791                int numProcs = 0;
4792                for (int i=0; i<N && numProcs<5; i++) {
4793                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4794                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4795                        numProcs++;
4796                        try {
4797                            synchronized (observer) {
4798                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4799                                observer.wait(200);  // Wait for write-close, give up after 200msec
4800                            }
4801                        } catch (InterruptedException e) {
4802                            Slog.wtf(TAG, e);
4803                        }
4804
4805                    }
4806                }
4807            }
4808        } finally {
4809            observer.stopWatching();
4810        }
4811    }
4812
4813    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4814        if (true || IS_USER_BUILD) {
4815            return;
4816        }
4817        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4818        if (tracesPath == null || tracesPath.length() == 0) {
4819            return;
4820        }
4821
4822        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4823        StrictMode.allowThreadDiskWrites();
4824        try {
4825            final File tracesFile = new File(tracesPath);
4826            final File tracesDir = tracesFile.getParentFile();
4827            final File tracesTmp = new File(tracesDir, "__tmp__");
4828            try {
4829                if (!tracesDir.exists()) {
4830                    tracesDir.mkdirs();
4831                    if (!SELinux.restorecon(tracesDir.getPath())) {
4832                        return;
4833                    }
4834                }
4835                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4836
4837                if (tracesFile.exists()) {
4838                    tracesTmp.delete();
4839                    tracesFile.renameTo(tracesTmp);
4840                }
4841                StringBuilder sb = new StringBuilder();
4842                Time tobj = new Time();
4843                tobj.set(System.currentTimeMillis());
4844                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4845                sb.append(": ");
4846                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4847                sb.append(" since ");
4848                sb.append(msg);
4849                FileOutputStream fos = new FileOutputStream(tracesFile);
4850                fos.write(sb.toString().getBytes());
4851                if (app == null) {
4852                    fos.write("\n*** No application process!".getBytes());
4853                }
4854                fos.close();
4855                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4856            } catch (IOException e) {
4857                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4858                return;
4859            }
4860
4861            if (app != null) {
4862                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4863                firstPids.add(app.pid);
4864                dumpStackTraces(tracesPath, firstPids, null, null, null);
4865            }
4866
4867            File lastTracesFile = null;
4868            File curTracesFile = null;
4869            for (int i=9; i>=0; i--) {
4870                String name = String.format(Locale.US, "slow%02d.txt", i);
4871                curTracesFile = new File(tracesDir, name);
4872                if (curTracesFile.exists()) {
4873                    if (lastTracesFile != null) {
4874                        curTracesFile.renameTo(lastTracesFile);
4875                    } else {
4876                        curTracesFile.delete();
4877                    }
4878                }
4879                lastTracesFile = curTracesFile;
4880            }
4881            tracesFile.renameTo(curTracesFile);
4882            if (tracesTmp.exists()) {
4883                tracesTmp.renameTo(tracesFile);
4884            }
4885        } finally {
4886            StrictMode.setThreadPolicy(oldPolicy);
4887        }
4888    }
4889
4890    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4891            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4892        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4893        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4894
4895        if (mController != null) {
4896            try {
4897                // 0 == continue, -1 = kill process immediately
4898                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4899                if (res < 0 && app.pid != MY_PID) {
4900                    app.kill("anr", true);
4901                }
4902            } catch (RemoteException e) {
4903                mController = null;
4904                Watchdog.getInstance().setActivityController(null);
4905            }
4906        }
4907
4908        long anrTime = SystemClock.uptimeMillis();
4909        if (MONITOR_CPU_USAGE) {
4910            updateCpuStatsNow();
4911        }
4912
4913        synchronized (this) {
4914            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4915            if (mShuttingDown) {
4916                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4917                return;
4918            } else if (app.notResponding) {
4919                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4920                return;
4921            } else if (app.crashing) {
4922                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4923                return;
4924            }
4925
4926            // In case we come through here for the same app before completing
4927            // this one, mark as anring now so we will bail out.
4928            app.notResponding = true;
4929
4930            // Log the ANR to the event log.
4931            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4932                    app.processName, app.info.flags, annotation);
4933
4934            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4935            firstPids.add(app.pid);
4936
4937            int parentPid = app.pid;
4938            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4939            if (parentPid != app.pid) firstPids.add(parentPid);
4940
4941            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4942
4943            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4944                ProcessRecord r = mLruProcesses.get(i);
4945                if (r != null && r.thread != null) {
4946                    int pid = r.pid;
4947                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4948                        if (r.persistent) {
4949                            firstPids.add(pid);
4950                        } else {
4951                            lastPids.put(pid, Boolean.TRUE);
4952                        }
4953                    }
4954                }
4955            }
4956        }
4957
4958        // Log the ANR to the main log.
4959        StringBuilder info = new StringBuilder();
4960        info.setLength(0);
4961        info.append("ANR in ").append(app.processName);
4962        if (activity != null && activity.shortComponentName != null) {
4963            info.append(" (").append(activity.shortComponentName).append(")");
4964        }
4965        info.append("\n");
4966        info.append("PID: ").append(app.pid).append("\n");
4967        if (annotation != null) {
4968            info.append("Reason: ").append(annotation).append("\n");
4969        }
4970        if (parent != null && parent != activity) {
4971            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4972        }
4973
4974        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4975
4976        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4977                NATIVE_STACKS_OF_INTEREST);
4978
4979        String cpuInfo = null;
4980        if (MONITOR_CPU_USAGE) {
4981            updateCpuStatsNow();
4982            synchronized (mProcessCpuTracker) {
4983                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4984            }
4985            info.append(processCpuTracker.printCurrentLoad());
4986            info.append(cpuInfo);
4987        }
4988
4989        info.append(processCpuTracker.printCurrentState(anrTime));
4990
4991        Slog.e(TAG, info.toString());
4992        if (tracesFile == null) {
4993            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4994            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4995        }
4996
4997        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4998                cpuInfo, tracesFile, null);
4999
5000        if (mController != null) {
5001            try {
5002                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5003                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5004                if (res != 0) {
5005                    if (res < 0 && app.pid != MY_PID) {
5006                        app.kill("anr", true);
5007                    } else {
5008                        synchronized (this) {
5009                            mServices.scheduleServiceTimeoutLocked(app);
5010                        }
5011                    }
5012                    return;
5013                }
5014            } catch (RemoteException e) {
5015                mController = null;
5016                Watchdog.getInstance().setActivityController(null);
5017            }
5018        }
5019
5020        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5021        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5022                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5023
5024        synchronized (this) {
5025            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5026
5027            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5028                app.kill("bg anr", true);
5029                return;
5030            }
5031
5032            // Set the app's notResponding state, and look up the errorReportReceiver
5033            makeAppNotRespondingLocked(app,
5034                    activity != null ? activity.shortComponentName : null,
5035                    annotation != null ? "ANR " + annotation : "ANR",
5036                    info.toString());
5037
5038            // Bring up the infamous App Not Responding dialog
5039            Message msg = Message.obtain();
5040            HashMap<String, Object> map = new HashMap<String, Object>();
5041            msg.what = SHOW_NOT_RESPONDING_MSG;
5042            msg.obj = map;
5043            msg.arg1 = aboveSystem ? 1 : 0;
5044            map.put("app", app);
5045            if (activity != null) {
5046                map.put("activity", activity);
5047            }
5048
5049            mUiHandler.sendMessage(msg);
5050        }
5051    }
5052
5053    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5054        if (!mLaunchWarningShown) {
5055            mLaunchWarningShown = true;
5056            mUiHandler.post(new Runnable() {
5057                @Override
5058                public void run() {
5059                    synchronized (ActivityManagerService.this) {
5060                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5061                        d.show();
5062                        mUiHandler.postDelayed(new Runnable() {
5063                            @Override
5064                            public void run() {
5065                                synchronized (ActivityManagerService.this) {
5066                                    d.dismiss();
5067                                    mLaunchWarningShown = false;
5068                                }
5069                            }
5070                        }, 4000);
5071                    }
5072                }
5073            });
5074        }
5075    }
5076
5077    @Override
5078    public boolean clearApplicationUserData(final String packageName,
5079            final IPackageDataObserver observer, int userId) {
5080        enforceNotIsolatedCaller("clearApplicationUserData");
5081        if (packageName != null && packageName.equals(mDeviceOwnerName)) {
5082            throw new SecurityException("Clearing DeviceOwner data is forbidden.");
5083        }
5084        int uid = Binder.getCallingUid();
5085        int pid = Binder.getCallingPid();
5086        userId = handleIncomingUser(pid, uid,
5087                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5088        long callingId = Binder.clearCallingIdentity();
5089        try {
5090            IPackageManager pm = AppGlobals.getPackageManager();
5091            int pkgUid = -1;
5092            synchronized(this) {
5093                try {
5094                    pkgUid = pm.getPackageUid(packageName, userId);
5095                } catch (RemoteException e) {
5096                }
5097                if (pkgUid == -1) {
5098                    Slog.w(TAG, "Invalid packageName: " + packageName);
5099                    if (observer != null) {
5100                        try {
5101                            observer.onRemoveCompleted(packageName, false);
5102                        } catch (RemoteException e) {
5103                            Slog.i(TAG, "Observer no longer exists.");
5104                        }
5105                    }
5106                    return false;
5107                }
5108                if (uid == pkgUid || checkComponentPermission(
5109                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5110                        pid, uid, -1, true)
5111                        == PackageManager.PERMISSION_GRANTED) {
5112                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5113                } else {
5114                    throw new SecurityException("PID " + pid + " does not have permission "
5115                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5116                                    + " of package " + packageName);
5117                }
5118
5119                // Remove all tasks match the cleared application package and user
5120                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5121                    final TaskRecord tr = mRecentTasks.get(i);
5122                    final String taskPackageName =
5123                            tr.getBaseIntent().getComponent().getPackageName();
5124                    if (tr.userId != userId) continue;
5125                    if (!taskPackageName.equals(packageName)) continue;
5126                    removeTaskByIdLocked(tr.taskId, false);
5127                }
5128            }
5129
5130            try {
5131                // Clear application user data
5132                pm.clearApplicationUserData(packageName, observer, userId);
5133
5134                synchronized(this) {
5135                    // Remove all permissions granted from/to this package
5136                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5137                }
5138
5139                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5140                        Uri.fromParts("package", packageName, null));
5141                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5142                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5143                        null, null, 0, null, null, null, null, false, false, userId);
5144            } catch (RemoteException e) {
5145            }
5146        } finally {
5147            Binder.restoreCallingIdentity(callingId);
5148        }
5149        return true;
5150    }
5151
5152    @Override
5153    public void killBackgroundProcesses(final String packageName, int userId) {
5154        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5155                != PackageManager.PERMISSION_GRANTED &&
5156                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5157                        != PackageManager.PERMISSION_GRANTED) {
5158            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5159                    + Binder.getCallingPid()
5160                    + ", uid=" + Binder.getCallingUid()
5161                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5162            Slog.w(TAG, msg);
5163            throw new SecurityException(msg);
5164        }
5165
5166        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5167                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5168        long callingId = Binder.clearCallingIdentity();
5169        try {
5170            IPackageManager pm = AppGlobals.getPackageManager();
5171            synchronized(this) {
5172                int appId = -1;
5173                try {
5174                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5175                } catch (RemoteException e) {
5176                }
5177                if (appId == -1) {
5178                    Slog.w(TAG, "Invalid packageName: " + packageName);
5179                    return;
5180                }
5181                killPackageProcessesLocked(packageName, appId, userId,
5182                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5183            }
5184        } finally {
5185            Binder.restoreCallingIdentity(callingId);
5186        }
5187    }
5188
5189    @Override
5190    public void killAllBackgroundProcesses() {
5191        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5192                != PackageManager.PERMISSION_GRANTED) {
5193            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5194                    + Binder.getCallingPid()
5195                    + ", uid=" + Binder.getCallingUid()
5196                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5197            Slog.w(TAG, msg);
5198            throw new SecurityException(msg);
5199        }
5200
5201        long callingId = Binder.clearCallingIdentity();
5202        try {
5203            synchronized(this) {
5204                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5205                final int NP = mProcessNames.getMap().size();
5206                for (int ip=0; ip<NP; ip++) {
5207                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5208                    final int NA = apps.size();
5209                    for (int ia=0; ia<NA; ia++) {
5210                        ProcessRecord app = apps.valueAt(ia);
5211                        if (app.persistent) {
5212                            // we don't kill persistent processes
5213                            continue;
5214                        }
5215                        if (app.removed) {
5216                            procs.add(app);
5217                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5218                            app.removed = true;
5219                            procs.add(app);
5220                        }
5221                    }
5222                }
5223
5224                int N = procs.size();
5225                for (int i=0; i<N; i++) {
5226                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5227                }
5228                mAllowLowerMemLevel = true;
5229                updateOomAdjLocked();
5230                doLowMemReportIfNeededLocked(null);
5231            }
5232        } finally {
5233            Binder.restoreCallingIdentity(callingId);
5234        }
5235    }
5236
5237    @Override
5238    public void forceStopPackage(final String packageName, int userId) {
5239        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5240                != PackageManager.PERMISSION_GRANTED) {
5241            String msg = "Permission Denial: forceStopPackage() from pid="
5242                    + Binder.getCallingPid()
5243                    + ", uid=" + Binder.getCallingUid()
5244                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5245            Slog.w(TAG, msg);
5246            throw new SecurityException(msg);
5247        }
5248        final int callingPid = Binder.getCallingPid();
5249        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5250                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5251        long callingId = Binder.clearCallingIdentity();
5252        try {
5253            IPackageManager pm = AppGlobals.getPackageManager();
5254            synchronized(this) {
5255                int[] users = userId == UserHandle.USER_ALL
5256                        ? getUsersLocked() : new int[] { userId };
5257                for (int user : users) {
5258                    int pkgUid = -1;
5259                    try {
5260                        pkgUid = pm.getPackageUid(packageName, user);
5261                    } catch (RemoteException e) {
5262                    }
5263                    if (pkgUid == -1) {
5264                        Slog.w(TAG, "Invalid packageName: " + packageName);
5265                        continue;
5266                    }
5267                    try {
5268                        pm.setPackageStoppedState(packageName, true, user);
5269                    } catch (RemoteException e) {
5270                    } catch (IllegalArgumentException e) {
5271                        Slog.w(TAG, "Failed trying to unstop package "
5272                                + packageName + ": " + e);
5273                    }
5274                    if (isUserRunningLocked(user, false)) {
5275                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5276                    }
5277                }
5278            }
5279        } finally {
5280            Binder.restoreCallingIdentity(callingId);
5281        }
5282    }
5283
5284    @Override
5285    public void addPackageDependency(String packageName) {
5286        synchronized (this) {
5287            int callingPid = Binder.getCallingPid();
5288            if (callingPid == Process.myPid()) {
5289                //  Yeah, um, no.
5290                return;
5291            }
5292            ProcessRecord proc;
5293            synchronized (mPidsSelfLocked) {
5294                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5295            }
5296            if (proc != null) {
5297                if (proc.pkgDeps == null) {
5298                    proc.pkgDeps = new ArraySet<String>(1);
5299                }
5300                proc.pkgDeps.add(packageName);
5301            }
5302        }
5303    }
5304
5305    /*
5306     * The pkg name and app id have to be specified.
5307     */
5308    @Override
5309    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5310        if (pkg == null) {
5311            return;
5312        }
5313        // Make sure the uid is valid.
5314        if (appid < 0) {
5315            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5316            return;
5317        }
5318        int callerUid = Binder.getCallingUid();
5319        // Only the system server can kill an application
5320        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5321            // Post an aysnc message to kill the application
5322            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5323            msg.arg1 = appid;
5324            msg.arg2 = 0;
5325            Bundle bundle = new Bundle();
5326            bundle.putString("pkg", pkg);
5327            bundle.putString("reason", reason);
5328            msg.obj = bundle;
5329            mHandler.sendMessage(msg);
5330        } else {
5331            throw new SecurityException(callerUid + " cannot kill pkg: " +
5332                    pkg);
5333        }
5334    }
5335
5336    @Override
5337    public void closeSystemDialogs(String reason) {
5338        enforceNotIsolatedCaller("closeSystemDialogs");
5339
5340        final int pid = Binder.getCallingPid();
5341        final int uid = Binder.getCallingUid();
5342        final long origId = Binder.clearCallingIdentity();
5343        try {
5344            synchronized (this) {
5345                // Only allow this from foreground processes, so that background
5346                // applications can't abuse it to prevent system UI from being shown.
5347                if (uid >= Process.FIRST_APPLICATION_UID) {
5348                    ProcessRecord proc;
5349                    synchronized (mPidsSelfLocked) {
5350                        proc = mPidsSelfLocked.get(pid);
5351                    }
5352                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5353                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5354                                + " from background process " + proc);
5355                        return;
5356                    }
5357                }
5358                closeSystemDialogsLocked(reason);
5359            }
5360        } finally {
5361            Binder.restoreCallingIdentity(origId);
5362        }
5363    }
5364
5365    void closeSystemDialogsLocked(String reason) {
5366        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5367        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5368                | Intent.FLAG_RECEIVER_FOREGROUND);
5369        if (reason != null) {
5370            intent.putExtra("reason", reason);
5371        }
5372        mWindowManager.closeSystemDialogs(reason);
5373
5374        mStackSupervisor.closeSystemDialogsLocked();
5375
5376        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5377                AppOpsManager.OP_NONE, null, false, false,
5378                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5379    }
5380
5381    @Override
5382    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5383        enforceNotIsolatedCaller("getProcessMemoryInfo");
5384        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5385        for (int i=pids.length-1; i>=0; i--) {
5386            ProcessRecord proc;
5387            int oomAdj;
5388            synchronized (this) {
5389                synchronized (mPidsSelfLocked) {
5390                    proc = mPidsSelfLocked.get(pids[i]);
5391                    oomAdj = proc != null ? proc.setAdj : 0;
5392                }
5393            }
5394            infos[i] = new Debug.MemoryInfo();
5395            Debug.getMemoryInfo(pids[i], infos[i]);
5396            if (proc != null) {
5397                synchronized (this) {
5398                    if (proc.thread != null && proc.setAdj == oomAdj) {
5399                        // Record this for posterity if the process has been stable.
5400                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5401                                infos[i].getTotalUss(), false, proc.pkgList);
5402                    }
5403                }
5404            }
5405        }
5406        return infos;
5407    }
5408
5409    @Override
5410    public long[] getProcessPss(int[] pids) {
5411        enforceNotIsolatedCaller("getProcessPss");
5412        long[] pss = new long[pids.length];
5413        for (int i=pids.length-1; i>=0; i--) {
5414            ProcessRecord proc;
5415            int oomAdj;
5416            synchronized (this) {
5417                synchronized (mPidsSelfLocked) {
5418                    proc = mPidsSelfLocked.get(pids[i]);
5419                    oomAdj = proc != null ? proc.setAdj : 0;
5420                }
5421            }
5422            long[] tmpUss = new long[1];
5423            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5424            if (proc != null) {
5425                synchronized (this) {
5426                    if (proc.thread != null && proc.setAdj == oomAdj) {
5427                        // Record this for posterity if the process has been stable.
5428                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5429                    }
5430                }
5431            }
5432        }
5433        return pss;
5434    }
5435
5436    @Override
5437    public void killApplicationProcess(String processName, int uid) {
5438        if (processName == null) {
5439            return;
5440        }
5441
5442        int callerUid = Binder.getCallingUid();
5443        // Only the system server can kill an application
5444        if (callerUid == Process.SYSTEM_UID) {
5445            synchronized (this) {
5446                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5447                if (app != null && app.thread != null) {
5448                    try {
5449                        app.thread.scheduleSuicide();
5450                    } catch (RemoteException e) {
5451                        // If the other end already died, then our work here is done.
5452                    }
5453                } else {
5454                    Slog.w(TAG, "Process/uid not found attempting kill of "
5455                            + processName + " / " + uid);
5456                }
5457            }
5458        } else {
5459            throw new SecurityException(callerUid + " cannot kill app process: " +
5460                    processName);
5461        }
5462    }
5463
5464    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5465        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5466                false, true, false, false, UserHandle.getUserId(uid), reason);
5467        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5468                Uri.fromParts("package", packageName, null));
5469        if (!mProcessesReady) {
5470            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5471                    | Intent.FLAG_RECEIVER_FOREGROUND);
5472        }
5473        intent.putExtra(Intent.EXTRA_UID, uid);
5474        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5475        broadcastIntentLocked(null, null, intent,
5476                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5477                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5478    }
5479
5480    private void forceStopUserLocked(int userId, String reason) {
5481        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5482        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5483        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5484                | Intent.FLAG_RECEIVER_FOREGROUND);
5485        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5486        broadcastIntentLocked(null, null, intent,
5487                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5488                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5489    }
5490
5491    private final boolean killPackageProcessesLocked(String packageName, int appId,
5492            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5493            boolean doit, boolean evenPersistent, String reason) {
5494        ArrayList<ProcessRecord> procs = new ArrayList<>();
5495
5496        // Remove all processes this package may have touched: all with the
5497        // same UID (except for the system or root user), and all whose name
5498        // matches the package name.
5499        final int NP = mProcessNames.getMap().size();
5500        for (int ip=0; ip<NP; ip++) {
5501            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5502            final int NA = apps.size();
5503            for (int ia=0; ia<NA; ia++) {
5504                ProcessRecord app = apps.valueAt(ia);
5505                if (app.persistent && !evenPersistent) {
5506                    // we don't kill persistent processes
5507                    continue;
5508                }
5509                if (app.removed) {
5510                    if (doit) {
5511                        procs.add(app);
5512                    }
5513                    continue;
5514                }
5515
5516                // Skip process if it doesn't meet our oom adj requirement.
5517                if (app.setAdj < minOomAdj) {
5518                    continue;
5519                }
5520
5521                // If no package is specified, we call all processes under the
5522                // give user id.
5523                if (packageName == null) {
5524                    if (app.userId != userId) {
5525                        continue;
5526                    }
5527                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5528                        continue;
5529                    }
5530                // Package has been specified, we want to hit all processes
5531                // that match it.  We need to qualify this by the processes
5532                // that are running under the specified app and user ID.
5533                } else {
5534                    final boolean isDep = app.pkgDeps != null
5535                            && app.pkgDeps.contains(packageName);
5536                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5537                        continue;
5538                    }
5539                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5540                        continue;
5541                    }
5542                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5543                        continue;
5544                    }
5545                }
5546
5547                // Process has passed all conditions, kill it!
5548                if (!doit) {
5549                    return true;
5550                }
5551                app.removed = true;
5552                procs.add(app);
5553            }
5554        }
5555
5556        int N = procs.size();
5557        for (int i=0; i<N; i++) {
5558            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5559        }
5560        updateOomAdjLocked();
5561        return N > 0;
5562    }
5563
5564    private void cleanupDisabledPackageComponentsLocked(
5565            String packageName, int userId, String[] changedClasses) {
5566
5567        Set<String> disabledClasses = null;
5568        boolean packageDisabled = false;
5569        IPackageManager pm = AppGlobals.getPackageManager();
5570
5571        if (changedClasses == null) {
5572            // Nothing changed...
5573            return;
5574        }
5575
5576        // Determine enable/disable state of the package and its components.
5577        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5578        for (int i = changedClasses.length - 1; i >= 0; i--) {
5579            final String changedClass = changedClasses[i];
5580
5581            if (changedClass.equals(packageName)) {
5582                try {
5583                    // Entire package setting changed
5584                    enabled = pm.getApplicationEnabledSetting(packageName,
5585                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5586                } catch (Exception e) {
5587                    // No such package/component; probably racing with uninstall.  In any
5588                    // event it means we have nothing further to do here.
5589                    return;
5590                }
5591                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5592                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5593                if (packageDisabled) {
5594                    // Entire package is disabled.
5595                    // No need to continue to check component states.
5596                    disabledClasses = null;
5597                    break;
5598                }
5599            } else {
5600                try {
5601                    enabled = pm.getComponentEnabledSetting(
5602                            new ComponentName(packageName, changedClass),
5603                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5604                } catch (Exception e) {
5605                    // As above, probably racing with uninstall.
5606                    return;
5607                }
5608                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5609                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5610                    if (disabledClasses == null) {
5611                        disabledClasses = new ArraySet<>(changedClasses.length);
5612                    }
5613                    disabledClasses.add(changedClass);
5614                }
5615            }
5616        }
5617
5618        if (!packageDisabled && disabledClasses == null) {
5619            // Nothing to do here...
5620            return;
5621        }
5622
5623        // Clean-up disabled activities.
5624        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5625                packageName, disabledClasses, true, false, userId) && mBooted) {
5626            mStackSupervisor.resumeTopActivitiesLocked();
5627            mStackSupervisor.scheduleIdleLocked();
5628        }
5629
5630        // Clean-up disabled tasks
5631        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5632
5633        // Clean-up disabled services.
5634        mServices.bringDownDisabledPackageServicesLocked(
5635                packageName, disabledClasses, userId, false, true);
5636
5637        // Clean-up disabled providers.
5638        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5639        mProviderMap.collectPackageProvidersLocked(
5640                packageName, disabledClasses, true, false, userId, providers);
5641        for (int i = providers.size() - 1; i >= 0; i--) {
5642            removeDyingProviderLocked(null, providers.get(i), true);
5643        }
5644
5645        // Clean-up disabled broadcast receivers.
5646        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5647            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5648                    packageName, disabledClasses, userId, true);
5649        }
5650
5651    }
5652
5653    private final boolean forceStopPackageLocked(String packageName, int appId,
5654            boolean callerWillRestart, boolean purgeCache, boolean doit,
5655            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5656        int i;
5657
5658        if (userId == UserHandle.USER_ALL && packageName == null) {
5659            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5660        }
5661
5662        if (appId < 0 && packageName != null) {
5663            try {
5664                appId = UserHandle.getAppId(
5665                        AppGlobals.getPackageManager().getPackageUid(packageName, 0));
5666            } catch (RemoteException e) {
5667            }
5668        }
5669
5670        if (doit) {
5671            if (packageName != null) {
5672                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5673                        + " user=" + userId + ": " + reason);
5674            } else {
5675                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5676            }
5677
5678            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5679            for (int ip = pmap.size() - 1; ip >= 0; ip--) {
5680                SparseArray<Long> ba = pmap.valueAt(ip);
5681                for (i = ba.size() - 1; i >= 0; i--) {
5682                    boolean remove = false;
5683                    final int entUid = ba.keyAt(i);
5684                    if (packageName != null) {
5685                        if (userId == UserHandle.USER_ALL) {
5686                            if (UserHandle.getAppId(entUid) == appId) {
5687                                remove = true;
5688                            }
5689                        } else {
5690                            if (entUid == UserHandle.getUid(userId, appId)) {
5691                                remove = true;
5692                            }
5693                        }
5694                    } else if (UserHandle.getUserId(entUid) == userId) {
5695                        remove = true;
5696                    }
5697                    if (remove) {
5698                        ba.removeAt(i);
5699                    }
5700                }
5701                if (ba.size() == 0) {
5702                    pmap.removeAt(ip);
5703                }
5704            }
5705        }
5706
5707        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5708                -100, callerWillRestart, true, doit, evenPersistent,
5709                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5710
5711        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5712                packageName, null, doit, evenPersistent, userId)) {
5713            if (!doit) {
5714                return true;
5715            }
5716            didSomething = true;
5717        }
5718
5719        if (mServices.bringDownDisabledPackageServicesLocked(
5720                packageName, null, userId, evenPersistent, doit)) {
5721            if (!doit) {
5722                return true;
5723            }
5724            didSomething = true;
5725        }
5726
5727        if (packageName == null) {
5728            // Remove all sticky broadcasts from this user.
5729            mStickyBroadcasts.remove(userId);
5730        }
5731
5732        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5733        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5734                userId, providers)) {
5735            if (!doit) {
5736                return true;
5737            }
5738            didSomething = true;
5739        }
5740        for (i = providers.size() - 1; i >= 0; i--) {
5741            removeDyingProviderLocked(null, providers.get(i), true);
5742        }
5743
5744        // Remove transient permissions granted from/to this package/user
5745        removeUriPermissionsForPackageLocked(packageName, userId, false);
5746
5747        if (doit) {
5748            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
5749                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5750                        packageName, null, userId, doit);
5751            }
5752        }
5753
5754        if (packageName == null || uninstalling) {
5755            // Remove pending intents.  For now we only do this when force
5756            // stopping users, because we have some problems when doing this
5757            // for packages -- app widgets are not currently cleaned up for
5758            // such packages, so they can be left with bad pending intents.
5759            if (mIntentSenderRecords.size() > 0) {
5760                Iterator<WeakReference<PendingIntentRecord>> it
5761                        = mIntentSenderRecords.values().iterator();
5762                while (it.hasNext()) {
5763                    WeakReference<PendingIntentRecord> wpir = it.next();
5764                    if (wpir == null) {
5765                        it.remove();
5766                        continue;
5767                    }
5768                    PendingIntentRecord pir = wpir.get();
5769                    if (pir == null) {
5770                        it.remove();
5771                        continue;
5772                    }
5773                    if (packageName == null) {
5774                        // Stopping user, remove all objects for the user.
5775                        if (pir.key.userId != userId) {
5776                            // Not the same user, skip it.
5777                            continue;
5778                        }
5779                    } else {
5780                        if (UserHandle.getAppId(pir.uid) != appId) {
5781                            // Different app id, skip it.
5782                            continue;
5783                        }
5784                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5785                            // Different user, skip it.
5786                            continue;
5787                        }
5788                        if (!pir.key.packageName.equals(packageName)) {
5789                            // Different package, skip it.
5790                            continue;
5791                        }
5792                    }
5793                    if (!doit) {
5794                        return true;
5795                    }
5796                    didSomething = true;
5797                    it.remove();
5798                    pir.canceled = true;
5799                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5800                        pir.key.activity.pendingResults.remove(pir.ref);
5801                    }
5802                }
5803            }
5804        }
5805
5806        if (doit) {
5807            if (purgeCache && packageName != null) {
5808                AttributeCache ac = AttributeCache.instance();
5809                if (ac != null) {
5810                    ac.removePackage(packageName);
5811                }
5812            }
5813            if (mBooted) {
5814                mStackSupervisor.resumeTopActivitiesLocked();
5815                mStackSupervisor.scheduleIdleLocked();
5816            }
5817        }
5818
5819        return didSomething;
5820    }
5821
5822    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
5823        ProcessRecord old = mProcessNames.remove(name, uid);
5824        if (old != null) {
5825            old.uidRecord.numProcs--;
5826            if (old.uidRecord.numProcs == 0) {
5827                // No more processes using this uid, tell clients it is gone.
5828                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5829                        "No more processes in " + old.uidRecord);
5830                enqueueUidChangeLocked(old.uidRecord, true);
5831                mActiveUids.remove(uid);
5832            }
5833            old.uidRecord = null;
5834        }
5835        mIsolatedProcesses.remove(uid);
5836        return old;
5837    }
5838
5839    private final void addProcessNameLocked(ProcessRecord proc) {
5840        // We shouldn't already have a process under this name, but just in case we
5841        // need to clean up whatever may be there now.
5842        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
5843        if (old == proc && proc.persistent) {
5844            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
5845            Slog.w(TAG, "Re-adding persistent process " + proc);
5846        } else if (old != null) {
5847            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
5848        }
5849        UidRecord uidRec = mActiveUids.get(proc.uid);
5850        if (uidRec == null) {
5851            uidRec = new UidRecord(proc.uid);
5852            // This is the first appearance of the uid, report it now!
5853            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5854                    "Creating new process uid: " + uidRec);
5855            mActiveUids.put(proc.uid, uidRec);
5856            enqueueUidChangeLocked(uidRec, false);
5857        }
5858        proc.uidRecord = uidRec;
5859        uidRec.numProcs++;
5860        mProcessNames.put(proc.processName, proc.uid, proc);
5861        if (proc.isolated) {
5862            mIsolatedProcesses.put(proc.uid, proc);
5863        }
5864    }
5865
5866    private final boolean removeProcessLocked(ProcessRecord app,
5867            boolean callerWillRestart, boolean allowRestart, String reason) {
5868        final String name = app.processName;
5869        final int uid = app.uid;
5870        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
5871            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
5872
5873        removeProcessNameLocked(name, uid);
5874        if (mHeavyWeightProcess == app) {
5875            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5876                    mHeavyWeightProcess.userId, 0));
5877            mHeavyWeightProcess = null;
5878        }
5879        boolean needRestart = false;
5880        if (app.pid > 0 && app.pid != MY_PID) {
5881            int pid = app.pid;
5882            synchronized (mPidsSelfLocked) {
5883                mPidsSelfLocked.remove(pid);
5884                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5885            }
5886            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5887            if (app.isolated) {
5888                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5889            }
5890            boolean willRestart = false;
5891            if (app.persistent && !app.isolated) {
5892                if (!callerWillRestart) {
5893                    willRestart = true;
5894                } else {
5895                    needRestart = true;
5896                }
5897            }
5898            app.kill(reason, true);
5899            handleAppDiedLocked(app, willRestart, allowRestart);
5900            if (willRestart) {
5901                removeLruProcessLocked(app);
5902                addAppLocked(app.info, false, null /* ABI override */);
5903            }
5904        } else {
5905            mRemovedProcesses.add(app);
5906        }
5907
5908        return needRestart;
5909    }
5910
5911    private final void processStartTimedOutLocked(ProcessRecord app) {
5912        final int pid = app.pid;
5913        boolean gone = false;
5914        synchronized (mPidsSelfLocked) {
5915            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5916            if (knownApp != null && knownApp.thread == null) {
5917                mPidsSelfLocked.remove(pid);
5918                gone = true;
5919            }
5920        }
5921
5922        if (gone) {
5923            Slog.w(TAG, "Process " + app + " failed to attach");
5924            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5925                    pid, app.uid, app.processName);
5926            removeProcessNameLocked(app.processName, app.uid);
5927            if (mHeavyWeightProcess == app) {
5928                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5929                        mHeavyWeightProcess.userId, 0));
5930                mHeavyWeightProcess = null;
5931            }
5932            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5933            if (app.isolated) {
5934                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5935            }
5936            // Take care of any launching providers waiting for this process.
5937            checkAppInLaunchingProvidersLocked(app, true);
5938            // Take care of any services that are waiting for the process.
5939            mServices.processStartTimedOutLocked(app);
5940            app.kill("start timeout", true);
5941            removeLruProcessLocked(app);
5942            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5943                Slog.w(TAG, "Unattached app died before backup, skipping");
5944                try {
5945                    IBackupManager bm = IBackupManager.Stub.asInterface(
5946                            ServiceManager.getService(Context.BACKUP_SERVICE));
5947                    bm.agentDisconnected(app.info.packageName);
5948                } catch (RemoteException e) {
5949                    // Can't happen; the backup manager is local
5950                }
5951            }
5952            if (isPendingBroadcastProcessLocked(pid)) {
5953                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5954                skipPendingBroadcastLocked(pid);
5955            }
5956        } else {
5957            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5958        }
5959    }
5960
5961    private final boolean attachApplicationLocked(IApplicationThread thread,
5962            int pid) {
5963
5964        // Find the application record that is being attached...  either via
5965        // the pid if we are running in multiple processes, or just pull the
5966        // next app record if we are emulating process with anonymous threads.
5967        ProcessRecord app;
5968        if (pid != MY_PID && pid >= 0) {
5969            synchronized (mPidsSelfLocked) {
5970                app = mPidsSelfLocked.get(pid);
5971            }
5972        } else {
5973            app = null;
5974        }
5975
5976        if (app == null) {
5977            Slog.w(TAG, "No pending application record for pid " + pid
5978                    + " (IApplicationThread " + thread + "); dropping process");
5979            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5980            if (pid > 0 && pid != MY_PID) {
5981                Process.killProcessQuiet(pid);
5982                //TODO: killProcessGroup(app.info.uid, pid);
5983            } else {
5984                try {
5985                    thread.scheduleExit();
5986                } catch (Exception e) {
5987                    // Ignore exceptions.
5988                }
5989            }
5990            return false;
5991        }
5992
5993        // If this application record is still attached to a previous
5994        // process, clean it up now.
5995        if (app.thread != null) {
5996            handleAppDiedLocked(app, true, true);
5997        }
5998
5999        // Tell the process all about itself.
6000
6001        if (DEBUG_ALL) Slog.v(
6002                TAG, "Binding process pid " + pid + " to record " + app);
6003
6004        final String processName = app.processName;
6005        try {
6006            AppDeathRecipient adr = new AppDeathRecipient(
6007                    app, pid, thread);
6008            thread.asBinder().linkToDeath(adr, 0);
6009            app.deathRecipient = adr;
6010        } catch (RemoteException e) {
6011            app.resetPackageList(mProcessStats);
6012            startProcessLocked(app, "link fail", processName);
6013            return false;
6014        }
6015
6016        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6017
6018        app.makeActive(thread, mProcessStats);
6019        app.curAdj = app.setAdj = -100;
6020        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6021        app.forcingToForeground = null;
6022        updateProcessForegroundLocked(app, false, false);
6023        app.hasShownUi = false;
6024        app.debugging = false;
6025        app.cached = false;
6026        app.killedByAm = false;
6027
6028        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6029
6030        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6031        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6032
6033        if (!normalMode) {
6034            Slog.i(TAG, "Launching preboot mode app: " + app);
6035        }
6036
6037        if (DEBUG_ALL) Slog.v(
6038            TAG, "New app record " + app
6039            + " thread=" + thread.asBinder() + " pid=" + pid);
6040        try {
6041            int testMode = IApplicationThread.DEBUG_OFF;
6042            if (mDebugApp != null && mDebugApp.equals(processName)) {
6043                testMode = mWaitForDebugger
6044                    ? IApplicationThread.DEBUG_WAIT
6045                    : IApplicationThread.DEBUG_ON;
6046                app.debugging = true;
6047                if (mDebugTransient) {
6048                    mDebugApp = mOrigDebugApp;
6049                    mWaitForDebugger = mOrigWaitForDebugger;
6050                }
6051            }
6052            String profileFile = app.instrumentationProfileFile;
6053            ParcelFileDescriptor profileFd = null;
6054            int samplingInterval = 0;
6055            boolean profileAutoStop = false;
6056            if (mProfileApp != null && mProfileApp.equals(processName)) {
6057                mProfileProc = app;
6058                profileFile = mProfileFile;
6059                profileFd = mProfileFd;
6060                samplingInterval = mSamplingInterval;
6061                profileAutoStop = mAutoStopProfiler;
6062            }
6063            boolean enableOpenGlTrace = false;
6064            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6065                enableOpenGlTrace = true;
6066                mOpenGlTraceApp = null;
6067            }
6068
6069            // If the app is being launched for restore or full backup, set it up specially
6070            boolean isRestrictedBackupMode = false;
6071            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6072                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6073                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6074                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6075            }
6076
6077            ensurePackageDexOpt(app.instrumentationInfo != null
6078                    ? app.instrumentationInfo.packageName
6079                    : app.info.packageName);
6080            if (app.instrumentationClass != null) {
6081                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6082            }
6083            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6084                    + processName + " with config " + mConfiguration);
6085            ApplicationInfo appInfo = app.instrumentationInfo != null
6086                    ? app.instrumentationInfo : app.info;
6087            app.compat = compatibilityInfoForPackageLocked(appInfo);
6088            if (profileFd != null) {
6089                profileFd = profileFd.dup();
6090            }
6091            ProfilerInfo profilerInfo = profileFile == null ? null
6092                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6093            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6094                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6095                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6096                    isRestrictedBackupMode || !normalMode, app.persistent,
6097                    new Configuration(mConfiguration), app.compat,
6098                    getCommonServicesLocked(app.isolated),
6099                    mCoreSettingsObserver.getCoreSettingsLocked());
6100            updateLruProcessLocked(app, false, null);
6101            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6102        } catch (Exception e) {
6103            // todo: Yikes!  What should we do?  For now we will try to
6104            // start another process, but that could easily get us in
6105            // an infinite loop of restarting processes...
6106            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6107
6108            app.resetPackageList(mProcessStats);
6109            app.unlinkDeathRecipient();
6110            startProcessLocked(app, "bind fail", processName);
6111            return false;
6112        }
6113
6114        // Remove this record from the list of starting applications.
6115        mPersistentStartingProcesses.remove(app);
6116        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6117                "Attach application locked removing on hold: " + app);
6118        mProcessesOnHold.remove(app);
6119
6120        boolean badApp = false;
6121        boolean didSomething = false;
6122
6123        // See if the top visible activity is waiting to run in this process...
6124        if (normalMode) {
6125            try {
6126                if (mStackSupervisor.attachApplicationLocked(app)) {
6127                    didSomething = true;
6128                }
6129            } catch (Exception e) {
6130                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6131                badApp = true;
6132            }
6133        }
6134
6135        // Find any services that should be running in this process...
6136        if (!badApp) {
6137            try {
6138                didSomething |= mServices.attachApplicationLocked(app, processName);
6139            } catch (Exception e) {
6140                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6141                badApp = true;
6142            }
6143        }
6144
6145        // Check if a next-broadcast receiver is in this process...
6146        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6147            try {
6148                didSomething |= sendPendingBroadcastsLocked(app);
6149            } catch (Exception e) {
6150                // If the app died trying to launch the receiver we declare it 'bad'
6151                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6152                badApp = true;
6153            }
6154        }
6155
6156        // Check whether the next backup agent is in this process...
6157        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6158            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6159                    "New app is backup target, launching agent for " + app);
6160            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6161            try {
6162                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6163                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6164                        mBackupTarget.backupMode);
6165            } catch (Exception e) {
6166                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6167                badApp = true;
6168            }
6169        }
6170
6171        if (badApp) {
6172            app.kill("error during init", true);
6173            handleAppDiedLocked(app, false, true);
6174            return false;
6175        }
6176
6177        if (!didSomething) {
6178            updateOomAdjLocked();
6179        }
6180
6181        return true;
6182    }
6183
6184    @Override
6185    public final void attachApplication(IApplicationThread thread) {
6186        synchronized (this) {
6187            int callingPid = Binder.getCallingPid();
6188            final long origId = Binder.clearCallingIdentity();
6189            attachApplicationLocked(thread, callingPid);
6190            Binder.restoreCallingIdentity(origId);
6191        }
6192    }
6193
6194    @Override
6195    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6196        final long origId = Binder.clearCallingIdentity();
6197        synchronized (this) {
6198            ActivityStack stack = ActivityRecord.getStackLocked(token);
6199            if (stack != null) {
6200                ActivityRecord r =
6201                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6202                if (stopProfiling) {
6203                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6204                        try {
6205                            mProfileFd.close();
6206                        } catch (IOException e) {
6207                        }
6208                        clearProfilerLocked();
6209                    }
6210                }
6211            }
6212        }
6213        Binder.restoreCallingIdentity(origId);
6214    }
6215
6216    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6217        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6218                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6219    }
6220
6221    void enableScreenAfterBoot() {
6222        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6223                SystemClock.uptimeMillis());
6224        mWindowManager.enableScreenAfterBoot();
6225
6226        synchronized (this) {
6227            updateEventDispatchingLocked();
6228        }
6229    }
6230
6231    @Override
6232    public void showBootMessage(final CharSequence msg, final boolean always) {
6233        if (Binder.getCallingUid() != Process.myUid()) {
6234            // These days only the core system can call this, so apps can't get in
6235            // the way of what we show about running them.
6236        }
6237        mWindowManager.showBootMessage(msg, always);
6238    }
6239
6240    @Override
6241    public void keyguardWaitingForActivityDrawn() {
6242        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6243        final long token = Binder.clearCallingIdentity();
6244        try {
6245            synchronized (this) {
6246                if (DEBUG_LOCKSCREEN) logLockScreen("");
6247                mWindowManager.keyguardWaitingForActivityDrawn();
6248                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6249                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6250                    updateSleepIfNeededLocked();
6251                }
6252            }
6253        } finally {
6254            Binder.restoreCallingIdentity(token);
6255        }
6256    }
6257
6258    @Override
6259    public void keyguardGoingAway(boolean disableWindowAnimations,
6260            boolean keyguardGoingToNotificationShade) {
6261        enforceNotIsolatedCaller("keyguardGoingAway");
6262        final long token = Binder.clearCallingIdentity();
6263        try {
6264            synchronized (this) {
6265                if (DEBUG_LOCKSCREEN) logLockScreen("");
6266                mWindowManager.keyguardGoingAway(disableWindowAnimations,
6267                        keyguardGoingToNotificationShade);
6268                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6269                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6270                    updateSleepIfNeededLocked();
6271                }
6272            }
6273        } finally {
6274            Binder.restoreCallingIdentity(token);
6275        }
6276    }
6277
6278    final void finishBooting() {
6279        synchronized (this) {
6280            if (!mBootAnimationComplete) {
6281                mCallFinishBooting = true;
6282                return;
6283            }
6284            mCallFinishBooting = false;
6285        }
6286
6287        ArraySet<String> completedIsas = new ArraySet<String>();
6288        for (String abi : Build.SUPPORTED_ABIS) {
6289            Process.establishZygoteConnectionForAbi(abi);
6290            final String instructionSet = VMRuntime.getInstructionSet(abi);
6291            if (!completedIsas.contains(instructionSet)) {
6292                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6293                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6294                }
6295                completedIsas.add(instructionSet);
6296            }
6297        }
6298
6299        IntentFilter pkgFilter = new IntentFilter();
6300        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6301        pkgFilter.addDataScheme("package");
6302        mContext.registerReceiver(new BroadcastReceiver() {
6303            @Override
6304            public void onReceive(Context context, Intent intent) {
6305                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6306                if (pkgs != null) {
6307                    for (String pkg : pkgs) {
6308                        synchronized (ActivityManagerService.this) {
6309                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6310                                    0, "query restart")) {
6311                                setResultCode(Activity.RESULT_OK);
6312                                return;
6313                            }
6314                        }
6315                    }
6316                }
6317            }
6318        }, pkgFilter);
6319
6320        IntentFilter dumpheapFilter = new IntentFilter();
6321        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6322        mContext.registerReceiver(new BroadcastReceiver() {
6323            @Override
6324            public void onReceive(Context context, Intent intent) {
6325                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6326                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6327                } else {
6328                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6329                }
6330            }
6331        }, dumpheapFilter);
6332
6333        // Let system services know.
6334        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6335
6336        synchronized (this) {
6337            // Ensure that any processes we had put on hold are now started
6338            // up.
6339            final int NP = mProcessesOnHold.size();
6340            if (NP > 0) {
6341                ArrayList<ProcessRecord> procs =
6342                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6343                for (int ip=0; ip<NP; ip++) {
6344                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6345                            + procs.get(ip));
6346                    startProcessLocked(procs.get(ip), "on-hold", null);
6347                }
6348            }
6349
6350            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6351                // Start looking for apps that are abusing wake locks.
6352                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6353                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6354                // Tell anyone interested that we are done booting!
6355                SystemProperties.set("sys.boot_completed", "1");
6356
6357                // And trigger dev.bootcomplete if we are not showing encryption progress
6358                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6359                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6360                    SystemProperties.set("dev.bootcomplete", "1");
6361                }
6362                for (int i=0; i<mStartedUsers.size(); i++) {
6363                    UserState uss = mStartedUsers.valueAt(i);
6364                    if (uss.mState == UserState.STATE_BOOTING) {
6365                        uss.mState = UserState.STATE_RUNNING;
6366                        final int userId = mStartedUsers.keyAt(i);
6367                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6368                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6369                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6370                        broadcastIntentLocked(null, null, intent, null,
6371                                new IIntentReceiver.Stub() {
6372                                    @Override
6373                                    public void performReceive(Intent intent, int resultCode,
6374                                            String data, Bundle extras, boolean ordered,
6375                                            boolean sticky, int sendingUser) {
6376                                        synchronized (ActivityManagerService.this) {
6377                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6378                                                    true, false);
6379                                        }
6380                                    }
6381                                },
6382                                0, null, null,
6383                                new String[] {android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
6384                                AppOpsManager.OP_NONE, null, true, false,
6385                                MY_PID, Process.SYSTEM_UID, userId);
6386                    }
6387                }
6388                scheduleStartProfilesLocked();
6389            }
6390        }
6391    }
6392
6393    @Override
6394    public void bootAnimationComplete() {
6395        final boolean callFinishBooting;
6396        synchronized (this) {
6397            callFinishBooting = mCallFinishBooting;
6398            mBootAnimationComplete = true;
6399        }
6400        if (callFinishBooting) {
6401            finishBooting();
6402        }
6403    }
6404
6405    final void ensureBootCompleted() {
6406        boolean booting;
6407        boolean enableScreen;
6408        synchronized (this) {
6409            booting = mBooting;
6410            mBooting = false;
6411            enableScreen = !mBooted;
6412            mBooted = true;
6413        }
6414
6415        if (booting) {
6416            finishBooting();
6417        }
6418
6419        if (enableScreen) {
6420            enableScreenAfterBoot();
6421        }
6422    }
6423
6424    @Override
6425    public final void activityResumed(IBinder token) {
6426        final long origId = Binder.clearCallingIdentity();
6427        synchronized(this) {
6428            ActivityStack stack = ActivityRecord.getStackLocked(token);
6429            if (stack != null) {
6430                ActivityRecord.activityResumedLocked(token);
6431            }
6432        }
6433        Binder.restoreCallingIdentity(origId);
6434    }
6435
6436    @Override
6437    public final void activityPaused(IBinder token) {
6438        final long origId = Binder.clearCallingIdentity();
6439        synchronized(this) {
6440            ActivityStack stack = ActivityRecord.getStackLocked(token);
6441            if (stack != null) {
6442                stack.activityPausedLocked(token, false);
6443            }
6444        }
6445        Binder.restoreCallingIdentity(origId);
6446    }
6447
6448    @Override
6449    public final void activityStopped(IBinder token, Bundle icicle,
6450            PersistableBundle persistentState, CharSequence description) {
6451        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6452
6453        // Refuse possible leaked file descriptors
6454        if (icicle != null && icicle.hasFileDescriptors()) {
6455            throw new IllegalArgumentException("File descriptors passed in Bundle");
6456        }
6457
6458        final long origId = Binder.clearCallingIdentity();
6459
6460        synchronized (this) {
6461            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6462            if (r != null) {
6463                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6464            }
6465        }
6466
6467        trimApplications();
6468
6469        Binder.restoreCallingIdentity(origId);
6470    }
6471
6472    @Override
6473    public final void activityDestroyed(IBinder token) {
6474        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6475        synchronized (this) {
6476            ActivityStack stack = ActivityRecord.getStackLocked(token);
6477            if (stack != null) {
6478                stack.activityDestroyedLocked(token, "activityDestroyed");
6479            }
6480        }
6481    }
6482
6483    @Override
6484    public final void backgroundResourcesReleased(IBinder token) {
6485        final long origId = Binder.clearCallingIdentity();
6486        try {
6487            synchronized (this) {
6488                ActivityStack stack = ActivityRecord.getStackLocked(token);
6489                if (stack != null) {
6490                    stack.backgroundResourcesReleased();
6491                }
6492            }
6493        } finally {
6494            Binder.restoreCallingIdentity(origId);
6495        }
6496    }
6497
6498    @Override
6499    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6500        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6501    }
6502
6503    @Override
6504    public final void notifyEnterAnimationComplete(IBinder token) {
6505        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6506    }
6507
6508    @Override
6509    public String getCallingPackage(IBinder token) {
6510        synchronized (this) {
6511            ActivityRecord r = getCallingRecordLocked(token);
6512            return r != null ? r.info.packageName : null;
6513        }
6514    }
6515
6516    @Override
6517    public ComponentName getCallingActivity(IBinder token) {
6518        synchronized (this) {
6519            ActivityRecord r = getCallingRecordLocked(token);
6520            return r != null ? r.intent.getComponent() : null;
6521        }
6522    }
6523
6524    private ActivityRecord getCallingRecordLocked(IBinder token) {
6525        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6526        if (r == null) {
6527            return null;
6528        }
6529        return r.resultTo;
6530    }
6531
6532    @Override
6533    public ComponentName getActivityClassForToken(IBinder token) {
6534        synchronized(this) {
6535            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6536            if (r == null) {
6537                return null;
6538            }
6539            return r.intent.getComponent();
6540        }
6541    }
6542
6543    @Override
6544    public String getPackageForToken(IBinder token) {
6545        synchronized(this) {
6546            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6547            if (r == null) {
6548                return null;
6549            }
6550            return r.packageName;
6551        }
6552    }
6553
6554    @Override
6555    public IIntentSender getIntentSender(int type,
6556            String packageName, IBinder token, String resultWho,
6557            int requestCode, Intent[] intents, String[] resolvedTypes,
6558            int flags, Bundle options, int userId) {
6559        enforceNotIsolatedCaller("getIntentSender");
6560        // Refuse possible leaked file descriptors
6561        if (intents != null) {
6562            if (intents.length < 1) {
6563                throw new IllegalArgumentException("Intents array length must be >= 1");
6564            }
6565            for (int i=0; i<intents.length; i++) {
6566                Intent intent = intents[i];
6567                if (intent != null) {
6568                    if (intent.hasFileDescriptors()) {
6569                        throw new IllegalArgumentException("File descriptors passed in Intent");
6570                    }
6571                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6572                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6573                        throw new IllegalArgumentException(
6574                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6575                    }
6576                    intents[i] = new Intent(intent);
6577                }
6578            }
6579            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6580                throw new IllegalArgumentException(
6581                        "Intent array length does not match resolvedTypes length");
6582            }
6583        }
6584        if (options != null) {
6585            if (options.hasFileDescriptors()) {
6586                throw new IllegalArgumentException("File descriptors passed in options");
6587            }
6588        }
6589
6590        synchronized(this) {
6591            int callingUid = Binder.getCallingUid();
6592            int origUserId = userId;
6593            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6594                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6595                    ALLOW_NON_FULL, "getIntentSender", null);
6596            if (origUserId == UserHandle.USER_CURRENT) {
6597                // We don't want to evaluate this until the pending intent is
6598                // actually executed.  However, we do want to always do the
6599                // security checking for it above.
6600                userId = UserHandle.USER_CURRENT;
6601            }
6602            try {
6603                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6604                    int uid = AppGlobals.getPackageManager()
6605                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6606                    if (!UserHandle.isSameApp(callingUid, uid)) {
6607                        String msg = "Permission Denial: getIntentSender() from pid="
6608                            + Binder.getCallingPid()
6609                            + ", uid=" + Binder.getCallingUid()
6610                            + ", (need uid=" + uid + ")"
6611                            + " is not allowed to send as package " + packageName;
6612                        Slog.w(TAG, msg);
6613                        throw new SecurityException(msg);
6614                    }
6615                }
6616
6617                return getIntentSenderLocked(type, packageName, callingUid, userId,
6618                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6619
6620            } catch (RemoteException e) {
6621                throw new SecurityException(e);
6622            }
6623        }
6624    }
6625
6626    IIntentSender getIntentSenderLocked(int type, String packageName,
6627            int callingUid, int userId, IBinder token, String resultWho,
6628            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6629            Bundle options) {
6630        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6631        ActivityRecord activity = null;
6632        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6633            activity = ActivityRecord.isInStackLocked(token);
6634            if (activity == null) {
6635                return null;
6636            }
6637            if (activity.finishing) {
6638                return null;
6639            }
6640        }
6641
6642        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6643        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6644        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6645        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6646                |PendingIntent.FLAG_UPDATE_CURRENT);
6647
6648        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6649                type, packageName, activity, resultWho,
6650                requestCode, intents, resolvedTypes, flags, options, userId);
6651        WeakReference<PendingIntentRecord> ref;
6652        ref = mIntentSenderRecords.get(key);
6653        PendingIntentRecord rec = ref != null ? ref.get() : null;
6654        if (rec != null) {
6655            if (!cancelCurrent) {
6656                if (updateCurrent) {
6657                    if (rec.key.requestIntent != null) {
6658                        rec.key.requestIntent.replaceExtras(intents != null ?
6659                                intents[intents.length - 1] : null);
6660                    }
6661                    if (intents != null) {
6662                        intents[intents.length-1] = rec.key.requestIntent;
6663                        rec.key.allIntents = intents;
6664                        rec.key.allResolvedTypes = resolvedTypes;
6665                    } else {
6666                        rec.key.allIntents = null;
6667                        rec.key.allResolvedTypes = null;
6668                    }
6669                }
6670                return rec;
6671            }
6672            rec.canceled = true;
6673            mIntentSenderRecords.remove(key);
6674        }
6675        if (noCreate) {
6676            return rec;
6677        }
6678        rec = new PendingIntentRecord(this, key, callingUid);
6679        mIntentSenderRecords.put(key, rec.ref);
6680        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6681            if (activity.pendingResults == null) {
6682                activity.pendingResults
6683                        = new HashSet<WeakReference<PendingIntentRecord>>();
6684            }
6685            activity.pendingResults.add(rec.ref);
6686        }
6687        return rec;
6688    }
6689
6690    @Override
6691    public void cancelIntentSender(IIntentSender sender) {
6692        if (!(sender instanceof PendingIntentRecord)) {
6693            return;
6694        }
6695        synchronized(this) {
6696            PendingIntentRecord rec = (PendingIntentRecord)sender;
6697            try {
6698                int uid = AppGlobals.getPackageManager()
6699                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6700                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6701                    String msg = "Permission Denial: cancelIntentSender() from pid="
6702                        + Binder.getCallingPid()
6703                        + ", uid=" + Binder.getCallingUid()
6704                        + " is not allowed to cancel packges "
6705                        + rec.key.packageName;
6706                    Slog.w(TAG, msg);
6707                    throw new SecurityException(msg);
6708                }
6709            } catch (RemoteException e) {
6710                throw new SecurityException(e);
6711            }
6712            cancelIntentSenderLocked(rec, true);
6713        }
6714    }
6715
6716    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6717        rec.canceled = true;
6718        mIntentSenderRecords.remove(rec.key);
6719        if (cleanActivity && rec.key.activity != null) {
6720            rec.key.activity.pendingResults.remove(rec.ref);
6721        }
6722    }
6723
6724    @Override
6725    public String getPackageForIntentSender(IIntentSender pendingResult) {
6726        if (!(pendingResult instanceof PendingIntentRecord)) {
6727            return null;
6728        }
6729        try {
6730            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6731            return res.key.packageName;
6732        } catch (ClassCastException e) {
6733        }
6734        return null;
6735    }
6736
6737    @Override
6738    public int getUidForIntentSender(IIntentSender sender) {
6739        if (sender instanceof PendingIntentRecord) {
6740            try {
6741                PendingIntentRecord res = (PendingIntentRecord)sender;
6742                return res.uid;
6743            } catch (ClassCastException e) {
6744            }
6745        }
6746        return -1;
6747    }
6748
6749    @Override
6750    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6751        if (!(pendingResult instanceof PendingIntentRecord)) {
6752            return false;
6753        }
6754        try {
6755            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6756            if (res.key.allIntents == null) {
6757                return false;
6758            }
6759            for (int i=0; i<res.key.allIntents.length; i++) {
6760                Intent intent = res.key.allIntents[i];
6761                if (intent.getPackage() != null && intent.getComponent() != null) {
6762                    return false;
6763                }
6764            }
6765            return true;
6766        } catch (ClassCastException e) {
6767        }
6768        return false;
6769    }
6770
6771    @Override
6772    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6773        if (!(pendingResult instanceof PendingIntentRecord)) {
6774            return false;
6775        }
6776        try {
6777            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6778            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6779                return true;
6780            }
6781            return false;
6782        } catch (ClassCastException e) {
6783        }
6784        return false;
6785    }
6786
6787    @Override
6788    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6789        if (!(pendingResult instanceof PendingIntentRecord)) {
6790            return null;
6791        }
6792        try {
6793            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6794            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6795        } catch (ClassCastException e) {
6796        }
6797        return null;
6798    }
6799
6800    @Override
6801    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6802        if (!(pendingResult instanceof PendingIntentRecord)) {
6803            return null;
6804        }
6805        try {
6806            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6807            synchronized (this) {
6808                return getTagForIntentSenderLocked(res, prefix);
6809            }
6810        } catch (ClassCastException e) {
6811        }
6812        return null;
6813    }
6814
6815    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
6816        final Intent intent = res.key.requestIntent;
6817        if (intent != null) {
6818            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6819                    || res.lastTagPrefix.equals(prefix))) {
6820                return res.lastTag;
6821            }
6822            res.lastTagPrefix = prefix;
6823            final StringBuilder sb = new StringBuilder(128);
6824            if (prefix != null) {
6825                sb.append(prefix);
6826            }
6827            if (intent.getAction() != null) {
6828                sb.append(intent.getAction());
6829            } else if (intent.getComponent() != null) {
6830                intent.getComponent().appendShortString(sb);
6831            } else {
6832                sb.append("?");
6833            }
6834            return res.lastTag = sb.toString();
6835        }
6836        return null;
6837    }
6838
6839    @Override
6840    public void setProcessLimit(int max) {
6841        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6842                "setProcessLimit()");
6843        synchronized (this) {
6844            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6845            mProcessLimitOverride = max;
6846        }
6847        trimApplications();
6848    }
6849
6850    @Override
6851    public int getProcessLimit() {
6852        synchronized (this) {
6853            return mProcessLimitOverride;
6854        }
6855    }
6856
6857    void foregroundTokenDied(ForegroundToken token) {
6858        synchronized (ActivityManagerService.this) {
6859            synchronized (mPidsSelfLocked) {
6860                ForegroundToken cur
6861                    = mForegroundProcesses.get(token.pid);
6862                if (cur != token) {
6863                    return;
6864                }
6865                mForegroundProcesses.remove(token.pid);
6866                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6867                if (pr == null) {
6868                    return;
6869                }
6870                pr.forcingToForeground = null;
6871                updateProcessForegroundLocked(pr, false, false);
6872            }
6873            updateOomAdjLocked();
6874        }
6875    }
6876
6877    @Override
6878    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6879        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6880                "setProcessForeground()");
6881        synchronized(this) {
6882            boolean changed = false;
6883
6884            synchronized (mPidsSelfLocked) {
6885                ProcessRecord pr = mPidsSelfLocked.get(pid);
6886                if (pr == null && isForeground) {
6887                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6888                    return;
6889                }
6890                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6891                if (oldToken != null) {
6892                    oldToken.token.unlinkToDeath(oldToken, 0);
6893                    mForegroundProcesses.remove(pid);
6894                    if (pr != null) {
6895                        pr.forcingToForeground = null;
6896                    }
6897                    changed = true;
6898                }
6899                if (isForeground && token != null) {
6900                    ForegroundToken newToken = new ForegroundToken() {
6901                        @Override
6902                        public void binderDied() {
6903                            foregroundTokenDied(this);
6904                        }
6905                    };
6906                    newToken.pid = pid;
6907                    newToken.token = token;
6908                    try {
6909                        token.linkToDeath(newToken, 0);
6910                        mForegroundProcesses.put(pid, newToken);
6911                        pr.forcingToForeground = token;
6912                        changed = true;
6913                    } catch (RemoteException e) {
6914                        // If the process died while doing this, we will later
6915                        // do the cleanup with the process death link.
6916                    }
6917                }
6918            }
6919
6920            if (changed) {
6921                updateOomAdjLocked();
6922            }
6923        }
6924    }
6925
6926    // =========================================================
6927    // PROCESS INFO
6928    // =========================================================
6929
6930    static class ProcessInfoService extends IProcessInfoService.Stub {
6931        final ActivityManagerService mActivityManagerService;
6932        ProcessInfoService(ActivityManagerService activityManagerService) {
6933            mActivityManagerService = activityManagerService;
6934        }
6935
6936        @Override
6937        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
6938            mActivityManagerService.getProcessStatesForPIDs(/*in*/ pids, /*out*/ states);
6939        }
6940    }
6941
6942    /**
6943     * For each PID in the given input array, write the current process state
6944     * for that process into the output array, or -1 to indicate that no
6945     * process with the given PID exists.
6946     */
6947    public void getProcessStatesForPIDs(/*in*/ int[] pids, /*out*/ int[] states) {
6948        if (pids == null) {
6949            throw new NullPointerException("pids");
6950        } else if (states == null) {
6951            throw new NullPointerException("states");
6952        } else if (pids.length != states.length) {
6953            throw new IllegalArgumentException("input and output arrays have different lengths!");
6954        }
6955
6956        synchronized (mPidsSelfLocked) {
6957            for (int i = 0; i < pids.length; i++) {
6958                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
6959                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
6960                        pr.curProcState;
6961            }
6962        }
6963    }
6964
6965    // =========================================================
6966    // PERMISSIONS
6967    // =========================================================
6968
6969    static class PermissionController extends IPermissionController.Stub {
6970        ActivityManagerService mActivityManagerService;
6971        PermissionController(ActivityManagerService activityManagerService) {
6972            mActivityManagerService = activityManagerService;
6973        }
6974
6975        @Override
6976        public boolean checkPermission(String permission, int pid, int uid) {
6977            return mActivityManagerService.checkPermission(permission, pid,
6978                    uid) == PackageManager.PERMISSION_GRANTED;
6979        }
6980
6981        @Override
6982        public String[] getPackagesForUid(int uid) {
6983            return mActivityManagerService.mContext.getPackageManager()
6984                    .getPackagesForUid(uid);
6985        }
6986
6987        @Override
6988        public boolean isRuntimePermission(String permission) {
6989            try {
6990                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
6991                        .getPermissionInfo(permission, 0);
6992                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
6993            } catch (NameNotFoundException nnfe) {
6994                Slog.e(TAG, "No such permission: "+ permission, nnfe);
6995            }
6996            return false;
6997        }
6998    }
6999
7000    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7001        @Override
7002        public int checkComponentPermission(String permission, int pid, int uid,
7003                int owningUid, boolean exported) {
7004            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7005                    owningUid, exported);
7006        }
7007
7008        @Override
7009        public Object getAMSLock() {
7010            return ActivityManagerService.this;
7011        }
7012    }
7013
7014    /**
7015     * This can be called with or without the global lock held.
7016     */
7017    int checkComponentPermission(String permission, int pid, int uid,
7018            int owningUid, boolean exported) {
7019        if (pid == MY_PID) {
7020            return PackageManager.PERMISSION_GRANTED;
7021        }
7022        return ActivityManager.checkComponentPermission(permission, uid,
7023                owningUid, exported);
7024    }
7025
7026    /**
7027     * As the only public entry point for permissions checking, this method
7028     * can enforce the semantic that requesting a check on a null global
7029     * permission is automatically denied.  (Internally a null permission
7030     * string is used when calling {@link #checkComponentPermission} in cases
7031     * when only uid-based security is needed.)
7032     *
7033     * This can be called with or without the global lock held.
7034     */
7035    @Override
7036    public int checkPermission(String permission, int pid, int uid) {
7037        if (permission == null) {
7038            return PackageManager.PERMISSION_DENIED;
7039        }
7040        return checkComponentPermission(permission, pid, uid, -1, true);
7041    }
7042
7043    @Override
7044    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7045        if (permission == null) {
7046            return PackageManager.PERMISSION_DENIED;
7047        }
7048
7049        // We might be performing an operation on behalf of an indirect binder
7050        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7051        // client identity accordingly before proceeding.
7052        Identity tlsIdentity = sCallerIdentity.get();
7053        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7054            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7055                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7056            uid = tlsIdentity.uid;
7057            pid = tlsIdentity.pid;
7058        }
7059
7060        return checkComponentPermission(permission, pid, uid, -1, true);
7061    }
7062
7063    /**
7064     * Binder IPC calls go through the public entry point.
7065     * This can be called with or without the global lock held.
7066     */
7067    int checkCallingPermission(String permission) {
7068        return checkPermission(permission,
7069                Binder.getCallingPid(),
7070                UserHandle.getAppId(Binder.getCallingUid()));
7071    }
7072
7073    /**
7074     * This can be called with or without the global lock held.
7075     */
7076    void enforceCallingPermission(String permission, String func) {
7077        if (checkCallingPermission(permission)
7078                == PackageManager.PERMISSION_GRANTED) {
7079            return;
7080        }
7081
7082        String msg = "Permission Denial: " + func + " from pid="
7083                + Binder.getCallingPid()
7084                + ", uid=" + Binder.getCallingUid()
7085                + " requires " + permission;
7086        Slog.w(TAG, msg);
7087        throw new SecurityException(msg);
7088    }
7089
7090    /**
7091     * Determine if UID is holding permissions required to access {@link Uri} in
7092     * the given {@link ProviderInfo}. Final permission checking is always done
7093     * in {@link ContentProvider}.
7094     */
7095    private final boolean checkHoldingPermissionsLocked(
7096            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7097        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7098                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7099        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7100            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7101                    != PERMISSION_GRANTED) {
7102                return false;
7103            }
7104        }
7105        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7106    }
7107
7108    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7109            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7110        if (pi.applicationInfo.uid == uid) {
7111            return true;
7112        } else if (!pi.exported) {
7113            return false;
7114        }
7115
7116        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7117        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7118        try {
7119            // check if target holds top-level <provider> permissions
7120            if (!readMet && pi.readPermission != null && considerUidPermissions
7121                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7122                readMet = true;
7123            }
7124            if (!writeMet && pi.writePermission != null && considerUidPermissions
7125                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7126                writeMet = true;
7127            }
7128
7129            // track if unprotected read/write is allowed; any denied
7130            // <path-permission> below removes this ability
7131            boolean allowDefaultRead = pi.readPermission == null;
7132            boolean allowDefaultWrite = pi.writePermission == null;
7133
7134            // check if target holds any <path-permission> that match uri
7135            final PathPermission[] pps = pi.pathPermissions;
7136            if (pps != null) {
7137                final String path = grantUri.uri.getPath();
7138                int i = pps.length;
7139                while (i > 0 && (!readMet || !writeMet)) {
7140                    i--;
7141                    PathPermission pp = pps[i];
7142                    if (pp.match(path)) {
7143                        if (!readMet) {
7144                            final String pprperm = pp.getReadPermission();
7145                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7146                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7147                                    + ": match=" + pp.match(path)
7148                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7149                            if (pprperm != null) {
7150                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7151                                        == PERMISSION_GRANTED) {
7152                                    readMet = true;
7153                                } else {
7154                                    allowDefaultRead = false;
7155                                }
7156                            }
7157                        }
7158                        if (!writeMet) {
7159                            final String ppwperm = pp.getWritePermission();
7160                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7161                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7162                                    + ": match=" + pp.match(path)
7163                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7164                            if (ppwperm != null) {
7165                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7166                                        == PERMISSION_GRANTED) {
7167                                    writeMet = true;
7168                                } else {
7169                                    allowDefaultWrite = false;
7170                                }
7171                            }
7172                        }
7173                    }
7174                }
7175            }
7176
7177            // grant unprotected <provider> read/write, if not blocked by
7178            // <path-permission> above
7179            if (allowDefaultRead) readMet = true;
7180            if (allowDefaultWrite) writeMet = true;
7181
7182        } catch (RemoteException e) {
7183            return false;
7184        }
7185
7186        return readMet && writeMet;
7187    }
7188
7189    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7190        ProviderInfo pi = null;
7191        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7192        if (cpr != null) {
7193            pi = cpr.info;
7194        } else {
7195            try {
7196                pi = AppGlobals.getPackageManager().resolveContentProvider(
7197                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7198            } catch (RemoteException ex) {
7199            }
7200        }
7201        return pi;
7202    }
7203
7204    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7205        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7206        if (targetUris != null) {
7207            return targetUris.get(grantUri);
7208        }
7209        return null;
7210    }
7211
7212    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7213            String targetPkg, int targetUid, GrantUri grantUri) {
7214        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7215        if (targetUris == null) {
7216            targetUris = Maps.newArrayMap();
7217            mGrantedUriPermissions.put(targetUid, targetUris);
7218        }
7219
7220        UriPermission perm = targetUris.get(grantUri);
7221        if (perm == null) {
7222            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7223            targetUris.put(grantUri, perm);
7224        }
7225
7226        return perm;
7227    }
7228
7229    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7230            final int modeFlags) {
7231        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7232        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7233                : UriPermission.STRENGTH_OWNED;
7234
7235        // Root gets to do everything.
7236        if (uid == 0) {
7237            return true;
7238        }
7239
7240        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7241        if (perms == null) return false;
7242
7243        // First look for exact match
7244        final UriPermission exactPerm = perms.get(grantUri);
7245        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7246            return true;
7247        }
7248
7249        // No exact match, look for prefixes
7250        final int N = perms.size();
7251        for (int i = 0; i < N; i++) {
7252            final UriPermission perm = perms.valueAt(i);
7253            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7254                    && perm.getStrength(modeFlags) >= minStrength) {
7255                return true;
7256            }
7257        }
7258
7259        return false;
7260    }
7261
7262    /**
7263     * @param uri This uri must NOT contain an embedded userId.
7264     * @param userId The userId in which the uri is to be resolved.
7265     */
7266    @Override
7267    public int checkUriPermission(Uri uri, int pid, int uid,
7268            final int modeFlags, int userId, IBinder callerToken) {
7269        enforceNotIsolatedCaller("checkUriPermission");
7270
7271        // Another redirected-binder-call permissions check as in
7272        // {@link checkPermissionWithToken}.
7273        Identity tlsIdentity = sCallerIdentity.get();
7274        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7275            uid = tlsIdentity.uid;
7276            pid = tlsIdentity.pid;
7277        }
7278
7279        // Our own process gets to do everything.
7280        if (pid == MY_PID) {
7281            return PackageManager.PERMISSION_GRANTED;
7282        }
7283        synchronized (this) {
7284            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7285                    ? PackageManager.PERMISSION_GRANTED
7286                    : PackageManager.PERMISSION_DENIED;
7287        }
7288    }
7289
7290    /**
7291     * Check if the targetPkg can be granted permission to access uri by
7292     * the callingUid using the given modeFlags.  Throws a security exception
7293     * if callingUid is not allowed to do this.  Returns the uid of the target
7294     * if the URI permission grant should be performed; returns -1 if it is not
7295     * needed (for example targetPkg already has permission to access the URI).
7296     * If you already know the uid of the target, you can supply it in
7297     * lastTargetUid else set that to -1.
7298     */
7299    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7300            final int modeFlags, int lastTargetUid) {
7301        if (!Intent.isAccessUriMode(modeFlags)) {
7302            return -1;
7303        }
7304
7305        if (targetPkg != null) {
7306            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7307                    "Checking grant " + targetPkg + " permission to " + grantUri);
7308        }
7309
7310        final IPackageManager pm = AppGlobals.getPackageManager();
7311
7312        // If this is not a content: uri, we can't do anything with it.
7313        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7314            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7315                    "Can't grant URI permission for non-content URI: " + grantUri);
7316            return -1;
7317        }
7318
7319        final String authority = grantUri.uri.getAuthority();
7320        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7321        if (pi == null) {
7322            Slog.w(TAG, "No content provider found for permission check: " +
7323                    grantUri.uri.toSafeString());
7324            return -1;
7325        }
7326
7327        int targetUid = lastTargetUid;
7328        if (targetUid < 0 && targetPkg != null) {
7329            try {
7330                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7331                if (targetUid < 0) {
7332                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7333                            "Can't grant URI permission no uid for: " + targetPkg);
7334                    return -1;
7335                }
7336            } catch (RemoteException ex) {
7337                return -1;
7338            }
7339        }
7340
7341        if (targetUid >= 0) {
7342            // First...  does the target actually need this permission?
7343            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7344                // No need to grant the target this permission.
7345                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7346                        "Target " + targetPkg + " already has full permission to " + grantUri);
7347                return -1;
7348            }
7349        } else {
7350            // First...  there is no target package, so can anyone access it?
7351            boolean allowed = pi.exported;
7352            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7353                if (pi.readPermission != null) {
7354                    allowed = false;
7355                }
7356            }
7357            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7358                if (pi.writePermission != null) {
7359                    allowed = false;
7360                }
7361            }
7362            if (allowed) {
7363                return -1;
7364            }
7365        }
7366
7367        /* There is a special cross user grant if:
7368         * - The target is on another user.
7369         * - Apps on the current user can access the uri without any uid permissions.
7370         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7371         * grant uri permissions.
7372         */
7373        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7374                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7375                modeFlags, false /*without considering the uid permissions*/);
7376
7377        // Second...  is the provider allowing granting of URI permissions?
7378        if (!specialCrossUserGrant) {
7379            if (!pi.grantUriPermissions) {
7380                throw new SecurityException("Provider " + pi.packageName
7381                        + "/" + pi.name
7382                        + " does not allow granting of Uri permissions (uri "
7383                        + grantUri + ")");
7384            }
7385            if (pi.uriPermissionPatterns != null) {
7386                final int N = pi.uriPermissionPatterns.length;
7387                boolean allowed = false;
7388                for (int i=0; i<N; i++) {
7389                    if (pi.uriPermissionPatterns[i] != null
7390                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7391                        allowed = true;
7392                        break;
7393                    }
7394                }
7395                if (!allowed) {
7396                    throw new SecurityException("Provider " + pi.packageName
7397                            + "/" + pi.name
7398                            + " does not allow granting of permission to path of Uri "
7399                            + grantUri);
7400                }
7401            }
7402        }
7403
7404        // Third...  does the caller itself have permission to access
7405        // this uri?
7406        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7407            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7408                // Require they hold a strong enough Uri permission
7409                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7410                    throw new SecurityException("Uid " + callingUid
7411                            + " does not have permission to uri " + grantUri);
7412                }
7413            }
7414        }
7415        return targetUid;
7416    }
7417
7418    /**
7419     * @param uri This uri must NOT contain an embedded userId.
7420     * @param userId The userId in which the uri is to be resolved.
7421     */
7422    @Override
7423    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7424            final int modeFlags, int userId) {
7425        enforceNotIsolatedCaller("checkGrantUriPermission");
7426        synchronized(this) {
7427            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7428                    new GrantUri(userId, uri, false), modeFlags, -1);
7429        }
7430    }
7431
7432    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7433            final int modeFlags, UriPermissionOwner owner) {
7434        if (!Intent.isAccessUriMode(modeFlags)) {
7435            return;
7436        }
7437
7438        // So here we are: the caller has the assumed permission
7439        // to the uri, and the target doesn't.  Let's now give this to
7440        // the target.
7441
7442        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7443                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7444
7445        final String authority = grantUri.uri.getAuthority();
7446        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7447        if (pi == null) {
7448            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7449            return;
7450        }
7451
7452        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7453            grantUri.prefix = true;
7454        }
7455        final UriPermission perm = findOrCreateUriPermissionLocked(
7456                pi.packageName, targetPkg, targetUid, grantUri);
7457        perm.grantModes(modeFlags, owner);
7458    }
7459
7460    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7461            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7462        if (targetPkg == null) {
7463            throw new NullPointerException("targetPkg");
7464        }
7465        int targetUid;
7466        final IPackageManager pm = AppGlobals.getPackageManager();
7467        try {
7468            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7469        } catch (RemoteException ex) {
7470            return;
7471        }
7472
7473        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7474                targetUid);
7475        if (targetUid < 0) {
7476            return;
7477        }
7478
7479        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7480                owner);
7481    }
7482
7483    static class NeededUriGrants extends ArrayList<GrantUri> {
7484        final String targetPkg;
7485        final int targetUid;
7486        final int flags;
7487
7488        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7489            this.targetPkg = targetPkg;
7490            this.targetUid = targetUid;
7491            this.flags = flags;
7492        }
7493    }
7494
7495    /**
7496     * Like checkGrantUriPermissionLocked, but takes an Intent.
7497     */
7498    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7499            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7500        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7501                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7502                + " clip=" + (intent != null ? intent.getClipData() : null)
7503                + " from " + intent + "; flags=0x"
7504                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7505
7506        if (targetPkg == null) {
7507            throw new NullPointerException("targetPkg");
7508        }
7509
7510        if (intent == null) {
7511            return null;
7512        }
7513        Uri data = intent.getData();
7514        ClipData clip = intent.getClipData();
7515        if (data == null && clip == null) {
7516            return null;
7517        }
7518        // Default userId for uris in the intent (if they don't specify it themselves)
7519        int contentUserHint = intent.getContentUserHint();
7520        if (contentUserHint == UserHandle.USER_CURRENT) {
7521            contentUserHint = UserHandle.getUserId(callingUid);
7522        }
7523        final IPackageManager pm = AppGlobals.getPackageManager();
7524        int targetUid;
7525        if (needed != null) {
7526            targetUid = needed.targetUid;
7527        } else {
7528            try {
7529                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7530            } catch (RemoteException ex) {
7531                return null;
7532            }
7533            if (targetUid < 0) {
7534                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7535                        "Can't grant URI permission no uid for: " + targetPkg
7536                        + " on user " + targetUserId);
7537                return null;
7538            }
7539        }
7540        if (data != null) {
7541            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7542            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7543                    targetUid);
7544            if (targetUid > 0) {
7545                if (needed == null) {
7546                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7547                }
7548                needed.add(grantUri);
7549            }
7550        }
7551        if (clip != null) {
7552            for (int i=0; i<clip.getItemCount(); i++) {
7553                Uri uri = clip.getItemAt(i).getUri();
7554                if (uri != null) {
7555                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7556                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7557                            targetUid);
7558                    if (targetUid > 0) {
7559                        if (needed == null) {
7560                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7561                        }
7562                        needed.add(grantUri);
7563                    }
7564                } else {
7565                    Intent clipIntent = clip.getItemAt(i).getIntent();
7566                    if (clipIntent != null) {
7567                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7568                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7569                        if (newNeeded != null) {
7570                            needed = newNeeded;
7571                        }
7572                    }
7573                }
7574            }
7575        }
7576
7577        return needed;
7578    }
7579
7580    /**
7581     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7582     */
7583    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7584            UriPermissionOwner owner) {
7585        if (needed != null) {
7586            for (int i=0; i<needed.size(); i++) {
7587                GrantUri grantUri = needed.get(i);
7588                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7589                        grantUri, needed.flags, owner);
7590            }
7591        }
7592    }
7593
7594    void grantUriPermissionFromIntentLocked(int callingUid,
7595            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7596        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7597                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7598        if (needed == null) {
7599            return;
7600        }
7601
7602        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7603    }
7604
7605    /**
7606     * @param uri This uri must NOT contain an embedded userId.
7607     * @param userId The userId in which the uri is to be resolved.
7608     */
7609    @Override
7610    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7611            final int modeFlags, int userId) {
7612        enforceNotIsolatedCaller("grantUriPermission");
7613        GrantUri grantUri = new GrantUri(userId, uri, false);
7614        synchronized(this) {
7615            final ProcessRecord r = getRecordForAppLocked(caller);
7616            if (r == null) {
7617                throw new SecurityException("Unable to find app for caller "
7618                        + caller
7619                        + " when granting permission to uri " + grantUri);
7620            }
7621            if (targetPkg == null) {
7622                throw new IllegalArgumentException("null target");
7623            }
7624            if (grantUri == null) {
7625                throw new IllegalArgumentException("null uri");
7626            }
7627
7628            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7629                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7630                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7631                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7632
7633            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7634                    UserHandle.getUserId(r.uid));
7635        }
7636    }
7637
7638    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7639        if (perm.modeFlags == 0) {
7640            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7641                    perm.targetUid);
7642            if (perms != null) {
7643                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7644                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7645
7646                perms.remove(perm.uri);
7647                if (perms.isEmpty()) {
7648                    mGrantedUriPermissions.remove(perm.targetUid);
7649                }
7650            }
7651        }
7652    }
7653
7654    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7655        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7656                "Revoking all granted permissions to " + grantUri);
7657
7658        final IPackageManager pm = AppGlobals.getPackageManager();
7659        final String authority = grantUri.uri.getAuthority();
7660        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7661        if (pi == null) {
7662            Slog.w(TAG, "No content provider found for permission revoke: "
7663                    + grantUri.toSafeString());
7664            return;
7665        }
7666
7667        // Does the caller have this permission on the URI?
7668        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7669            // If they don't have direct access to the URI, then revoke any
7670            // ownerless URI permissions that have been granted to them.
7671            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7672            if (perms != null) {
7673                boolean persistChanged = false;
7674                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7675                    final UriPermission perm = it.next();
7676                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7677                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7678                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7679                                "Revoking non-owned " + perm.targetUid
7680                                + " permission to " + perm.uri);
7681                        persistChanged |= perm.revokeModes(
7682                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7683                        if (perm.modeFlags == 0) {
7684                            it.remove();
7685                        }
7686                    }
7687                }
7688                if (perms.isEmpty()) {
7689                    mGrantedUriPermissions.remove(callingUid);
7690                }
7691                if (persistChanged) {
7692                    schedulePersistUriGrants();
7693                }
7694            }
7695            return;
7696        }
7697
7698        boolean persistChanged = false;
7699
7700        // Go through all of the permissions and remove any that match.
7701        int N = mGrantedUriPermissions.size();
7702        for (int i = 0; i < N; i++) {
7703            final int targetUid = mGrantedUriPermissions.keyAt(i);
7704            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7705
7706            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7707                final UriPermission perm = it.next();
7708                if (perm.uri.sourceUserId == grantUri.sourceUserId
7709                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7710                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7711                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7712                    persistChanged |= perm.revokeModes(
7713                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7714                    if (perm.modeFlags == 0) {
7715                        it.remove();
7716                    }
7717                }
7718            }
7719
7720            if (perms.isEmpty()) {
7721                mGrantedUriPermissions.remove(targetUid);
7722                N--;
7723                i--;
7724            }
7725        }
7726
7727        if (persistChanged) {
7728            schedulePersistUriGrants();
7729        }
7730    }
7731
7732    /**
7733     * @param uri This uri must NOT contain an embedded userId.
7734     * @param userId The userId in which the uri is to be resolved.
7735     */
7736    @Override
7737    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7738            int userId) {
7739        enforceNotIsolatedCaller("revokeUriPermission");
7740        synchronized(this) {
7741            final ProcessRecord r = getRecordForAppLocked(caller);
7742            if (r == null) {
7743                throw new SecurityException("Unable to find app for caller "
7744                        + caller
7745                        + " when revoking permission to uri " + uri);
7746            }
7747            if (uri == null) {
7748                Slog.w(TAG, "revokeUriPermission: null uri");
7749                return;
7750            }
7751
7752            if (!Intent.isAccessUriMode(modeFlags)) {
7753                return;
7754            }
7755
7756            final String authority = uri.getAuthority();
7757            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7758            if (pi == null) {
7759                Slog.w(TAG, "No content provider found for permission revoke: "
7760                        + uri.toSafeString());
7761                return;
7762            }
7763
7764            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7765        }
7766    }
7767
7768    /**
7769     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7770     * given package.
7771     *
7772     * @param packageName Package name to match, or {@code null} to apply to all
7773     *            packages.
7774     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7775     *            to all users.
7776     * @param persistable If persistable grants should be removed.
7777     */
7778    private void removeUriPermissionsForPackageLocked(
7779            String packageName, int userHandle, boolean persistable) {
7780        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7781            throw new IllegalArgumentException("Must narrow by either package or user");
7782        }
7783
7784        boolean persistChanged = false;
7785
7786        int N = mGrantedUriPermissions.size();
7787        for (int i = 0; i < N; i++) {
7788            final int targetUid = mGrantedUriPermissions.keyAt(i);
7789            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7790
7791            // Only inspect grants matching user
7792            if (userHandle == UserHandle.USER_ALL
7793                    || userHandle == UserHandle.getUserId(targetUid)) {
7794                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7795                    final UriPermission perm = it.next();
7796
7797                    // Only inspect grants matching package
7798                    if (packageName == null || perm.sourcePkg.equals(packageName)
7799                            || perm.targetPkg.equals(packageName)) {
7800                        persistChanged |= perm.revokeModes(persistable
7801                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7802
7803                        // Only remove when no modes remain; any persisted grants
7804                        // will keep this alive.
7805                        if (perm.modeFlags == 0) {
7806                            it.remove();
7807                        }
7808                    }
7809                }
7810
7811                if (perms.isEmpty()) {
7812                    mGrantedUriPermissions.remove(targetUid);
7813                    N--;
7814                    i--;
7815                }
7816            }
7817        }
7818
7819        if (persistChanged) {
7820            schedulePersistUriGrants();
7821        }
7822    }
7823
7824    @Override
7825    public IBinder newUriPermissionOwner(String name) {
7826        enforceNotIsolatedCaller("newUriPermissionOwner");
7827        synchronized(this) {
7828            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7829            return owner.getExternalTokenLocked();
7830        }
7831    }
7832
7833    /**
7834     * @param uri This uri must NOT contain an embedded userId.
7835     * @param sourceUserId The userId in which the uri is to be resolved.
7836     * @param targetUserId The userId of the app that receives the grant.
7837     */
7838    @Override
7839    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7840            final int modeFlags, int sourceUserId, int targetUserId) {
7841        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7842                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7843        synchronized(this) {
7844            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7845            if (owner == null) {
7846                throw new IllegalArgumentException("Unknown owner: " + token);
7847            }
7848            if (fromUid != Binder.getCallingUid()) {
7849                if (Binder.getCallingUid() != Process.myUid()) {
7850                    // Only system code can grant URI permissions on behalf
7851                    // of other users.
7852                    throw new SecurityException("nice try");
7853                }
7854            }
7855            if (targetPkg == null) {
7856                throw new IllegalArgumentException("null target");
7857            }
7858            if (uri == null) {
7859                throw new IllegalArgumentException("null uri");
7860            }
7861
7862            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7863                    modeFlags, owner, targetUserId);
7864        }
7865    }
7866
7867    /**
7868     * @param uri This uri must NOT contain an embedded userId.
7869     * @param userId The userId in which the uri is to be resolved.
7870     */
7871    @Override
7872    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7873        synchronized(this) {
7874            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7875            if (owner == null) {
7876                throw new IllegalArgumentException("Unknown owner: " + token);
7877            }
7878
7879            if (uri == null) {
7880                owner.removeUriPermissionsLocked(mode);
7881            } else {
7882                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7883            }
7884        }
7885    }
7886
7887    private void schedulePersistUriGrants() {
7888        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7889            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7890                    10 * DateUtils.SECOND_IN_MILLIS);
7891        }
7892    }
7893
7894    private void writeGrantedUriPermissions() {
7895        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
7896
7897        // Snapshot permissions so we can persist without lock
7898        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7899        synchronized (this) {
7900            final int size = mGrantedUriPermissions.size();
7901            for (int i = 0; i < size; i++) {
7902                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7903                for (UriPermission perm : perms.values()) {
7904                    if (perm.persistedModeFlags != 0) {
7905                        persist.add(perm.snapshot());
7906                    }
7907                }
7908            }
7909        }
7910
7911        FileOutputStream fos = null;
7912        try {
7913            fos = mGrantFile.startWrite();
7914
7915            XmlSerializer out = new FastXmlSerializer();
7916            out.setOutput(fos, StandardCharsets.UTF_8.name());
7917            out.startDocument(null, true);
7918            out.startTag(null, TAG_URI_GRANTS);
7919            for (UriPermission.Snapshot perm : persist) {
7920                out.startTag(null, TAG_URI_GRANT);
7921                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7922                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7923                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7924                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7925                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7926                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7927                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7928                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7929                out.endTag(null, TAG_URI_GRANT);
7930            }
7931            out.endTag(null, TAG_URI_GRANTS);
7932            out.endDocument();
7933
7934            mGrantFile.finishWrite(fos);
7935        } catch (IOException e) {
7936            if (fos != null) {
7937                mGrantFile.failWrite(fos);
7938            }
7939        }
7940    }
7941
7942    private void readGrantedUriPermissionsLocked() {
7943        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
7944
7945        final long now = System.currentTimeMillis();
7946
7947        FileInputStream fis = null;
7948        try {
7949            fis = mGrantFile.openRead();
7950            final XmlPullParser in = Xml.newPullParser();
7951            in.setInput(fis, StandardCharsets.UTF_8.name());
7952
7953            int type;
7954            while ((type = in.next()) != END_DOCUMENT) {
7955                final String tag = in.getName();
7956                if (type == START_TAG) {
7957                    if (TAG_URI_GRANT.equals(tag)) {
7958                        final int sourceUserId;
7959                        final int targetUserId;
7960                        final int userHandle = readIntAttribute(in,
7961                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7962                        if (userHandle != UserHandle.USER_NULL) {
7963                            // For backwards compatibility.
7964                            sourceUserId = userHandle;
7965                            targetUserId = userHandle;
7966                        } else {
7967                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7968                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7969                        }
7970                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7971                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7972                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7973                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7974                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7975                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7976
7977                        // Sanity check that provider still belongs to source package
7978                        final ProviderInfo pi = getProviderInfoLocked(
7979                                uri.getAuthority(), sourceUserId);
7980                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7981                            int targetUid = -1;
7982                            try {
7983                                targetUid = AppGlobals.getPackageManager()
7984                                        .getPackageUid(targetPkg, targetUserId);
7985                            } catch (RemoteException e) {
7986                            }
7987                            if (targetUid != -1) {
7988                                final UriPermission perm = findOrCreateUriPermissionLocked(
7989                                        sourcePkg, targetPkg, targetUid,
7990                                        new GrantUri(sourceUserId, uri, prefix));
7991                                perm.initPersistedModes(modeFlags, createdTime);
7992                            }
7993                        } else {
7994                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7995                                    + " but instead found " + pi);
7996                        }
7997                    }
7998                }
7999            }
8000        } catch (FileNotFoundException e) {
8001            // Missing grants is okay
8002        } catch (IOException e) {
8003            Slog.wtf(TAG, "Failed reading Uri grants", e);
8004        } catch (XmlPullParserException e) {
8005            Slog.wtf(TAG, "Failed reading Uri grants", e);
8006        } finally {
8007            IoUtils.closeQuietly(fis);
8008        }
8009    }
8010
8011    /**
8012     * @param uri This uri must NOT contain an embedded userId.
8013     * @param userId The userId in which the uri is to be resolved.
8014     */
8015    @Override
8016    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8017        enforceNotIsolatedCaller("takePersistableUriPermission");
8018
8019        Preconditions.checkFlagsArgument(modeFlags,
8020                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8021
8022        synchronized (this) {
8023            final int callingUid = Binder.getCallingUid();
8024            boolean persistChanged = false;
8025            GrantUri grantUri = new GrantUri(userId, uri, false);
8026
8027            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8028                    new GrantUri(userId, uri, false));
8029            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8030                    new GrantUri(userId, uri, true));
8031
8032            final boolean exactValid = (exactPerm != null)
8033                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8034            final boolean prefixValid = (prefixPerm != null)
8035                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8036
8037            if (!(exactValid || prefixValid)) {
8038                throw new SecurityException("No persistable permission grants found for UID "
8039                        + callingUid + " and Uri " + grantUri.toSafeString());
8040            }
8041
8042            if (exactValid) {
8043                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8044            }
8045            if (prefixValid) {
8046                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8047            }
8048
8049            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8050
8051            if (persistChanged) {
8052                schedulePersistUriGrants();
8053            }
8054        }
8055    }
8056
8057    /**
8058     * @param uri This uri must NOT contain an embedded userId.
8059     * @param userId The userId in which the uri is to be resolved.
8060     */
8061    @Override
8062    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8063        enforceNotIsolatedCaller("releasePersistableUriPermission");
8064
8065        Preconditions.checkFlagsArgument(modeFlags,
8066                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8067
8068        synchronized (this) {
8069            final int callingUid = Binder.getCallingUid();
8070            boolean persistChanged = false;
8071
8072            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8073                    new GrantUri(userId, uri, false));
8074            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8075                    new GrantUri(userId, uri, true));
8076            if (exactPerm == null && prefixPerm == null) {
8077                throw new SecurityException("No permission grants found for UID " + callingUid
8078                        + " and Uri " + uri.toSafeString());
8079            }
8080
8081            if (exactPerm != null) {
8082                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8083                removeUriPermissionIfNeededLocked(exactPerm);
8084            }
8085            if (prefixPerm != null) {
8086                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8087                removeUriPermissionIfNeededLocked(prefixPerm);
8088            }
8089
8090            if (persistChanged) {
8091                schedulePersistUriGrants();
8092            }
8093        }
8094    }
8095
8096    /**
8097     * Prune any older {@link UriPermission} for the given UID until outstanding
8098     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8099     *
8100     * @return if any mutations occured that require persisting.
8101     */
8102    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8103        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8104        if (perms == null) return false;
8105        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8106
8107        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8108        for (UriPermission perm : perms.values()) {
8109            if (perm.persistedModeFlags != 0) {
8110                persisted.add(perm);
8111            }
8112        }
8113
8114        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8115        if (trimCount <= 0) return false;
8116
8117        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8118        for (int i = 0; i < trimCount; i++) {
8119            final UriPermission perm = persisted.get(i);
8120
8121            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8122                    "Trimming grant created at " + perm.persistedCreateTime);
8123
8124            perm.releasePersistableModes(~0);
8125            removeUriPermissionIfNeededLocked(perm);
8126        }
8127
8128        return true;
8129    }
8130
8131    @Override
8132    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8133            String packageName, boolean incoming) {
8134        enforceNotIsolatedCaller("getPersistedUriPermissions");
8135        Preconditions.checkNotNull(packageName, "packageName");
8136
8137        final int callingUid = Binder.getCallingUid();
8138        final IPackageManager pm = AppGlobals.getPackageManager();
8139        try {
8140            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8141            if (packageUid != callingUid) {
8142                throw new SecurityException(
8143                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8144            }
8145        } catch (RemoteException e) {
8146            throw new SecurityException("Failed to verify package name ownership");
8147        }
8148
8149        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8150        synchronized (this) {
8151            if (incoming) {
8152                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8153                        callingUid);
8154                if (perms == null) {
8155                    Slog.w(TAG, "No permission grants found for " + packageName);
8156                } else {
8157                    for (UriPermission perm : perms.values()) {
8158                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8159                            result.add(perm.buildPersistedPublicApiObject());
8160                        }
8161                    }
8162                }
8163            } else {
8164                final int size = mGrantedUriPermissions.size();
8165                for (int i = 0; i < size; i++) {
8166                    final ArrayMap<GrantUri, UriPermission> perms =
8167                            mGrantedUriPermissions.valueAt(i);
8168                    for (UriPermission perm : perms.values()) {
8169                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8170                            result.add(perm.buildPersistedPublicApiObject());
8171                        }
8172                    }
8173                }
8174            }
8175        }
8176        return new ParceledListSlice<android.content.UriPermission>(result);
8177    }
8178
8179    @Override
8180    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8181        synchronized (this) {
8182            ProcessRecord app =
8183                who != null ? getRecordForAppLocked(who) : null;
8184            if (app == null) return;
8185
8186            Message msg = Message.obtain();
8187            msg.what = WAIT_FOR_DEBUGGER_MSG;
8188            msg.obj = app;
8189            msg.arg1 = waiting ? 1 : 0;
8190            mUiHandler.sendMessage(msg);
8191        }
8192    }
8193
8194    @Override
8195    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8196        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8197        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8198        outInfo.availMem = Process.getFreeMemory();
8199        outInfo.totalMem = Process.getTotalMemory();
8200        outInfo.threshold = homeAppMem;
8201        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8202        outInfo.hiddenAppThreshold = cachedAppMem;
8203        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8204                ProcessList.SERVICE_ADJ);
8205        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8206                ProcessList.VISIBLE_APP_ADJ);
8207        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8208                ProcessList.FOREGROUND_APP_ADJ);
8209    }
8210
8211    // =========================================================
8212    // TASK MANAGEMENT
8213    // =========================================================
8214
8215    @Override
8216    public List<IAppTask> getAppTasks(String callingPackage) {
8217        int callingUid = Binder.getCallingUid();
8218        long ident = Binder.clearCallingIdentity();
8219
8220        synchronized(this) {
8221            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8222            try {
8223                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8224
8225                final int N = mRecentTasks.size();
8226                for (int i = 0; i < N; i++) {
8227                    TaskRecord tr = mRecentTasks.get(i);
8228                    // Skip tasks that do not match the caller.  We don't need to verify
8229                    // callingPackage, because we are also limiting to callingUid and know
8230                    // that will limit to the correct security sandbox.
8231                    if (tr.effectiveUid != callingUid) {
8232                        continue;
8233                    }
8234                    Intent intent = tr.getBaseIntent();
8235                    if (intent == null ||
8236                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8237                        continue;
8238                    }
8239                    ActivityManager.RecentTaskInfo taskInfo =
8240                            createRecentTaskInfoFromTaskRecord(tr);
8241                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8242                    list.add(taskImpl);
8243                }
8244            } finally {
8245                Binder.restoreCallingIdentity(ident);
8246            }
8247            return list;
8248        }
8249    }
8250
8251    @Override
8252    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8253        final int callingUid = Binder.getCallingUid();
8254        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8255
8256        synchronized(this) {
8257            if (DEBUG_ALL) Slog.v(
8258                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8259
8260            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8261                    callingUid);
8262
8263            // TODO: Improve with MRU list from all ActivityStacks.
8264            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8265        }
8266
8267        return list;
8268    }
8269
8270    /**
8271     * Creates a new RecentTaskInfo from a TaskRecord.
8272     */
8273    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8274        // Update the task description to reflect any changes in the task stack
8275        tr.updateTaskDescription();
8276
8277        // Compose the recent task info
8278        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8279        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8280        rti.persistentId = tr.taskId;
8281        rti.baseIntent = new Intent(tr.getBaseIntent());
8282        rti.origActivity = tr.origActivity;
8283        rti.description = tr.lastDescription;
8284        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8285        rti.userId = tr.userId;
8286        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8287        rti.firstActiveTime = tr.firstActiveTime;
8288        rti.lastActiveTime = tr.lastActiveTime;
8289        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8290        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8291        rti.numActivities = 0;
8292
8293        ActivityRecord base = null;
8294        ActivityRecord top = null;
8295        ActivityRecord tmp;
8296
8297        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8298            tmp = tr.mActivities.get(i);
8299            if (tmp.finishing) {
8300                continue;
8301            }
8302            base = tmp;
8303            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8304                top = base;
8305            }
8306            rti.numActivities++;
8307        }
8308
8309        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8310        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8311
8312        return rti;
8313    }
8314
8315    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8316        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8317                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8318        if (!allowed) {
8319            if (checkPermission(android.Manifest.permission.GET_TASKS,
8320                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8321                // Temporary compatibility: some existing apps on the system image may
8322                // still be requesting the old permission and not switched to the new
8323                // one; if so, we'll still allow them full access.  This means we need
8324                // to see if they are holding the old permission and are a system app.
8325                try {
8326                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8327                        allowed = true;
8328                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8329                                + " is using old GET_TASKS but privileged; allowing");
8330                    }
8331                } catch (RemoteException e) {
8332                }
8333            }
8334        }
8335        if (!allowed) {
8336            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8337                    + " does not hold REAL_GET_TASKS; limiting output");
8338        }
8339        return allowed;
8340    }
8341
8342    @Override
8343    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8344        final int callingUid = Binder.getCallingUid();
8345        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8346                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8347
8348        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8349        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8350        synchronized (this) {
8351            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8352                    callingUid);
8353            final boolean detailed = checkCallingPermission(
8354                    android.Manifest.permission.GET_DETAILED_TASKS)
8355                    == PackageManager.PERMISSION_GRANTED;
8356
8357            final int recentsCount = mRecentTasks.size();
8358            ArrayList<ActivityManager.RecentTaskInfo> res =
8359                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8360
8361            final Set<Integer> includedUsers;
8362            if (includeProfiles) {
8363                includedUsers = getProfileIdsLocked(userId);
8364            } else {
8365                includedUsers = new HashSet<>();
8366            }
8367            includedUsers.add(Integer.valueOf(userId));
8368
8369            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8370                TaskRecord tr = mRecentTasks.get(i);
8371                // Only add calling user or related users recent tasks
8372                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8373                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8374                    continue;
8375                }
8376
8377                // Return the entry if desired by the caller.  We always return
8378                // the first entry, because callers always expect this to be the
8379                // foreground app.  We may filter others if the caller has
8380                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8381                // we should exclude the entry.
8382
8383                if (i == 0
8384                        || withExcluded
8385                        || (tr.intent == null)
8386                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8387                                == 0)) {
8388                    if (!allowed) {
8389                        // If the caller doesn't have the GET_TASKS permission, then only
8390                        // allow them to see a small subset of tasks -- their own and home.
8391                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8392                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8393                            continue;
8394                        }
8395                    }
8396                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8397                        if (tr.stack != null && tr.stack.isHomeStack()) {
8398                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8399                                    "Skipping, home stack task: " + tr);
8400                            continue;
8401                        }
8402                    }
8403                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8404                        // Don't include auto remove tasks that are finished or finishing.
8405                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8406                                "Skipping, auto-remove without activity: " + tr);
8407                        continue;
8408                    }
8409                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8410                            && !tr.isAvailable) {
8411                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8412                                "Skipping, unavail real act: " + tr);
8413                        continue;
8414                    }
8415
8416                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8417                    if (!detailed) {
8418                        rti.baseIntent.replaceExtras((Bundle)null);
8419                    }
8420
8421                    res.add(rti);
8422                    maxNum--;
8423                }
8424            }
8425            return res;
8426        }
8427    }
8428
8429    @Override
8430    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8431        synchronized (this) {
8432            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8433                    "getTaskThumbnail()");
8434            TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id, false);
8435            if (tr != null) {
8436                return tr.getTaskThumbnailLocked();
8437            }
8438        }
8439        return null;
8440    }
8441
8442    @Override
8443    public int addAppTask(IBinder activityToken, Intent intent,
8444            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8445        final int callingUid = Binder.getCallingUid();
8446        final long callingIdent = Binder.clearCallingIdentity();
8447
8448        try {
8449            synchronized (this) {
8450                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8451                if (r == null) {
8452                    throw new IllegalArgumentException("Activity does not exist; token="
8453                            + activityToken);
8454                }
8455                ComponentName comp = intent.getComponent();
8456                if (comp == null) {
8457                    throw new IllegalArgumentException("Intent " + intent
8458                            + " must specify explicit component");
8459                }
8460                if (thumbnail.getWidth() != mThumbnailWidth
8461                        || thumbnail.getHeight() != mThumbnailHeight) {
8462                    throw new IllegalArgumentException("Bad thumbnail size: got "
8463                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8464                            + mThumbnailWidth + "x" + mThumbnailHeight);
8465                }
8466                if (intent.getSelector() != null) {
8467                    intent.setSelector(null);
8468                }
8469                if (intent.getSourceBounds() != null) {
8470                    intent.setSourceBounds(null);
8471                }
8472                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8473                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8474                        // The caller has added this as an auto-remove task...  that makes no
8475                        // sense, so turn off auto-remove.
8476                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8477                    }
8478                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8479                    // Must be a new task.
8480                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8481                }
8482                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8483                    mLastAddedTaskActivity = null;
8484                }
8485                ActivityInfo ainfo = mLastAddedTaskActivity;
8486                if (ainfo == null) {
8487                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8488                            comp, 0, UserHandle.getUserId(callingUid));
8489                    if (ainfo.applicationInfo.uid != callingUid) {
8490                        throw new SecurityException(
8491                                "Can't add task for another application: target uid="
8492                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8493                    }
8494                }
8495
8496                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8497                        intent, description);
8498
8499                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
8500                if (trimIdx >= 0) {
8501                    // If this would have caused a trim, then we'll abort because that
8502                    // means it would be added at the end of the list but then just removed.
8503                    return INVALID_TASK_ID;
8504                }
8505
8506                final int N = mRecentTasks.size();
8507                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8508                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8509                    tr.removedFromRecents();
8510                }
8511
8512                task.inRecents = true;
8513                mRecentTasks.add(task);
8514                r.task.stack.addTask(task, false, false);
8515
8516                task.setLastThumbnail(thumbnail);
8517                task.freeLastThumbnail();
8518
8519                return task.taskId;
8520            }
8521        } finally {
8522            Binder.restoreCallingIdentity(callingIdent);
8523        }
8524    }
8525
8526    @Override
8527    public Point getAppTaskThumbnailSize() {
8528        synchronized (this) {
8529            return new Point(mThumbnailWidth,  mThumbnailHeight);
8530        }
8531    }
8532
8533    @Override
8534    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8535        synchronized (this) {
8536            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8537            if (r != null) {
8538                r.setTaskDescription(td);
8539                r.task.updateTaskDescription();
8540            }
8541        }
8542    }
8543
8544    @Override
8545    public void setTaskResizeable(int taskId, boolean resizeable) {
8546        synchronized (this) {
8547            TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8548            if (task == null) {
8549                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
8550                return;
8551            }
8552            if (task.mResizeable != resizeable) {
8553                task.mResizeable = resizeable;
8554                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8555                mStackSupervisor.resumeTopActivitiesLocked();
8556            }
8557        }
8558    }
8559
8560    @Override
8561    public void resizeTask(int taskId, Rect bounds) {
8562        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8563                "resizeTask()");
8564        long ident = Binder.clearCallingIdentity();
8565        try {
8566            synchronized (this) {
8567                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8568                if (task == null) {
8569                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
8570                    return;
8571                }
8572                mStackSupervisor.resizeTaskLocked(task, bounds);
8573            }
8574        } finally {
8575            Binder.restoreCallingIdentity(ident);
8576        }
8577    }
8578
8579    @Override
8580    public Bitmap getTaskDescriptionIcon(String filename) {
8581        if (!FileUtils.isValidExtFilename(filename)
8582                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8583            throw new IllegalArgumentException("Bad filename: " + filename);
8584        }
8585        return mTaskPersister.getTaskDescriptionIcon(filename);
8586    }
8587
8588    @Override
8589    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8590            throws RemoteException {
8591        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8592                opts.getCustomInPlaceResId() == 0) {
8593            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8594                    "with valid animation");
8595        }
8596        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8597        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8598                opts.getCustomInPlaceResId());
8599        mWindowManager.executeAppTransition();
8600    }
8601
8602    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8603        mRecentTasks.remove(tr);
8604        tr.removedFromRecents();
8605        ComponentName component = tr.getBaseIntent().getComponent();
8606        if (component == null) {
8607            Slog.w(TAG, "No component for base intent of task: " + tr);
8608            return;
8609        }
8610
8611        // Find any running services associated with this app and stop if needed.
8612        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8613
8614        if (!killProcess) {
8615            return;
8616        }
8617
8618        // Determine if the process(es) for this task should be killed.
8619        final String pkg = component.getPackageName();
8620        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
8621        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8622        for (int i = 0; i < pmap.size(); i++) {
8623
8624            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8625            for (int j = 0; j < uids.size(); j++) {
8626                ProcessRecord proc = uids.valueAt(j);
8627                if (proc.userId != tr.userId) {
8628                    // Don't kill process for a different user.
8629                    continue;
8630                }
8631                if (proc == mHomeProcess) {
8632                    // Don't kill the home process along with tasks from the same package.
8633                    continue;
8634                }
8635                if (!proc.pkgList.containsKey(pkg)) {
8636                    // Don't kill process that is not associated with this task.
8637                    continue;
8638                }
8639
8640                for (int k = 0; k < proc.activities.size(); k++) {
8641                    TaskRecord otherTask = proc.activities.get(k).task;
8642                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8643                        // Don't kill process(es) that has an activity in a different task that is
8644                        // also in recents.
8645                        return;
8646                    }
8647                }
8648
8649                if (proc.foregroundServices) {
8650                    // Don't kill process(es) with foreground service.
8651                    return;
8652                }
8653
8654                // Add process to kill list.
8655                procsToKill.add(proc);
8656            }
8657        }
8658
8659        // Kill the running processes.
8660        for (int i = 0; i < procsToKill.size(); i++) {
8661            ProcessRecord pr = procsToKill.get(i);
8662            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
8663                    && pr.curReceiver == null) {
8664                pr.kill("remove task", true);
8665            } else {
8666                // We delay killing processes that are not in the background or running a receiver.
8667                pr.waitingToKill = "remove task";
8668            }
8669        }
8670    }
8671
8672    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8673        // Remove all tasks with activities in the specified package from the list of recent tasks
8674        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8675            TaskRecord tr = mRecentTasks.get(i);
8676            if (tr.userId != userId) continue;
8677
8678            ComponentName cn = tr.intent.getComponent();
8679            if (cn != null && cn.getPackageName().equals(packageName)) {
8680                // If the package name matches, remove the task.
8681                removeTaskByIdLocked(tr.taskId, true);
8682            }
8683        }
8684    }
8685
8686    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
8687            int userId) {
8688
8689        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8690            TaskRecord tr = mRecentTasks.get(i);
8691            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
8692                continue;
8693            }
8694
8695            ComponentName cn = tr.intent.getComponent();
8696            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
8697                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
8698            if (sameComponent) {
8699                removeTaskByIdLocked(tr.taskId, false);
8700            }
8701        }
8702    }
8703
8704    /**
8705     * Removes the task with the specified task id.
8706     *
8707     * @param taskId Identifier of the task to be removed.
8708     * @param killProcess Kill any process associated with the task if possible.
8709     * @return Returns true if the given task was found and removed.
8710     */
8711    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8712        TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8713        if (tr != null) {
8714            tr.removeTaskActivitiesLocked();
8715            cleanUpRemovedTaskLocked(tr, killProcess);
8716            if (tr.isPersistable) {
8717                notifyTaskPersisterLocked(null, true);
8718            }
8719            return true;
8720        }
8721        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8722        return false;
8723    }
8724
8725    @Override
8726    public boolean removeTask(int taskId) {
8727        synchronized (this) {
8728            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8729                    "removeTask()");
8730            long ident = Binder.clearCallingIdentity();
8731            try {
8732                return removeTaskByIdLocked(taskId, true);
8733            } finally {
8734                Binder.restoreCallingIdentity(ident);
8735            }
8736        }
8737    }
8738
8739    /**
8740     * TODO: Add mController hook
8741     */
8742    @Override
8743    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8744        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
8745
8746        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
8747        synchronized(this) {
8748            moveTaskToFrontLocked(taskId, flags, options);
8749        }
8750    }
8751
8752    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8753        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8754                Binder.getCallingUid(), -1, -1, "Task to front")) {
8755            ActivityOptions.abort(options);
8756            return;
8757        }
8758        final long origId = Binder.clearCallingIdentity();
8759        try {
8760            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8761            if (task == null) {
8762                Slog.d(TAG, "Could not find task for id: "+ taskId);
8763                return;
8764            }
8765            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8766                mStackSupervisor.showLockTaskToast();
8767                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8768                return;
8769            }
8770            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8771            if (prev != null && prev.isRecentsActivity()) {
8772                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8773            }
8774            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
8775        } finally {
8776            Binder.restoreCallingIdentity(origId);
8777        }
8778        ActivityOptions.abort(options);
8779    }
8780
8781    /**
8782     * Moves an activity, and all of the other activities within the same task, to the bottom
8783     * of the history stack.  The activity's order within the task is unchanged.
8784     *
8785     * @param token A reference to the activity we wish to move
8786     * @param nonRoot If false then this only works if the activity is the root
8787     *                of a task; if true it will work for any activity in a task.
8788     * @return Returns true if the move completed, false if not.
8789     */
8790    @Override
8791    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8792        enforceNotIsolatedCaller("moveActivityTaskToBack");
8793        synchronized(this) {
8794            final long origId = Binder.clearCallingIdentity();
8795            try {
8796                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8797                final TaskRecord task = mRecentTasks.taskForIdLocked(taskId);
8798                if (task != null) {
8799                    if (mStackSupervisor.isLockedTask(task)) {
8800                        mStackSupervisor.showLockTaskToast();
8801                        return false;
8802                    }
8803                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
8804                }
8805            } finally {
8806                Binder.restoreCallingIdentity(origId);
8807            }
8808        }
8809        return false;
8810    }
8811
8812    @Override
8813    public void moveTaskBackwards(int task) {
8814        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8815                "moveTaskBackwards()");
8816
8817        synchronized(this) {
8818            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8819                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8820                return;
8821            }
8822            final long origId = Binder.clearCallingIdentity();
8823            moveTaskBackwardsLocked(task);
8824            Binder.restoreCallingIdentity(origId);
8825        }
8826    }
8827
8828    private final void moveTaskBackwardsLocked(int task) {
8829        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8830    }
8831
8832    @Override
8833    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
8834            IActivityContainerCallback callback) throws RemoteException {
8835        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8836                "createActivityContainer()");
8837        synchronized (this) {
8838            if (parentActivityToken == null) {
8839                throw new IllegalArgumentException("parent token must not be null");
8840            }
8841            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
8842            if (r == null) {
8843                return null;
8844            }
8845            if (callback == null) {
8846                throw new IllegalArgumentException("callback must not be null");
8847            }
8848            return mStackSupervisor.createVirtualActivityContainer(r, callback);
8849        }
8850    }
8851
8852    @Override
8853    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8854        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8855                "deleteActivityContainer()");
8856        synchronized (this) {
8857            mStackSupervisor.deleteActivityContainer(container);
8858        }
8859    }
8860
8861    @Override
8862    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
8863        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8864                "createStackOnDisplay()");
8865        synchronized (this) {
8866            final int stackId = mStackSupervisor.getNextStackId();
8867            final ActivityStack stack = mStackSupervisor.createStackOnDisplay(stackId, displayId);
8868            if (stack == null) {
8869                return null;
8870            }
8871            return stack.mActivityContainer;
8872        }
8873    }
8874
8875    @Override
8876    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
8877        synchronized (this) {
8878            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8879            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
8880                return stack.mActivityContainer.getDisplayId();
8881            }
8882            return Display.DEFAULT_DISPLAY;
8883        }
8884    }
8885
8886    @Override
8887    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8888        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8889                "moveTaskToStack()");
8890        if (stackId == HOME_STACK_ID) {
8891            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8892                    new RuntimeException("here").fillInStackTrace());
8893        }
8894        synchronized (this) {
8895            long ident = Binder.clearCallingIdentity();
8896            try {
8897                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
8898                        + " to stackId=" + stackId + " toTop=" + toTop);
8899                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop);
8900            } finally {
8901                Binder.restoreCallingIdentity(ident);
8902            }
8903        }
8904    }
8905
8906    @Override
8907    public void resizeStack(int stackId, Rect bounds) {
8908        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8909                "resizeStack()");
8910        long ident = Binder.clearCallingIdentity();
8911        try {
8912            synchronized (this) {
8913                mStackSupervisor.resizeStackLocked(stackId, bounds);
8914            }
8915        } finally {
8916            Binder.restoreCallingIdentity(ident);
8917        }
8918    }
8919
8920    @Override
8921    public List<StackInfo> getAllStackInfos() {
8922        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8923                "getAllStackInfos()");
8924        long ident = Binder.clearCallingIdentity();
8925        try {
8926            synchronized (this) {
8927                return mStackSupervisor.getAllStackInfosLocked();
8928            }
8929        } finally {
8930            Binder.restoreCallingIdentity(ident);
8931        }
8932    }
8933
8934    @Override
8935    public StackInfo getStackInfo(int stackId) {
8936        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8937                "getStackInfo()");
8938        long ident = Binder.clearCallingIdentity();
8939        try {
8940            synchronized (this) {
8941                return mStackSupervisor.getStackInfoLocked(stackId);
8942            }
8943        } finally {
8944            Binder.restoreCallingIdentity(ident);
8945        }
8946    }
8947
8948    @Override
8949    public boolean isInHomeStack(int taskId) {
8950        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8951                "getStackInfo()");
8952        long ident = Binder.clearCallingIdentity();
8953        try {
8954            synchronized (this) {
8955                TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8956                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8957            }
8958        } finally {
8959            Binder.restoreCallingIdentity(ident);
8960        }
8961    }
8962
8963    @Override
8964    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8965        synchronized(this) {
8966            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8967        }
8968    }
8969
8970    @Override
8971    public void updateDeviceOwner(String packageName) {
8972        final int callingUid = Binder.getCallingUid();
8973        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
8974            throw new SecurityException("updateDeviceOwner called from non-system process");
8975        }
8976        synchronized (this) {
8977            mDeviceOwnerName = packageName;
8978        }
8979    }
8980
8981    @Override
8982    public void updateLockTaskPackages(int userId, String[] packages) {
8983        final int callingUid = Binder.getCallingUid();
8984        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
8985            throw new SecurityException("updateLockTaskPackage called from non-system process");
8986        }
8987        synchronized (this) {
8988            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
8989                    Arrays.toString(packages));
8990            mLockTaskPackages.put(userId, packages);
8991            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
8992        }
8993    }
8994
8995
8996    void startLockTaskModeLocked(TaskRecord task) {
8997        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
8998        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
8999            return;
9000        }
9001
9002        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9003        // is initiated by system after the pinning request was shown and locked mode is initiated
9004        // by an authorized app directly
9005        final int callingUid = Binder.getCallingUid();
9006        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9007        long ident = Binder.clearCallingIdentity();
9008        try {
9009            final ActivityStack stack = mStackSupervisor.getFocusedStack();
9010            if (!isSystemInitiated) {
9011                task.mLockTaskUid = callingUid;
9012                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9013                    // startLockTask() called by app and task mode is lockTaskModeDefault.
9014                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9015                    StatusBarManagerInternal statusBarManager =
9016                            LocalServices.getService(StatusBarManagerInternal.class);
9017                    if (statusBarManager != null) {
9018                        statusBarManager.showScreenPinningRequest();
9019                    }
9020                    return;
9021                }
9022
9023                if (stack == null || task != stack.topTask()) {
9024                    throw new IllegalArgumentException("Invalid task, not in foreground");
9025                }
9026            }
9027            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9028                    "Locking fully");
9029            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9030                    ActivityManager.LOCK_TASK_MODE_PINNED :
9031                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9032                    "startLockTask", true);
9033        } finally {
9034            Binder.restoreCallingIdentity(ident);
9035        }
9036    }
9037
9038    @Override
9039    public void startLockTaskMode(int taskId) {
9040        synchronized (this) {
9041            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9042            if (task != null) {
9043                startLockTaskModeLocked(task);
9044            }
9045        }
9046    }
9047
9048    @Override
9049    public void startLockTaskMode(IBinder token) {
9050        synchronized (this) {
9051            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9052            if (r == null) {
9053                return;
9054            }
9055            final TaskRecord task = r.task;
9056            if (task != null) {
9057                startLockTaskModeLocked(task);
9058            }
9059        }
9060    }
9061
9062    @Override
9063    public void startLockTaskModeOnCurrent() throws RemoteException {
9064        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9065                "startLockTaskModeOnCurrent");
9066        long ident = Binder.clearCallingIdentity();
9067        try {
9068            synchronized (this) {
9069                ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9070                if (r != null) {
9071                    startLockTaskModeLocked(r.task);
9072                }
9073            }
9074        } finally {
9075            Binder.restoreCallingIdentity(ident);
9076        }
9077    }
9078
9079    @Override
9080    public void stopLockTaskMode() {
9081        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9082        if (lockTask == null) {
9083            // Our work here is done.
9084            return;
9085        }
9086
9087        final int callingUid = Binder.getCallingUid();
9088        final int lockTaskUid = lockTask.mLockTaskUid;
9089        // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9090        // It is possible lockTaskMode was started by the system process because
9091        // android:lockTaskMode is set to a locking value in the application manifest instead of
9092        // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9093        // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9094        if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9095                callingUid != lockTaskUid
9096                && (lockTaskUid != 0
9097                    || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9098            throw new SecurityException("Invalid uid, expected " + lockTaskUid
9099                    + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9100        }
9101
9102        long ident = Binder.clearCallingIdentity();
9103        try {
9104            Log.d(TAG, "stopLockTaskMode");
9105            // Stop lock task
9106            synchronized (this) {
9107                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9108                        "stopLockTask", true);
9109            }
9110        } finally {
9111            Binder.restoreCallingIdentity(ident);
9112        }
9113    }
9114
9115    @Override
9116    public void stopLockTaskModeOnCurrent() throws RemoteException {
9117        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9118                "stopLockTaskModeOnCurrent");
9119        long ident = Binder.clearCallingIdentity();
9120        try {
9121            stopLockTaskMode();
9122        } finally {
9123            Binder.restoreCallingIdentity(ident);
9124        }
9125    }
9126
9127    @Override
9128    public boolean isInLockTaskMode() {
9129        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9130    }
9131
9132    @Override
9133    public int getLockTaskModeState() {
9134        synchronized (this) {
9135            return mStackSupervisor.getLockTaskModeState();
9136        }
9137    }
9138
9139    @Override
9140    public void showLockTaskEscapeMessage(IBinder token) {
9141        synchronized (this) {
9142            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9143            if (r == null) {
9144                return;
9145            }
9146            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9147        }
9148    }
9149
9150    // =========================================================
9151    // CONTENT PROVIDERS
9152    // =========================================================
9153
9154    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9155        List<ProviderInfo> providers = null;
9156        try {
9157            providers = AppGlobals.getPackageManager().
9158                queryContentProviders(app.processName, app.uid,
9159                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
9160        } catch (RemoteException ex) {
9161        }
9162        if (DEBUG_MU) Slog.v(TAG_MU,
9163                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9164        int userId = app.userId;
9165        if (providers != null) {
9166            int N = providers.size();
9167            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9168            for (int i=0; i<N; i++) {
9169                ProviderInfo cpi =
9170                    (ProviderInfo)providers.get(i);
9171                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9172                        cpi.name, cpi.flags);
9173                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_OWNER) {
9174                    // This is a singleton provider, but a user besides the
9175                    // default user is asking to initialize a process it runs
9176                    // in...  well, no, it doesn't actually run in this process,
9177                    // it runs in the process of the default user.  Get rid of it.
9178                    providers.remove(i);
9179                    N--;
9180                    i--;
9181                    continue;
9182                }
9183
9184                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9185                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9186                if (cpr == null) {
9187                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9188                    mProviderMap.putProviderByClass(comp, cpr);
9189                }
9190                if (DEBUG_MU) Slog.v(TAG_MU,
9191                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9192                app.pubProviders.put(cpi.name, cpr);
9193                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9194                    // Don't add this if it is a platform component that is marked
9195                    // to run in multiple processes, because this is actually
9196                    // part of the framework so doesn't make sense to track as a
9197                    // separate apk in the process.
9198                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9199                            mProcessStats);
9200                }
9201                ensurePackageDexOpt(cpi.applicationInfo.packageName);
9202            }
9203        }
9204        return providers;
9205    }
9206
9207    /**
9208     * Check if {@link ProcessRecord} has a possible chance at accessing the
9209     * given {@link ProviderInfo}. Final permission checking is always done
9210     * in {@link ContentProvider}.
9211     */
9212    private final String checkContentProviderPermissionLocked(
9213            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9214        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9215        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9216        boolean checkedGrants = false;
9217        if (checkUser) {
9218            // Looking for cross-user grants before enforcing the typical cross-users permissions
9219            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
9220            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9221                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9222                    return null;
9223                }
9224                checkedGrants = true;
9225            }
9226            userId = handleIncomingUser(callingPid, callingUid, userId,
9227                    false, ALLOW_NON_FULL,
9228                    "checkContentProviderPermissionLocked " + cpi.authority, null);
9229            if (userId != tmpTargetUserId) {
9230                // When we actually went to determine the final targer user ID, this ended
9231                // up different than our initial check for the authority.  This is because
9232                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9233                // SELF.  So we need to re-check the grants again.
9234                checkedGrants = false;
9235            }
9236        }
9237        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9238                cpi.applicationInfo.uid, cpi.exported)
9239                == PackageManager.PERMISSION_GRANTED) {
9240            return null;
9241        }
9242        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9243                cpi.applicationInfo.uid, cpi.exported)
9244                == PackageManager.PERMISSION_GRANTED) {
9245            return null;
9246        }
9247
9248        PathPermission[] pps = cpi.pathPermissions;
9249        if (pps != null) {
9250            int i = pps.length;
9251            while (i > 0) {
9252                i--;
9253                PathPermission pp = pps[i];
9254                String pprperm = pp.getReadPermission();
9255                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9256                        cpi.applicationInfo.uid, cpi.exported)
9257                        == PackageManager.PERMISSION_GRANTED) {
9258                    return null;
9259                }
9260                String ppwperm = pp.getWritePermission();
9261                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9262                        cpi.applicationInfo.uid, cpi.exported)
9263                        == PackageManager.PERMISSION_GRANTED) {
9264                    return null;
9265                }
9266            }
9267        }
9268        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9269            return null;
9270        }
9271
9272        String msg;
9273        if (!cpi.exported) {
9274            msg = "Permission Denial: opening provider " + cpi.name
9275                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9276                    + ", uid=" + callingUid + ") that is not exported from uid "
9277                    + cpi.applicationInfo.uid;
9278        } else {
9279            msg = "Permission Denial: opening provider " + cpi.name
9280                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9281                    + ", uid=" + callingUid + ") requires "
9282                    + cpi.readPermission + " or " + cpi.writePermission;
9283        }
9284        Slog.w(TAG, msg);
9285        return msg;
9286    }
9287
9288    /**
9289     * Returns if the ContentProvider has granted a uri to callingUid
9290     */
9291    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9292        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9293        if (perms != null) {
9294            for (int i=perms.size()-1; i>=0; i--) {
9295                GrantUri grantUri = perms.keyAt(i);
9296                if (grantUri.sourceUserId == userId || !checkUser) {
9297                    if (matchesProvider(grantUri.uri, cpi)) {
9298                        return true;
9299                    }
9300                }
9301            }
9302        }
9303        return false;
9304    }
9305
9306    /**
9307     * Returns true if the uri authority is one of the authorities specified in the provider.
9308     */
9309    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9310        String uriAuth = uri.getAuthority();
9311        String cpiAuth = cpi.authority;
9312        if (cpiAuth.indexOf(';') == -1) {
9313            return cpiAuth.equals(uriAuth);
9314        }
9315        String[] cpiAuths = cpiAuth.split(";");
9316        int length = cpiAuths.length;
9317        for (int i = 0; i < length; i++) {
9318            if (cpiAuths[i].equals(uriAuth)) return true;
9319        }
9320        return false;
9321    }
9322
9323    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9324            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9325        if (r != null) {
9326            for (int i=0; i<r.conProviders.size(); i++) {
9327                ContentProviderConnection conn = r.conProviders.get(i);
9328                if (conn.provider == cpr) {
9329                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9330                            "Adding provider requested by "
9331                            + r.processName + " from process "
9332                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9333                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9334                    if (stable) {
9335                        conn.stableCount++;
9336                        conn.numStableIncs++;
9337                    } else {
9338                        conn.unstableCount++;
9339                        conn.numUnstableIncs++;
9340                    }
9341                    return conn;
9342                }
9343            }
9344            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9345            if (stable) {
9346                conn.stableCount = 1;
9347                conn.numStableIncs = 1;
9348            } else {
9349                conn.unstableCount = 1;
9350                conn.numUnstableIncs = 1;
9351            }
9352            cpr.connections.add(conn);
9353            r.conProviders.add(conn);
9354            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9355            return conn;
9356        }
9357        cpr.addExternalProcessHandleLocked(externalProcessToken);
9358        return null;
9359    }
9360
9361    boolean decProviderCountLocked(ContentProviderConnection conn,
9362            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9363        if (conn != null) {
9364            cpr = conn.provider;
9365            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9366                    "Removing provider requested by "
9367                    + conn.client.processName + " from process "
9368                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9369                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9370            if (stable) {
9371                conn.stableCount--;
9372            } else {
9373                conn.unstableCount--;
9374            }
9375            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9376                cpr.connections.remove(conn);
9377                conn.client.conProviders.remove(conn);
9378                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9379                return true;
9380            }
9381            return false;
9382        }
9383        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9384        return false;
9385    }
9386
9387    private void checkTime(long startTime, String where) {
9388        long now = SystemClock.elapsedRealtime();
9389        if ((now-startTime) > 1000) {
9390            // If we are taking more than a second, log about it.
9391            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9392        }
9393    }
9394
9395    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9396            String name, IBinder token, boolean stable, int userId) {
9397        ContentProviderRecord cpr;
9398        ContentProviderConnection conn = null;
9399        ProviderInfo cpi = null;
9400
9401        synchronized(this) {
9402            long startTime = SystemClock.elapsedRealtime();
9403
9404            ProcessRecord r = null;
9405            if (caller != null) {
9406                r = getRecordForAppLocked(caller);
9407                if (r == null) {
9408                    throw new SecurityException(
9409                            "Unable to find app for caller " + caller
9410                          + " (pid=" + Binder.getCallingPid()
9411                          + ") when getting content provider " + name);
9412                }
9413            }
9414
9415            boolean checkCrossUser = true;
9416
9417            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9418
9419            // First check if this content provider has been published...
9420            cpr = mProviderMap.getProviderByName(name, userId);
9421            // If that didn't work, check if it exists for user 0 and then
9422            // verify that it's a singleton provider before using it.
9423            if (cpr == null && userId != UserHandle.USER_OWNER) {
9424                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9425                if (cpr != null) {
9426                    cpi = cpr.info;
9427                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9428                            cpi.name, cpi.flags)
9429                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9430                        userId = UserHandle.USER_OWNER;
9431                        checkCrossUser = false;
9432                    } else {
9433                        cpr = null;
9434                        cpi = null;
9435                    }
9436                }
9437            }
9438
9439            boolean providerRunning = cpr != null;
9440            if (providerRunning) {
9441                cpi = cpr.info;
9442                String msg;
9443                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9444                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9445                        != null) {
9446                    throw new SecurityException(msg);
9447                }
9448                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9449
9450                if (r != null && cpr.canRunHere(r)) {
9451                    // This provider has been published or is in the process
9452                    // of being published...  but it is also allowed to run
9453                    // in the caller's process, so don't make a connection
9454                    // and just let the caller instantiate its own instance.
9455                    ContentProviderHolder holder = cpr.newHolder(null);
9456                    // don't give caller the provider object, it needs
9457                    // to make its own.
9458                    holder.provider = null;
9459                    return holder;
9460                }
9461
9462                final long origId = Binder.clearCallingIdentity();
9463
9464                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9465
9466                // In this case the provider instance already exists, so we can
9467                // return it right away.
9468                conn = incProviderCountLocked(r, cpr, token, stable);
9469                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9470                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9471                        // If this is a perceptible app accessing the provider,
9472                        // make sure to count it as being accessed and thus
9473                        // back up on the LRU list.  This is good because
9474                        // content providers are often expensive to start.
9475                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9476                        updateLruProcessLocked(cpr.proc, false, null);
9477                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9478                    }
9479                }
9480
9481                if (cpr.proc != null) {
9482                    if (false) {
9483                        if (cpr.name.flattenToShortString().equals(
9484                                "com.android.providers.calendar/.CalendarProvider2")) {
9485                            Slog.v(TAG, "****************** KILLING "
9486                                + cpr.name.flattenToShortString());
9487                            Process.killProcess(cpr.proc.pid);
9488                        }
9489                    }
9490                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9491                    boolean success = updateOomAdjLocked(cpr.proc);
9492                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
9493                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9494                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
9495                    // NOTE: there is still a race here where a signal could be
9496                    // pending on the process even though we managed to update its
9497                    // adj level.  Not sure what to do about this, but at least
9498                    // the race is now smaller.
9499                    if (!success) {
9500                        // Uh oh...  it looks like the provider's process
9501                        // has been killed on us.  We need to wait for a new
9502                        // process to be started, and make sure its death
9503                        // doesn't kill our process.
9504                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
9505                                + " is crashing; detaching " + r);
9506                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9507                        checkTime(startTime, "getContentProviderImpl: before appDied");
9508                        appDiedLocked(cpr.proc);
9509                        checkTime(startTime, "getContentProviderImpl: after appDied");
9510                        if (!lastRef) {
9511                            // This wasn't the last ref our process had on
9512                            // the provider...  we have now been killed, bail.
9513                            return null;
9514                        }
9515                        providerRunning = false;
9516                        conn = null;
9517                    }
9518                }
9519
9520                Binder.restoreCallingIdentity(origId);
9521            }
9522
9523            boolean singleton;
9524            if (!providerRunning) {
9525                try {
9526                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9527                    cpi = AppGlobals.getPackageManager().
9528                        resolveContentProvider(name,
9529                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9530                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9531                } catch (RemoteException ex) {
9532                }
9533                if (cpi == null) {
9534                    return null;
9535                }
9536                // If the provider is a singleton AND
9537                // (it's a call within the same user || the provider is a
9538                // privileged app)
9539                // Then allow connecting to the singleton provider
9540                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9541                        cpi.name, cpi.flags)
9542                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9543                if (singleton) {
9544                    userId = UserHandle.USER_OWNER;
9545                }
9546                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9547                checkTime(startTime, "getContentProviderImpl: got app info for user");
9548
9549                String msg;
9550                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9551                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9552                        != null) {
9553                    throw new SecurityException(msg);
9554                }
9555                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9556
9557                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9558                        && !cpi.processName.equals("system")) {
9559                    // If this content provider does not run in the system
9560                    // process, and the system is not yet ready to run other
9561                    // processes, then fail fast instead of hanging.
9562                    throw new IllegalArgumentException(
9563                            "Attempt to launch content provider before system ready");
9564                }
9565
9566                // Make sure that the user who owns this provider is running.  If not,
9567                // we don't want to allow it to run.
9568                if (!isUserRunningLocked(userId, false)) {
9569                    Slog.w(TAG, "Unable to launch app "
9570                            + cpi.applicationInfo.packageName + "/"
9571                            + cpi.applicationInfo.uid + " for provider "
9572                            + name + ": user " + userId + " is stopped");
9573                    return null;
9574                }
9575
9576                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9577                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9578                cpr = mProviderMap.getProviderByClass(comp, userId);
9579                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9580                final boolean firstClass = cpr == null;
9581                if (firstClass) {
9582                    final long ident = Binder.clearCallingIdentity();
9583                    try {
9584                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9585                        ApplicationInfo ai =
9586                            AppGlobals.getPackageManager().
9587                                getApplicationInfo(
9588                                        cpi.applicationInfo.packageName,
9589                                        STOCK_PM_FLAGS, userId);
9590                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9591                        if (ai == null) {
9592                            Slog.w(TAG, "No package info for content provider "
9593                                    + cpi.name);
9594                            return null;
9595                        }
9596                        ai = getAppInfoForUser(ai, userId);
9597                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9598                    } catch (RemoteException ex) {
9599                        // pm is in same process, this will never happen.
9600                    } finally {
9601                        Binder.restoreCallingIdentity(ident);
9602                    }
9603                }
9604
9605                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9606
9607                if (r != null && cpr.canRunHere(r)) {
9608                    // If this is a multiprocess provider, then just return its
9609                    // info and allow the caller to instantiate it.  Only do
9610                    // this if the provider is the same user as the caller's
9611                    // process, or can run as root (so can be in any process).
9612                    return cpr.newHolder(null);
9613                }
9614
9615                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
9616                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
9617                            + cpr.info.name + " callers=" + Debug.getCallers(6));
9618
9619                // This is single process, and our app is now connecting to it.
9620                // See if we are already in the process of launching this
9621                // provider.
9622                final int N = mLaunchingProviders.size();
9623                int i;
9624                for (i = 0; i < N; i++) {
9625                    if (mLaunchingProviders.get(i) == cpr) {
9626                        break;
9627                    }
9628                }
9629
9630                // If the provider is not already being launched, then get it
9631                // started.
9632                if (i >= N) {
9633                    final long origId = Binder.clearCallingIdentity();
9634
9635                    try {
9636                        // Content provider is now in use, its package can't be stopped.
9637                        try {
9638                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9639                            AppGlobals.getPackageManager().setPackageStoppedState(
9640                                    cpr.appInfo.packageName, false, userId);
9641                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9642                        } catch (RemoteException e) {
9643                        } catch (IllegalArgumentException e) {
9644                            Slog.w(TAG, "Failed trying to unstop package "
9645                                    + cpr.appInfo.packageName + ": " + e);
9646                        }
9647
9648                        // Use existing process if already started
9649                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9650                        ProcessRecord proc = getProcessRecordLocked(
9651                                cpi.processName, cpr.appInfo.uid, false);
9652                        if (proc != null && proc.thread != null) {
9653                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
9654                                    "Installing in existing process " + proc);
9655                            if (!proc.pubProviders.containsKey(cpi.name)) {
9656                                checkTime(startTime, "getContentProviderImpl: scheduling install");
9657                                proc.pubProviders.put(cpi.name, cpr);
9658                                try {
9659                                    proc.thread.scheduleInstallProvider(cpi);
9660                                } catch (RemoteException e) {
9661                                }
9662                            }
9663                        } else {
9664                            checkTime(startTime, "getContentProviderImpl: before start process");
9665                            proc = startProcessLocked(cpi.processName,
9666                                    cpr.appInfo, false, 0, "content provider",
9667                                    new ComponentName(cpi.applicationInfo.packageName,
9668                                            cpi.name), false, false, false);
9669                            checkTime(startTime, "getContentProviderImpl: after start process");
9670                            if (proc == null) {
9671                                Slog.w(TAG, "Unable to launch app "
9672                                        + cpi.applicationInfo.packageName + "/"
9673                                        + cpi.applicationInfo.uid + " for provider "
9674                                        + name + ": process is bad");
9675                                return null;
9676                            }
9677                        }
9678                        cpr.launchingApp = proc;
9679                        mLaunchingProviders.add(cpr);
9680                    } finally {
9681                        Binder.restoreCallingIdentity(origId);
9682                    }
9683                }
9684
9685                checkTime(startTime, "getContentProviderImpl: updating data structures");
9686
9687                // Make sure the provider is published (the same provider class
9688                // may be published under multiple names).
9689                if (firstClass) {
9690                    mProviderMap.putProviderByClass(comp, cpr);
9691                }
9692
9693                mProviderMap.putProviderByName(name, cpr);
9694                conn = incProviderCountLocked(r, cpr, token, stable);
9695                if (conn != null) {
9696                    conn.waiting = true;
9697                }
9698            }
9699            checkTime(startTime, "getContentProviderImpl: done!");
9700        }
9701
9702        // Wait for the provider to be published...
9703        synchronized (cpr) {
9704            while (cpr.provider == null) {
9705                if (cpr.launchingApp == null) {
9706                    Slog.w(TAG, "Unable to launch app "
9707                            + cpi.applicationInfo.packageName + "/"
9708                            + cpi.applicationInfo.uid + " for provider "
9709                            + name + ": launching app became null");
9710                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9711                            UserHandle.getUserId(cpi.applicationInfo.uid),
9712                            cpi.applicationInfo.packageName,
9713                            cpi.applicationInfo.uid, name);
9714                    return null;
9715                }
9716                try {
9717                    if (DEBUG_MU) Slog.v(TAG_MU,
9718                            "Waiting to start provider " + cpr
9719                            + " launchingApp=" + cpr.launchingApp);
9720                    if (conn != null) {
9721                        conn.waiting = true;
9722                    }
9723                    cpr.wait();
9724                } catch (InterruptedException ex) {
9725                } finally {
9726                    if (conn != null) {
9727                        conn.waiting = false;
9728                    }
9729                }
9730            }
9731        }
9732        return cpr != null ? cpr.newHolder(conn) : null;
9733    }
9734
9735    @Override
9736    public final ContentProviderHolder getContentProvider(
9737            IApplicationThread caller, String name, int userId, boolean stable) {
9738        enforceNotIsolatedCaller("getContentProvider");
9739        if (caller == null) {
9740            String msg = "null IApplicationThread when getting content provider "
9741                    + name;
9742            Slog.w(TAG, msg);
9743            throw new SecurityException(msg);
9744        }
9745        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9746        // with cross-user grant.
9747        return getContentProviderImpl(caller, name, null, stable, userId);
9748    }
9749
9750    public ContentProviderHolder getContentProviderExternal(
9751            String name, int userId, IBinder token) {
9752        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9753            "Do not have permission in call getContentProviderExternal()");
9754        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9755                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9756        return getContentProviderExternalUnchecked(name, token, userId);
9757    }
9758
9759    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9760            IBinder token, int userId) {
9761        return getContentProviderImpl(null, name, token, true, userId);
9762    }
9763
9764    /**
9765     * Drop a content provider from a ProcessRecord's bookkeeping
9766     */
9767    public void removeContentProvider(IBinder connection, boolean stable) {
9768        enforceNotIsolatedCaller("removeContentProvider");
9769        long ident = Binder.clearCallingIdentity();
9770        try {
9771            synchronized (this) {
9772                ContentProviderConnection conn;
9773                try {
9774                    conn = (ContentProviderConnection)connection;
9775                } catch (ClassCastException e) {
9776                    String msg ="removeContentProvider: " + connection
9777                            + " not a ContentProviderConnection";
9778                    Slog.w(TAG, msg);
9779                    throw new IllegalArgumentException(msg);
9780                }
9781                if (conn == null) {
9782                    throw new NullPointerException("connection is null");
9783                }
9784                if (decProviderCountLocked(conn, null, null, stable)) {
9785                    updateOomAdjLocked();
9786                }
9787            }
9788        } finally {
9789            Binder.restoreCallingIdentity(ident);
9790        }
9791    }
9792
9793    public void removeContentProviderExternal(String name, IBinder token) {
9794        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9795            "Do not have permission in call removeContentProviderExternal()");
9796        int userId = UserHandle.getCallingUserId();
9797        long ident = Binder.clearCallingIdentity();
9798        try {
9799            removeContentProviderExternalUnchecked(name, token, userId);
9800        } finally {
9801            Binder.restoreCallingIdentity(ident);
9802        }
9803    }
9804
9805    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9806        synchronized (this) {
9807            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9808            if(cpr == null) {
9809                //remove from mProvidersByClass
9810                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
9811                return;
9812            }
9813
9814            //update content provider record entry info
9815            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9816            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9817            if (localCpr.hasExternalProcessHandles()) {
9818                if (localCpr.removeExternalProcessHandleLocked(token)) {
9819                    updateOomAdjLocked();
9820                } else {
9821                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9822                            + " with no external reference for token: "
9823                            + token + ".");
9824                }
9825            } else {
9826                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9827                        + " with no external references.");
9828            }
9829        }
9830    }
9831
9832    public final void publishContentProviders(IApplicationThread caller,
9833            List<ContentProviderHolder> providers) {
9834        if (providers == null) {
9835            return;
9836        }
9837
9838        enforceNotIsolatedCaller("publishContentProviders");
9839        synchronized (this) {
9840            final ProcessRecord r = getRecordForAppLocked(caller);
9841            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9842            if (r == null) {
9843                throw new SecurityException(
9844                        "Unable to find app for caller " + caller
9845                      + " (pid=" + Binder.getCallingPid()
9846                      + ") when publishing content providers");
9847            }
9848
9849            final long origId = Binder.clearCallingIdentity();
9850
9851            final int N = providers.size();
9852            for (int i=0; i<N; i++) {
9853                ContentProviderHolder src = providers.get(i);
9854                if (src == null || src.info == null || src.provider == null) {
9855                    continue;
9856                }
9857                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9858                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9859                if (dst != null) {
9860                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9861                    mProviderMap.putProviderByClass(comp, dst);
9862                    String names[] = dst.info.authority.split(";");
9863                    for (int j = 0; j < names.length; j++) {
9864                        mProviderMap.putProviderByName(names[j], dst);
9865                    }
9866
9867                    int NL = mLaunchingProviders.size();
9868                    int j;
9869                    for (j=0; j<NL; j++) {
9870                        if (mLaunchingProviders.get(j) == dst) {
9871                            mLaunchingProviders.remove(j);
9872                            j--;
9873                            NL--;
9874                        }
9875                    }
9876                    synchronized (dst) {
9877                        dst.provider = src.provider;
9878                        dst.proc = r;
9879                        dst.notifyAll();
9880                    }
9881                    updateOomAdjLocked(r);
9882                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
9883                            src.info.authority);
9884                }
9885            }
9886
9887            Binder.restoreCallingIdentity(origId);
9888        }
9889    }
9890
9891    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9892        ContentProviderConnection conn;
9893        try {
9894            conn = (ContentProviderConnection)connection;
9895        } catch (ClassCastException e) {
9896            String msg ="refContentProvider: " + connection
9897                    + " not a ContentProviderConnection";
9898            Slog.w(TAG, msg);
9899            throw new IllegalArgumentException(msg);
9900        }
9901        if (conn == null) {
9902            throw new NullPointerException("connection is null");
9903        }
9904
9905        synchronized (this) {
9906            if (stable > 0) {
9907                conn.numStableIncs += stable;
9908            }
9909            stable = conn.stableCount + stable;
9910            if (stable < 0) {
9911                throw new IllegalStateException("stableCount < 0: " + stable);
9912            }
9913
9914            if (unstable > 0) {
9915                conn.numUnstableIncs += unstable;
9916            }
9917            unstable = conn.unstableCount + unstable;
9918            if (unstable < 0) {
9919                throw new IllegalStateException("unstableCount < 0: " + unstable);
9920            }
9921
9922            if ((stable+unstable) <= 0) {
9923                throw new IllegalStateException("ref counts can't go to zero here: stable="
9924                        + stable + " unstable=" + unstable);
9925            }
9926            conn.stableCount = stable;
9927            conn.unstableCount = unstable;
9928            return !conn.dead;
9929        }
9930    }
9931
9932    public void unstableProviderDied(IBinder connection) {
9933        ContentProviderConnection conn;
9934        try {
9935            conn = (ContentProviderConnection)connection;
9936        } catch (ClassCastException e) {
9937            String msg ="refContentProvider: " + connection
9938                    + " not a ContentProviderConnection";
9939            Slog.w(TAG, msg);
9940            throw new IllegalArgumentException(msg);
9941        }
9942        if (conn == null) {
9943            throw new NullPointerException("connection is null");
9944        }
9945
9946        // Safely retrieve the content provider associated with the connection.
9947        IContentProvider provider;
9948        synchronized (this) {
9949            provider = conn.provider.provider;
9950        }
9951
9952        if (provider == null) {
9953            // Um, yeah, we're way ahead of you.
9954            return;
9955        }
9956
9957        // Make sure the caller is being honest with us.
9958        if (provider.asBinder().pingBinder()) {
9959            // Er, no, still looks good to us.
9960            synchronized (this) {
9961                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9962                        + " says " + conn + " died, but we don't agree");
9963                return;
9964            }
9965        }
9966
9967        // Well look at that!  It's dead!
9968        synchronized (this) {
9969            if (conn.provider.provider != provider) {
9970                // But something changed...  good enough.
9971                return;
9972            }
9973
9974            ProcessRecord proc = conn.provider.proc;
9975            if (proc == null || proc.thread == null) {
9976                // Seems like the process is already cleaned up.
9977                return;
9978            }
9979
9980            // As far as we're concerned, this is just like receiving a
9981            // death notification...  just a bit prematurely.
9982            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9983                    + ") early provider death");
9984            final long ident = Binder.clearCallingIdentity();
9985            try {
9986                appDiedLocked(proc);
9987            } finally {
9988                Binder.restoreCallingIdentity(ident);
9989            }
9990        }
9991    }
9992
9993    @Override
9994    public void appNotRespondingViaProvider(IBinder connection) {
9995        enforceCallingPermission(
9996                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9997
9998        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9999        if (conn == null) {
10000            Slog.w(TAG, "ContentProviderConnection is null");
10001            return;
10002        }
10003
10004        final ProcessRecord host = conn.provider.proc;
10005        if (host == null) {
10006            Slog.w(TAG, "Failed to find hosting ProcessRecord");
10007            return;
10008        }
10009
10010        final long token = Binder.clearCallingIdentity();
10011        try {
10012            appNotResponding(host, null, null, false, "ContentProvider not responding");
10013        } finally {
10014            Binder.restoreCallingIdentity(token);
10015        }
10016    }
10017
10018    public final void installSystemProviders() {
10019        List<ProviderInfo> providers;
10020        synchronized (this) {
10021            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10022            providers = generateApplicationProvidersLocked(app);
10023            if (providers != null) {
10024                for (int i=providers.size()-1; i>=0; i--) {
10025                    ProviderInfo pi = (ProviderInfo)providers.get(i);
10026                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10027                        Slog.w(TAG, "Not installing system proc provider " + pi.name
10028                                + ": not system .apk");
10029                        providers.remove(i);
10030                    }
10031                }
10032            }
10033        }
10034        if (providers != null) {
10035            mSystemThread.installSystemProviders(providers);
10036        }
10037
10038        mCoreSettingsObserver = new CoreSettingsObserver(this);
10039
10040        //mUsageStatsService.monitorPackages();
10041    }
10042
10043    /**
10044     * Allows apps to retrieve the MIME type of a URI.
10045     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
10046     * users, then it does not need permission to access the ContentProvider.
10047     * Either, it needs cross-user uri grants.
10048     *
10049     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
10050     *
10051     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
10052     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
10053     */
10054    public String getProviderMimeType(Uri uri, int userId) {
10055        enforceNotIsolatedCaller("getProviderMimeType");
10056        final String name = uri.getAuthority();
10057        int callingUid = Binder.getCallingUid();
10058        int callingPid = Binder.getCallingPid();
10059        long ident = 0;
10060        boolean clearedIdentity = false;
10061        userId = unsafeConvertIncomingUser(userId);
10062        if (canClearIdentity(callingPid, callingUid, userId)) {
10063            clearedIdentity = true;
10064            ident = Binder.clearCallingIdentity();
10065        }
10066        ContentProviderHolder holder = null;
10067        try {
10068            holder = getContentProviderExternalUnchecked(name, null, userId);
10069            if (holder != null) {
10070                return holder.provider.getType(uri);
10071            }
10072        } catch (RemoteException e) {
10073            Log.w(TAG, "Content provider dead retrieving " + uri, e);
10074            return null;
10075        } finally {
10076            // We need to clear the identity to call removeContentProviderExternalUnchecked
10077            if (!clearedIdentity) {
10078                ident = Binder.clearCallingIdentity();
10079            }
10080            try {
10081                if (holder != null) {
10082                    removeContentProviderExternalUnchecked(name, null, userId);
10083                }
10084            } finally {
10085                Binder.restoreCallingIdentity(ident);
10086            }
10087        }
10088
10089        return null;
10090    }
10091
10092    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
10093        if (UserHandle.getUserId(callingUid) == userId) {
10094            return true;
10095        }
10096        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
10097                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
10098                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
10099                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
10100                return true;
10101        }
10102        return false;
10103    }
10104
10105    // =========================================================
10106    // GLOBAL MANAGEMENT
10107    // =========================================================
10108
10109    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
10110            boolean isolated, int isolatedUid) {
10111        String proc = customProcess != null ? customProcess : info.processName;
10112        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10113        final int userId = UserHandle.getUserId(info.uid);
10114        int uid = info.uid;
10115        if (isolated) {
10116            if (isolatedUid == 0) {
10117                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
10118                while (true) {
10119                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
10120                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
10121                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
10122                    }
10123                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
10124                    mNextIsolatedProcessUid++;
10125                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
10126                        // No process for this uid, use it.
10127                        break;
10128                    }
10129                    stepsLeft--;
10130                    if (stepsLeft <= 0) {
10131                        return null;
10132                    }
10133                }
10134            } else {
10135                // Special case for startIsolatedProcess (internal only), where
10136                // the uid of the isolated process is specified by the caller.
10137                uid = isolatedUid;
10138            }
10139        }
10140        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
10141        if (!mBooted && !mBooting
10142                && userId == UserHandle.USER_OWNER
10143                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10144            r.persistent = true;
10145        }
10146        addProcessNameLocked(r);
10147        return r;
10148    }
10149
10150    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
10151            String abiOverride) {
10152        ProcessRecord app;
10153        if (!isolated) {
10154            app = getProcessRecordLocked(info.processName, info.uid, true);
10155        } else {
10156            app = null;
10157        }
10158
10159        if (app == null) {
10160            app = newProcessRecordLocked(info, null, isolated, 0);
10161            updateLruProcessLocked(app, false, null);
10162            updateOomAdjLocked();
10163        }
10164
10165        // This package really, really can not be stopped.
10166        try {
10167            AppGlobals.getPackageManager().setPackageStoppedState(
10168                    info.packageName, false, UserHandle.getUserId(app.uid));
10169        } catch (RemoteException e) {
10170        } catch (IllegalArgumentException e) {
10171            Slog.w(TAG, "Failed trying to unstop package "
10172                    + info.packageName + ": " + e);
10173        }
10174
10175        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10176            app.persistent = true;
10177            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10178        }
10179        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10180            mPersistentStartingProcesses.add(app);
10181            startProcessLocked(app, "added application", app.processName, abiOverride,
10182                    null /* entryPoint */, null /* entryPointArgs */);
10183        }
10184
10185        return app;
10186    }
10187
10188    public void unhandledBack() {
10189        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10190                "unhandledBack()");
10191
10192        synchronized(this) {
10193            final long origId = Binder.clearCallingIdentity();
10194            try {
10195                getFocusedStack().unhandledBackLocked();
10196            } finally {
10197                Binder.restoreCallingIdentity(origId);
10198            }
10199        }
10200    }
10201
10202    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10203        enforceNotIsolatedCaller("openContentUri");
10204        final int userId = UserHandle.getCallingUserId();
10205        String name = uri.getAuthority();
10206        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10207        ParcelFileDescriptor pfd = null;
10208        if (cph != null) {
10209            // We record the binder invoker's uid in thread-local storage before
10210            // going to the content provider to open the file.  Later, in the code
10211            // that handles all permissions checks, we look for this uid and use
10212            // that rather than the Activity Manager's own uid.  The effect is that
10213            // we do the check against the caller's permissions even though it looks
10214            // to the content provider like the Activity Manager itself is making
10215            // the request.
10216            Binder token = new Binder();
10217            sCallerIdentity.set(new Identity(
10218                    token, Binder.getCallingPid(), Binder.getCallingUid()));
10219            try {
10220                pfd = cph.provider.openFile(null, uri, "r", null, token);
10221            } catch (FileNotFoundException e) {
10222                // do nothing; pfd will be returned null
10223            } finally {
10224                // Ensure that whatever happens, we clean up the identity state
10225                sCallerIdentity.remove();
10226                // Ensure we're done with the provider.
10227                removeContentProviderExternalUnchecked(name, null, userId);
10228            }
10229        } else {
10230            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10231        }
10232        return pfd;
10233    }
10234
10235    // Actually is sleeping or shutting down or whatever else in the future
10236    // is an inactive state.
10237    public boolean isSleepingOrShuttingDown() {
10238        return isSleeping() || mShuttingDown;
10239    }
10240
10241    public boolean isSleeping() {
10242        return mSleeping;
10243    }
10244
10245    void onWakefulnessChanged(int wakefulness) {
10246        synchronized(this) {
10247            mWakefulness = wakefulness;
10248            updateSleepIfNeededLocked();
10249        }
10250    }
10251
10252    void finishRunningVoiceLocked() {
10253        if (mRunningVoice != null) {
10254            mRunningVoice = null;
10255            mVoiceWakeLock.release();
10256            updateSleepIfNeededLocked();
10257        }
10258    }
10259
10260    void startTimeTrackingFocusedActivityLocked() {
10261        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
10262            mCurAppTimeTracker.start(mFocusedActivity.packageName);
10263        }
10264    }
10265
10266    void updateSleepIfNeededLocked() {
10267        if (mSleeping && !shouldSleepLocked()) {
10268            mSleeping = false;
10269            startTimeTrackingFocusedActivityLocked();
10270            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
10271            mStackSupervisor.comeOutOfSleepIfNeededLocked();
10272            updateOomAdjLocked();
10273        } else if (!mSleeping && shouldSleepLocked()) {
10274            mSleeping = true;
10275            if (mCurAppTimeTracker != null) {
10276                mCurAppTimeTracker.stop();
10277            }
10278            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
10279            mStackSupervisor.goingToSleepLocked();
10280            updateOomAdjLocked();
10281
10282            // Initialize the wake times of all processes.
10283            checkExcessivePowerUsageLocked(false);
10284            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10285            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10286            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10287        }
10288    }
10289
10290    private boolean shouldSleepLocked() {
10291        // Resume applications while running a voice interactor.
10292        if (mRunningVoice != null) {
10293            return false;
10294        }
10295
10296        // TODO: Transform the lock screen state into a sleep token instead.
10297        switch (mWakefulness) {
10298            case PowerManagerInternal.WAKEFULNESS_AWAKE:
10299            case PowerManagerInternal.WAKEFULNESS_DREAMING:
10300            case PowerManagerInternal.WAKEFULNESS_DOZING:
10301                // Pause applications whenever the lock screen is shown or any sleep
10302                // tokens have been acquired.
10303                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
10304            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10305            default:
10306                // If we're asleep then pause applications unconditionally.
10307                return true;
10308        }
10309    }
10310
10311    /** Pokes the task persister. */
10312    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10313        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10314            // Never persist the home stack.
10315            return;
10316        }
10317        mTaskPersister.wakeup(task, flush);
10318    }
10319
10320    /** Notifies all listeners when the task stack has changed. */
10321    void notifyTaskStackChangedLocked() {
10322        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10323        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10324        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10325    }
10326
10327    @Override
10328    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
10329        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
10330    }
10331
10332    @Override
10333    public boolean shutdown(int timeout) {
10334        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10335                != PackageManager.PERMISSION_GRANTED) {
10336            throw new SecurityException("Requires permission "
10337                    + android.Manifest.permission.SHUTDOWN);
10338        }
10339
10340        boolean timedout = false;
10341
10342        synchronized(this) {
10343            mShuttingDown = true;
10344            updateEventDispatchingLocked();
10345            timedout = mStackSupervisor.shutdownLocked(timeout);
10346        }
10347
10348        mAppOpsService.shutdown();
10349        if (mUsageStatsService != null) {
10350            mUsageStatsService.prepareShutdown();
10351        }
10352        mBatteryStatsService.shutdown();
10353        synchronized (this) {
10354            mProcessStats.shutdownLocked();
10355            notifyTaskPersisterLocked(null, true);
10356        }
10357
10358        return timedout;
10359    }
10360
10361    public final void activitySlept(IBinder token) {
10362        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
10363
10364        final long origId = Binder.clearCallingIdentity();
10365
10366        synchronized (this) {
10367            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10368            if (r != null) {
10369                mStackSupervisor.activitySleptLocked(r);
10370            }
10371        }
10372
10373        Binder.restoreCallingIdentity(origId);
10374    }
10375
10376    private String lockScreenShownToString() {
10377        switch (mLockScreenShown) {
10378            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10379            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10380            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10381            default: return "Unknown=" + mLockScreenShown;
10382        }
10383    }
10384
10385    void logLockScreen(String msg) {
10386        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
10387                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10388                + PowerManagerInternal.wakefulnessToString(mWakefulness)
10389                + " mSleeping=" + mSleeping);
10390    }
10391
10392    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
10393        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
10394        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
10395            boolean wasRunningVoice = mRunningVoice != null;
10396            mRunningVoice = session;
10397            if (!wasRunningVoice) {
10398                mVoiceWakeLock.acquire();
10399                updateSleepIfNeededLocked();
10400            }
10401        }
10402    }
10403
10404    private void updateEventDispatchingLocked() {
10405        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10406    }
10407
10408    public void setLockScreenShown(boolean shown) {
10409        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10410                != PackageManager.PERMISSION_GRANTED) {
10411            throw new SecurityException("Requires permission "
10412                    + android.Manifest.permission.DEVICE_POWER);
10413        }
10414
10415        synchronized(this) {
10416            long ident = Binder.clearCallingIdentity();
10417            try {
10418                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10419                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10420                updateSleepIfNeededLocked();
10421            } finally {
10422                Binder.restoreCallingIdentity(ident);
10423            }
10424        }
10425    }
10426
10427    @Override
10428    public void stopAppSwitches() {
10429        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10430                != PackageManager.PERMISSION_GRANTED) {
10431            throw new SecurityException("Requires permission "
10432                    + android.Manifest.permission.STOP_APP_SWITCHES);
10433        }
10434
10435        synchronized(this) {
10436            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10437                    + APP_SWITCH_DELAY_TIME;
10438            mDidAppSwitch = false;
10439            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10440            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10441            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10442        }
10443    }
10444
10445    public void resumeAppSwitches() {
10446        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10447                != PackageManager.PERMISSION_GRANTED) {
10448            throw new SecurityException("Requires permission "
10449                    + android.Manifest.permission.STOP_APP_SWITCHES);
10450        }
10451
10452        synchronized(this) {
10453            // Note that we don't execute any pending app switches... we will
10454            // let those wait until either the timeout, or the next start
10455            // activity request.
10456            mAppSwitchesAllowedTime = 0;
10457        }
10458    }
10459
10460    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10461            int callingPid, int callingUid, String name) {
10462        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10463            return true;
10464        }
10465
10466        int perm = checkComponentPermission(
10467                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10468                sourceUid, -1, true);
10469        if (perm == PackageManager.PERMISSION_GRANTED) {
10470            return true;
10471        }
10472
10473        // If the actual IPC caller is different from the logical source, then
10474        // also see if they are allowed to control app switches.
10475        if (callingUid != -1 && callingUid != sourceUid) {
10476            perm = checkComponentPermission(
10477                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10478                    callingUid, -1, true);
10479            if (perm == PackageManager.PERMISSION_GRANTED) {
10480                return true;
10481            }
10482        }
10483
10484        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10485        return false;
10486    }
10487
10488    public void setDebugApp(String packageName, boolean waitForDebugger,
10489            boolean persistent) {
10490        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10491                "setDebugApp()");
10492
10493        long ident = Binder.clearCallingIdentity();
10494        try {
10495            // Note that this is not really thread safe if there are multiple
10496            // callers into it at the same time, but that's not a situation we
10497            // care about.
10498            if (persistent) {
10499                final ContentResolver resolver = mContext.getContentResolver();
10500                Settings.Global.putString(
10501                    resolver, Settings.Global.DEBUG_APP,
10502                    packageName);
10503                Settings.Global.putInt(
10504                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10505                    waitForDebugger ? 1 : 0);
10506            }
10507
10508            synchronized (this) {
10509                if (!persistent) {
10510                    mOrigDebugApp = mDebugApp;
10511                    mOrigWaitForDebugger = mWaitForDebugger;
10512                }
10513                mDebugApp = packageName;
10514                mWaitForDebugger = waitForDebugger;
10515                mDebugTransient = !persistent;
10516                if (packageName != null) {
10517                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10518                            false, UserHandle.USER_ALL, "set debug app");
10519                }
10520            }
10521        } finally {
10522            Binder.restoreCallingIdentity(ident);
10523        }
10524    }
10525
10526    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10527        synchronized (this) {
10528            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10529            if (!isDebuggable) {
10530                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10531                    throw new SecurityException("Process not debuggable: " + app.packageName);
10532                }
10533            }
10534
10535            mOpenGlTraceApp = processName;
10536        }
10537    }
10538
10539    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10540        synchronized (this) {
10541            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10542            if (!isDebuggable) {
10543                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10544                    throw new SecurityException("Process not debuggable: " + app.packageName);
10545                }
10546            }
10547            mProfileApp = processName;
10548            mProfileFile = profilerInfo.profileFile;
10549            if (mProfileFd != null) {
10550                try {
10551                    mProfileFd.close();
10552                } catch (IOException e) {
10553                }
10554                mProfileFd = null;
10555            }
10556            mProfileFd = profilerInfo.profileFd;
10557            mSamplingInterval = profilerInfo.samplingInterval;
10558            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10559            mProfileType = 0;
10560        }
10561    }
10562
10563    @Override
10564    public void setAlwaysFinish(boolean enabled) {
10565        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10566                "setAlwaysFinish()");
10567
10568        Settings.Global.putInt(
10569                mContext.getContentResolver(),
10570                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10571
10572        synchronized (this) {
10573            mAlwaysFinishActivities = enabled;
10574        }
10575    }
10576
10577    @Override
10578    public void setActivityController(IActivityController controller) {
10579        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10580                "setActivityController()");
10581        synchronized (this) {
10582            mController = controller;
10583            Watchdog.getInstance().setActivityController(controller);
10584        }
10585    }
10586
10587    @Override
10588    public void setUserIsMonkey(boolean userIsMonkey) {
10589        synchronized (this) {
10590            synchronized (mPidsSelfLocked) {
10591                final int callingPid = Binder.getCallingPid();
10592                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10593                if (precessRecord == null) {
10594                    throw new SecurityException("Unknown process: " + callingPid);
10595                }
10596                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10597                    throw new SecurityException("Only an instrumentation process "
10598                            + "with a UiAutomation can call setUserIsMonkey");
10599                }
10600            }
10601            mUserIsMonkey = userIsMonkey;
10602        }
10603    }
10604
10605    @Override
10606    public boolean isUserAMonkey() {
10607        synchronized (this) {
10608            // If there is a controller also implies the user is a monkey.
10609            return (mUserIsMonkey || mController != null);
10610        }
10611    }
10612
10613    public void requestBugReport() {
10614        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10615        SystemProperties.set("ctl.start", "bugreport");
10616    }
10617
10618    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10619        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10620    }
10621
10622    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10623        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10624            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10625        }
10626        return KEY_DISPATCHING_TIMEOUT;
10627    }
10628
10629    @Override
10630    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10631        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10632                != PackageManager.PERMISSION_GRANTED) {
10633            throw new SecurityException("Requires permission "
10634                    + android.Manifest.permission.FILTER_EVENTS);
10635        }
10636        ProcessRecord proc;
10637        long timeout;
10638        synchronized (this) {
10639            synchronized (mPidsSelfLocked) {
10640                proc = mPidsSelfLocked.get(pid);
10641            }
10642            timeout = getInputDispatchingTimeoutLocked(proc);
10643        }
10644
10645        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10646            return -1;
10647        }
10648
10649        return timeout;
10650    }
10651
10652    /**
10653     * Handle input dispatching timeouts.
10654     * Returns whether input dispatching should be aborted or not.
10655     */
10656    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10657            final ActivityRecord activity, final ActivityRecord parent,
10658            final boolean aboveSystem, String reason) {
10659        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10660                != PackageManager.PERMISSION_GRANTED) {
10661            throw new SecurityException("Requires permission "
10662                    + android.Manifest.permission.FILTER_EVENTS);
10663        }
10664
10665        final String annotation;
10666        if (reason == null) {
10667            annotation = "Input dispatching timed out";
10668        } else {
10669            annotation = "Input dispatching timed out (" + reason + ")";
10670        }
10671
10672        if (proc != null) {
10673            synchronized (this) {
10674                if (proc.debugging) {
10675                    return false;
10676                }
10677
10678                if (mDidDexOpt) {
10679                    // Give more time since we were dexopting.
10680                    mDidDexOpt = false;
10681                    return false;
10682                }
10683
10684                if (proc.instrumentationClass != null) {
10685                    Bundle info = new Bundle();
10686                    info.putString("shortMsg", "keyDispatchingTimedOut");
10687                    info.putString("longMsg", annotation);
10688                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10689                    return true;
10690                }
10691            }
10692            mHandler.post(new Runnable() {
10693                @Override
10694                public void run() {
10695                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10696                }
10697            });
10698        }
10699
10700        return true;
10701    }
10702
10703    @Override
10704    public Bundle getAssistContextExtras(int requestType) {
10705        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
10706                null, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
10707        if (pae == null) {
10708            return null;
10709        }
10710        synchronized (pae) {
10711            while (!pae.haveResult) {
10712                try {
10713                    pae.wait();
10714                } catch (InterruptedException e) {
10715                }
10716            }
10717        }
10718        synchronized (this) {
10719            buildAssistBundleLocked(pae, pae.result);
10720            mPendingAssistExtras.remove(pae);
10721            mHandler.removeCallbacks(pae);
10722        }
10723        return pae.extras;
10724    }
10725
10726    @Override
10727    public boolean isAssistDataAllowedOnCurrentActivity() {
10728        int userId = mCurrentUserId;
10729        synchronized (this) {
10730            ActivityRecord activity = getFocusedStack().topActivity();
10731            if (activity == null) {
10732                return false;
10733            }
10734            userId = activity.userId;
10735        }
10736        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
10737                Context.DEVICE_POLICY_SERVICE);
10738        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
10739    }
10740
10741    @Override
10742    public boolean showAssistFromActivity(IBinder token, Bundle args) {
10743        long ident = Binder.clearCallingIdentity();
10744        try {
10745            synchronized (this) {
10746                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
10747                ActivityRecord top = getFocusedStack().topActivity();
10748                if (top != caller) {
10749                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
10750                            + " is not current top " + top);
10751                    return false;
10752                }
10753                if (!top.nowVisible) {
10754                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
10755                            + " is not visible");
10756                    return false;
10757                }
10758            }
10759            AssistUtils utils = new AssistUtils(mContext);
10760            return utils.showSessionForActiveService(args,
10761                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
10762        } finally {
10763            Binder.restoreCallingIdentity(ident);
10764        }
10765    }
10766
10767    @Override
10768    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
10769            IBinder activityToken) {
10770        return enqueueAssistContext(requestType, null, null, receiver, activityToken,
10771                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
10772    }
10773
10774    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10775            IResultReceiver receiver, IBinder activityToken, int userHandle, Bundle args,
10776            long timeout) {
10777        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10778                "enqueueAssistContext()");
10779        synchronized (this) {
10780            ActivityRecord activity = getFocusedStack().topActivity();
10781            if (activity == null) {
10782                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
10783                return null;
10784            }
10785            if (activity.app == null || activity.app.thread == null) {
10786                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10787                return null;
10788            }
10789            if (activityToken != null) {
10790                ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
10791                if (activity != caller) {
10792                    Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
10793                            + " is not current top " + activity);
10794                    return null;
10795                }
10796            }
10797            PendingAssistExtras pae;
10798            Bundle extras = new Bundle();
10799            if (args != null) {
10800                extras.putAll(args);
10801            }
10802            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10803            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
10804            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
10805            try {
10806                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10807                        requestType);
10808                mPendingAssistExtras.add(pae);
10809                mHandler.postDelayed(pae, timeout);
10810            } catch (RemoteException e) {
10811                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10812                return null;
10813            }
10814            return pae;
10815        }
10816    }
10817
10818    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
10819        IResultReceiver receiver;
10820        synchronized (this) {
10821            mPendingAssistExtras.remove(pae);
10822            receiver = pae.receiver;
10823        }
10824        if (receiver != null) {
10825            // Caller wants result sent back to them.
10826            try {
10827                pae.receiver.send(0, null);
10828            } catch (RemoteException e) {
10829            }
10830        }
10831    }
10832
10833    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
10834        if (result != null) {
10835            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
10836        }
10837        if (pae.hint != null) {
10838            pae.extras.putBoolean(pae.hint, true);
10839        }
10840    }
10841
10842    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
10843            AssistContent content, Uri referrer) {
10844        PendingAssistExtras pae = (PendingAssistExtras)token;
10845        synchronized (pae) {
10846            pae.result = extras;
10847            pae.structure = structure;
10848            pae.content = content;
10849            if (referrer != null) {
10850                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
10851            }
10852            pae.haveResult = true;
10853            pae.notifyAll();
10854            if (pae.intent == null && pae.receiver == null) {
10855                // Caller is just waiting for the result.
10856                return;
10857            }
10858        }
10859
10860        // We are now ready to launch the assist activity.
10861        IResultReceiver sendReceiver = null;
10862        Bundle sendBundle = null;
10863        synchronized (this) {
10864            buildAssistBundleLocked(pae, extras);
10865            boolean exists = mPendingAssistExtras.remove(pae);
10866            mHandler.removeCallbacks(pae);
10867            if (!exists) {
10868                // Timed out.
10869                return;
10870            }
10871            if ((sendReceiver=pae.receiver) != null) {
10872                // Caller wants result sent back to them.
10873                sendBundle = new Bundle();
10874                sendBundle.putBundle("data", pae.extras);
10875                sendBundle.putParcelable("structure", pae.structure);
10876                sendBundle.putParcelable("content", pae.content);
10877            }
10878        }
10879        if (sendReceiver != null) {
10880            try {
10881                sendReceiver.send(0, sendBundle);
10882            } catch (RemoteException e) {
10883            }
10884            return;
10885        }
10886
10887        long ident = Binder.clearCallingIdentity();
10888        try {
10889            pae.intent.replaceExtras(pae.extras);
10890            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10891                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
10892                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10893            closeSystemDialogs("assist");
10894            try {
10895                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10896            } catch (ActivityNotFoundException e) {
10897                Slog.w(TAG, "No activity to handle assist action.", e);
10898            }
10899        } finally {
10900            Binder.restoreCallingIdentity(ident);
10901        }
10902    }
10903
10904    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
10905            Bundle args) {
10906        return enqueueAssistContext(requestType, intent, hint, null, null, userHandle, args,
10907                PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
10908    }
10909
10910    public void registerProcessObserver(IProcessObserver observer) {
10911        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10912                "registerProcessObserver()");
10913        synchronized (this) {
10914            mProcessObservers.register(observer);
10915        }
10916    }
10917
10918    @Override
10919    public void unregisterProcessObserver(IProcessObserver observer) {
10920        synchronized (this) {
10921            mProcessObservers.unregister(observer);
10922        }
10923    }
10924
10925    public void registerUidObserver(IUidObserver observer) {
10926        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10927                "registerUidObserver()");
10928        synchronized (this) {
10929            mUidObservers.register(observer);
10930        }
10931    }
10932
10933    @Override
10934    public void unregisterUidObserver(IUidObserver observer) {
10935        synchronized (this) {
10936            mUidObservers.unregister(observer);
10937        }
10938    }
10939
10940    @Override
10941    public boolean convertFromTranslucent(IBinder token) {
10942        final long origId = Binder.clearCallingIdentity();
10943        try {
10944            synchronized (this) {
10945                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10946                if (r == null) {
10947                    return false;
10948                }
10949                final boolean translucentChanged = r.changeWindowTranslucency(true);
10950                if (translucentChanged) {
10951                    r.task.stack.releaseBackgroundResources(r);
10952                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10953                }
10954                mWindowManager.setAppFullscreen(token, true);
10955                return translucentChanged;
10956            }
10957        } finally {
10958            Binder.restoreCallingIdentity(origId);
10959        }
10960    }
10961
10962    @Override
10963    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10964        final long origId = Binder.clearCallingIdentity();
10965        try {
10966            synchronized (this) {
10967                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10968                if (r == null) {
10969                    return false;
10970                }
10971                int index = r.task.mActivities.lastIndexOf(r);
10972                if (index > 0) {
10973                    ActivityRecord under = r.task.mActivities.get(index - 1);
10974                    under.returningOptions = options;
10975                }
10976                final boolean translucentChanged = r.changeWindowTranslucency(false);
10977                if (translucentChanged) {
10978                    r.task.stack.convertActivityToTranslucent(r);
10979                }
10980                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10981                mWindowManager.setAppFullscreen(token, false);
10982                return translucentChanged;
10983            }
10984        } finally {
10985            Binder.restoreCallingIdentity(origId);
10986        }
10987    }
10988
10989    @Override
10990    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10991        final long origId = Binder.clearCallingIdentity();
10992        try {
10993            synchronized (this) {
10994                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10995                if (r != null) {
10996                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10997                }
10998            }
10999            return false;
11000        } finally {
11001            Binder.restoreCallingIdentity(origId);
11002        }
11003    }
11004
11005    @Override
11006    public boolean isBackgroundVisibleBehind(IBinder token) {
11007        final long origId = Binder.clearCallingIdentity();
11008        try {
11009            synchronized (this) {
11010                final ActivityStack stack = ActivityRecord.getStackLocked(token);
11011                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
11012                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
11013                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
11014                return visible;
11015            }
11016        } finally {
11017            Binder.restoreCallingIdentity(origId);
11018        }
11019    }
11020
11021    @Override
11022    public ActivityOptions getActivityOptions(IBinder token) {
11023        final long origId = Binder.clearCallingIdentity();
11024        try {
11025            synchronized (this) {
11026                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11027                if (r != null) {
11028                    final ActivityOptions activityOptions = r.pendingOptions;
11029                    r.pendingOptions = null;
11030                    return activityOptions;
11031                }
11032                return null;
11033            }
11034        } finally {
11035            Binder.restoreCallingIdentity(origId);
11036        }
11037    }
11038
11039    @Override
11040    public void setImmersive(IBinder token, boolean immersive) {
11041        synchronized(this) {
11042            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11043            if (r == null) {
11044                throw new IllegalArgumentException();
11045            }
11046            r.immersive = immersive;
11047
11048            // update associated state if we're frontmost
11049            if (r == mFocusedActivity) {
11050                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
11051                applyUpdateLockStateLocked(r);
11052            }
11053        }
11054    }
11055
11056    @Override
11057    public boolean isImmersive(IBinder token) {
11058        synchronized (this) {
11059            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11060            if (r == null) {
11061                throw new IllegalArgumentException();
11062            }
11063            return r.immersive;
11064        }
11065    }
11066
11067    public boolean isTopActivityImmersive() {
11068        enforceNotIsolatedCaller("startActivity");
11069        synchronized (this) {
11070            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
11071            return (r != null) ? r.immersive : false;
11072        }
11073    }
11074
11075    @Override
11076    public boolean isTopOfTask(IBinder token) {
11077        synchronized (this) {
11078            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11079            if (r == null) {
11080                throw new IllegalArgumentException();
11081            }
11082            return r.task.getTopActivity() == r;
11083        }
11084    }
11085
11086    public final void enterSafeMode() {
11087        synchronized(this) {
11088            // It only makes sense to do this before the system is ready
11089            // and started launching other packages.
11090            if (!mSystemReady) {
11091                try {
11092                    AppGlobals.getPackageManager().enterSafeMode();
11093                } catch (RemoteException e) {
11094                }
11095            }
11096
11097            mSafeMode = true;
11098        }
11099    }
11100
11101    public final void showSafeModeOverlay() {
11102        View v = LayoutInflater.from(mContext).inflate(
11103                com.android.internal.R.layout.safe_mode, null);
11104        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
11105        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
11106        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
11107        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
11108        lp.gravity = Gravity.BOTTOM | Gravity.START;
11109        lp.format = v.getBackground().getOpacity();
11110        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
11111                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
11112        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
11113        ((WindowManager)mContext.getSystemService(
11114                Context.WINDOW_SERVICE)).addView(v, lp);
11115    }
11116
11117    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
11118        if (!(sender instanceof PendingIntentRecord)) {
11119            return;
11120        }
11121        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11122        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11123        synchronized (stats) {
11124            if (mBatteryStatsService.isOnBattery()) {
11125                mBatteryStatsService.enforceCallingPermission();
11126                int MY_UID = Binder.getCallingUid();
11127                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11128                BatteryStatsImpl.Uid.Pkg pkg =
11129                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
11130                            sourcePkg != null ? sourcePkg : rec.key.packageName);
11131                pkg.noteWakeupAlarmLocked(tag);
11132            }
11133        }
11134    }
11135
11136    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
11137        if (!(sender instanceof PendingIntentRecord)) {
11138            return;
11139        }
11140        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11141        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11142        synchronized (stats) {
11143            mBatteryStatsService.enforceCallingPermission();
11144            int MY_UID = Binder.getCallingUid();
11145            int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11146            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
11147        }
11148    }
11149
11150    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
11151        if (!(sender instanceof PendingIntentRecord)) {
11152            return;
11153        }
11154        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11155        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11156        synchronized (stats) {
11157            mBatteryStatsService.enforceCallingPermission();
11158            int MY_UID = Binder.getCallingUid();
11159            int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11160            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
11161        }
11162    }
11163
11164    public boolean killPids(int[] pids, String pReason, boolean secure) {
11165        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11166            throw new SecurityException("killPids only available to the system");
11167        }
11168        String reason = (pReason == null) ? "Unknown" : pReason;
11169        // XXX Note: don't acquire main activity lock here, because the window
11170        // manager calls in with its locks held.
11171
11172        boolean killed = false;
11173        synchronized (mPidsSelfLocked) {
11174            int[] types = new int[pids.length];
11175            int worstType = 0;
11176            for (int i=0; i<pids.length; i++) {
11177                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11178                if (proc != null) {
11179                    int type = proc.setAdj;
11180                    types[i] = type;
11181                    if (type > worstType) {
11182                        worstType = type;
11183                    }
11184                }
11185            }
11186
11187            // If the worst oom_adj is somewhere in the cached proc LRU range,
11188            // then constrain it so we will kill all cached procs.
11189            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
11190                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
11191                worstType = ProcessList.CACHED_APP_MIN_ADJ;
11192            }
11193
11194            // If this is not a secure call, don't let it kill processes that
11195            // are important.
11196            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
11197                worstType = ProcessList.SERVICE_ADJ;
11198            }
11199
11200            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
11201            for (int i=0; i<pids.length; i++) {
11202                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11203                if (proc == null) {
11204                    continue;
11205                }
11206                int adj = proc.setAdj;
11207                if (adj >= worstType && !proc.killedByAm) {
11208                    proc.kill(reason, true);
11209                    killed = true;
11210                }
11211            }
11212        }
11213        return killed;
11214    }
11215
11216    @Override
11217    public void killUid(int uid, String reason) {
11218        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
11219        synchronized (this) {
11220            final long identity = Binder.clearCallingIdentity();
11221            try {
11222                killPackageProcessesLocked(null, UserHandle.getAppId(uid),
11223                        UserHandle.getUserId(uid),
11224                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
11225                        reason != null ? reason : "kill uid");
11226            } finally {
11227                Binder.restoreCallingIdentity(identity);
11228            }
11229        }
11230    }
11231
11232    @Override
11233    public boolean killProcessesBelowForeground(String reason) {
11234        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11235            throw new SecurityException("killProcessesBelowForeground() only available to system");
11236        }
11237
11238        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
11239    }
11240
11241    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
11242        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11243            throw new SecurityException("killProcessesBelowAdj() only available to system");
11244        }
11245
11246        boolean killed = false;
11247        synchronized (mPidsSelfLocked) {
11248            final int size = mPidsSelfLocked.size();
11249            for (int i = 0; i < size; i++) {
11250                final int pid = mPidsSelfLocked.keyAt(i);
11251                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11252                if (proc == null) continue;
11253
11254                final int adj = proc.setAdj;
11255                if (adj > belowAdj && !proc.killedByAm) {
11256                    proc.kill(reason, true);
11257                    killed = true;
11258                }
11259            }
11260        }
11261        return killed;
11262    }
11263
11264    @Override
11265    public void hang(final IBinder who, boolean allowRestart) {
11266        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11267                != PackageManager.PERMISSION_GRANTED) {
11268            throw new SecurityException("Requires permission "
11269                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11270        }
11271
11272        final IBinder.DeathRecipient death = new DeathRecipient() {
11273            @Override
11274            public void binderDied() {
11275                synchronized (this) {
11276                    notifyAll();
11277                }
11278            }
11279        };
11280
11281        try {
11282            who.linkToDeath(death, 0);
11283        } catch (RemoteException e) {
11284            Slog.w(TAG, "hang: given caller IBinder is already dead.");
11285            return;
11286        }
11287
11288        synchronized (this) {
11289            Watchdog.getInstance().setAllowRestart(allowRestart);
11290            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
11291            synchronized (death) {
11292                while (who.isBinderAlive()) {
11293                    try {
11294                        death.wait();
11295                    } catch (InterruptedException e) {
11296                    }
11297                }
11298            }
11299            Watchdog.getInstance().setAllowRestart(true);
11300        }
11301    }
11302
11303    @Override
11304    public void restart() {
11305        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11306                != PackageManager.PERMISSION_GRANTED) {
11307            throw new SecurityException("Requires permission "
11308                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11309        }
11310
11311        Log.i(TAG, "Sending shutdown broadcast...");
11312
11313        BroadcastReceiver br = new BroadcastReceiver() {
11314            @Override public void onReceive(Context context, Intent intent) {
11315                // Now the broadcast is done, finish up the low-level shutdown.
11316                Log.i(TAG, "Shutting down activity manager...");
11317                shutdown(10000);
11318                Log.i(TAG, "Shutdown complete, restarting!");
11319                Process.killProcess(Process.myPid());
11320                System.exit(10);
11321            }
11322        };
11323
11324        // First send the high-level shut down broadcast.
11325        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
11326        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
11327        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
11328        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
11329        mContext.sendOrderedBroadcastAsUser(intent,
11330                UserHandle.ALL, null, br, mHandler, 0, null, null);
11331        */
11332        br.onReceive(mContext, intent);
11333    }
11334
11335    private long getLowRamTimeSinceIdle(long now) {
11336        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
11337    }
11338
11339    @Override
11340    public void performIdleMaintenance() {
11341        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11342                != PackageManager.PERMISSION_GRANTED) {
11343            throw new SecurityException("Requires permission "
11344                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11345        }
11346
11347        synchronized (this) {
11348            final long now = SystemClock.uptimeMillis();
11349            final long timeSinceLastIdle = now - mLastIdleTime;
11350            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
11351            mLastIdleTime = now;
11352            mLowRamTimeSinceLastIdle = 0;
11353            if (mLowRamStartTime != 0) {
11354                mLowRamStartTime = now;
11355            }
11356
11357            StringBuilder sb = new StringBuilder(128);
11358            sb.append("Idle maintenance over ");
11359            TimeUtils.formatDuration(timeSinceLastIdle, sb);
11360            sb.append(" low RAM for ");
11361            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11362            Slog.i(TAG, sb.toString());
11363
11364            // If at least 1/3 of our time since the last idle period has been spent
11365            // with RAM low, then we want to kill processes.
11366            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
11367
11368            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11369                ProcessRecord proc = mLruProcesses.get(i);
11370                if (proc.notCachedSinceIdle) {
11371                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
11372                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
11373                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
11374                        if (doKilling && proc.initialIdlePss != 0
11375                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
11376                            sb = new StringBuilder(128);
11377                            sb.append("Kill");
11378                            sb.append(proc.processName);
11379                            sb.append(" in idle maint: pss=");
11380                            sb.append(proc.lastPss);
11381                            sb.append(", initialPss=");
11382                            sb.append(proc.initialIdlePss);
11383                            sb.append(", period=");
11384                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
11385                            sb.append(", lowRamPeriod=");
11386                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11387                            Slog.wtfQuiet(TAG, sb.toString());
11388                            proc.kill("idle maint (pss " + proc.lastPss
11389                                    + " from " + proc.initialIdlePss + ")", true);
11390                        }
11391                    }
11392                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
11393                    proc.notCachedSinceIdle = true;
11394                    proc.initialIdlePss = 0;
11395                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
11396                            mTestPssMode, isSleeping(), now);
11397                }
11398            }
11399
11400            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
11401            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
11402        }
11403    }
11404
11405    private void retrieveSettings() {
11406        final ContentResolver resolver = mContext.getContentResolver();
11407        String debugApp = Settings.Global.getString(
11408            resolver, Settings.Global.DEBUG_APP);
11409        boolean waitForDebugger = Settings.Global.getInt(
11410            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11411        boolean alwaysFinishActivities = Settings.Global.getInt(
11412            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11413        boolean forceRtl = Settings.Global.getInt(
11414                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11415        // Transfer any global setting for forcing RTL layout, into a System Property
11416        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11417
11418        Configuration configuration = new Configuration();
11419        Settings.System.getConfiguration(resolver, configuration);
11420        if (forceRtl) {
11421            // This will take care of setting the correct layout direction flags
11422            configuration.setLayoutDirection(configuration.locale);
11423        }
11424
11425        synchronized (this) {
11426            mDebugApp = mOrigDebugApp = debugApp;
11427            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11428            mAlwaysFinishActivities = alwaysFinishActivities;
11429            // This happens before any activities are started, so we can
11430            // change mConfiguration in-place.
11431            updateConfigurationLocked(configuration, null, false, true);
11432            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
11433                    "Initial config: " + mConfiguration);
11434        }
11435    }
11436
11437    /** Loads resources after the current configuration has been set. */
11438    private void loadResourcesOnSystemReady() {
11439        final Resources res = mContext.getResources();
11440        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11441        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11442        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11443    }
11444
11445    public boolean testIsSystemReady() {
11446        // no need to synchronize(this) just to read & return the value
11447        return mSystemReady;
11448    }
11449
11450    private static File getCalledPreBootReceiversFile() {
11451        File dataDir = Environment.getDataDirectory();
11452        File systemDir = new File(dataDir, "system");
11453        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11454        return fname;
11455    }
11456
11457    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11458        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11459        File file = getCalledPreBootReceiversFile();
11460        FileInputStream fis = null;
11461        try {
11462            fis = new FileInputStream(file);
11463            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11464            int fvers = dis.readInt();
11465            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11466                String vers = dis.readUTF();
11467                String codename = dis.readUTF();
11468                String build = dis.readUTF();
11469                if (android.os.Build.VERSION.RELEASE.equals(vers)
11470                        && android.os.Build.VERSION.CODENAME.equals(codename)
11471                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11472                    int num = dis.readInt();
11473                    while (num > 0) {
11474                        num--;
11475                        String pkg = dis.readUTF();
11476                        String cls = dis.readUTF();
11477                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11478                    }
11479                }
11480            }
11481        } catch (FileNotFoundException e) {
11482        } catch (IOException e) {
11483            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11484        } finally {
11485            if (fis != null) {
11486                try {
11487                    fis.close();
11488                } catch (IOException e) {
11489                }
11490            }
11491        }
11492        return lastDoneReceivers;
11493    }
11494
11495    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11496        File file = getCalledPreBootReceiversFile();
11497        FileOutputStream fos = null;
11498        DataOutputStream dos = null;
11499        try {
11500            fos = new FileOutputStream(file);
11501            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11502            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11503            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11504            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11505            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11506            dos.writeInt(list.size());
11507            for (int i=0; i<list.size(); i++) {
11508                dos.writeUTF(list.get(i).getPackageName());
11509                dos.writeUTF(list.get(i).getClassName());
11510            }
11511        } catch (IOException e) {
11512            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11513            file.delete();
11514        } finally {
11515            FileUtils.sync(fos);
11516            if (dos != null) {
11517                try {
11518                    dos.close();
11519                } catch (IOException e) {
11520                    // TODO Auto-generated catch block
11521                    e.printStackTrace();
11522                }
11523            }
11524        }
11525    }
11526
11527    final class PreBootContinuation extends IIntentReceiver.Stub {
11528        final Intent intent;
11529        final Runnable onFinishCallback;
11530        final ArrayList<ComponentName> doneReceivers;
11531        final List<ResolveInfo> ris;
11532        final int[] users;
11533        int lastRi = -1;
11534        int curRi = 0;
11535        int curUser = 0;
11536
11537        PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
11538                ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
11539            intent = _intent;
11540            onFinishCallback = _onFinishCallback;
11541            doneReceivers = _doneReceivers;
11542            ris = _ris;
11543            users = _users;
11544        }
11545
11546        void go() {
11547            if (lastRi != curRi) {
11548                ActivityInfo ai = ris.get(curRi).activityInfo;
11549                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11550                intent.setComponent(comp);
11551                doneReceivers.add(comp);
11552                lastRi = curRi;
11553                CharSequence label = ai.loadLabel(mContext.getPackageManager());
11554                showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
11555            }
11556            Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
11557                    + " for user " + users[curUser]);
11558            EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
11559            broadcastIntentLocked(null, null, intent, null, this,
11560                    0, null, null, null, AppOpsManager.OP_NONE,
11561                    null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
11562        }
11563
11564        public void performReceive(Intent intent, int resultCode,
11565                String data, Bundle extras, boolean ordered,
11566                boolean sticky, int sendingUser) {
11567            curUser++;
11568            if (curUser >= users.length) {
11569                curUser = 0;
11570                curRi++;
11571                if (curRi >= ris.size()) {
11572                    // All done sending broadcasts!
11573                    if (onFinishCallback != null) {
11574                        // The raw IIntentReceiver interface is called
11575                        // with the AM lock held, so redispatch to
11576                        // execute our code without the lock.
11577                        mHandler.post(onFinishCallback);
11578                    }
11579                    return;
11580                }
11581            }
11582            go();
11583        }
11584    }
11585
11586    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11587            ArrayList<ComponentName> doneReceivers, int userId) {
11588        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11589        List<ResolveInfo> ris = null;
11590        try {
11591            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11592                    intent, null, 0, userId);
11593        } catch (RemoteException e) {
11594        }
11595        if (ris == null) {
11596            return false;
11597        }
11598        for (int i=ris.size()-1; i>=0; i--) {
11599            if ((ris.get(i).activityInfo.applicationInfo.flags
11600                    &ApplicationInfo.FLAG_SYSTEM) == 0) {
11601                ris.remove(i);
11602            }
11603        }
11604        intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11605
11606        // For User 0, load the version number. When delivering to a new user, deliver
11607        // to all receivers.
11608        if (userId == UserHandle.USER_OWNER) {
11609            ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11610            for (int i=0; i<ris.size(); i++) {
11611                ActivityInfo ai = ris.get(i).activityInfo;
11612                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11613                if (lastDoneReceivers.contains(comp)) {
11614                    // We already did the pre boot receiver for this app with the current
11615                    // platform version, so don't do it again...
11616                    ris.remove(i);
11617                    i--;
11618                    // ...however, do keep it as one that has been done, so we don't
11619                    // forget about it when rewriting the file of last done receivers.
11620                    doneReceivers.add(comp);
11621                }
11622            }
11623        }
11624
11625        if (ris.size() <= 0) {
11626            return false;
11627        }
11628
11629        // If primary user, send broadcast to all available users, else just to userId
11630        final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11631                : new int[] { userId };
11632        if (users.length <= 0) {
11633            return false;
11634        }
11635
11636        PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
11637                ris, users);
11638        cont.go();
11639        return true;
11640    }
11641
11642    public void systemReady(final Runnable goingCallback) {
11643        synchronized(this) {
11644            if (mSystemReady) {
11645                // If we're done calling all the receivers, run the next "boot phase" passed in
11646                // by the SystemServer
11647                if (goingCallback != null) {
11648                    goingCallback.run();
11649                }
11650                return;
11651            }
11652
11653            mLocalDeviceIdleController
11654                    = LocalServices.getService(DeviceIdleController.LocalService.class);
11655
11656            // Make sure we have the current profile info, since it is needed for
11657            // security checks.
11658            updateCurrentProfileIdsLocked();
11659
11660            mRecentTasks.clear();
11661            mRecentTasks.addAll(mTaskPersister.restoreTasksLocked());
11662            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
11663            mTaskPersister.startPersisting();
11664
11665            // Check to see if there are any update receivers to run.
11666            if (!mDidUpdate) {
11667                if (mWaitingUpdate) {
11668                    return;
11669                }
11670                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11671                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11672                    public void run() {
11673                        synchronized (ActivityManagerService.this) {
11674                            mDidUpdate = true;
11675                        }
11676                        showBootMessage(mContext.getText(
11677                                R.string.android_upgrading_complete),
11678                                false);
11679                        writeLastDonePreBootReceivers(doneReceivers);
11680                        systemReady(goingCallback);
11681                    }
11682                }, doneReceivers, UserHandle.USER_OWNER);
11683
11684                if (mWaitingUpdate) {
11685                    return;
11686                }
11687                mDidUpdate = true;
11688            }
11689
11690            mAppOpsService.systemReady();
11691            mSystemReady = true;
11692        }
11693
11694        ArrayList<ProcessRecord> procsToKill = null;
11695        synchronized(mPidsSelfLocked) {
11696            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11697                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11698                if (!isAllowedWhileBooting(proc.info)){
11699                    if (procsToKill == null) {
11700                        procsToKill = new ArrayList<ProcessRecord>();
11701                    }
11702                    procsToKill.add(proc);
11703                }
11704            }
11705        }
11706
11707        synchronized(this) {
11708            if (procsToKill != null) {
11709                for (int i=procsToKill.size()-1; i>=0; i--) {
11710                    ProcessRecord proc = procsToKill.get(i);
11711                    Slog.i(TAG, "Removing system update proc: " + proc);
11712                    removeProcessLocked(proc, true, false, "system update done");
11713                }
11714            }
11715
11716            // Now that we have cleaned up any update processes, we
11717            // are ready to start launching real processes and know that
11718            // we won't trample on them any more.
11719            mProcessesReady = true;
11720        }
11721
11722        Slog.i(TAG, "System now ready");
11723        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11724            SystemClock.uptimeMillis());
11725
11726        synchronized(this) {
11727            // Make sure we have no pre-ready processes sitting around.
11728
11729            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11730                ResolveInfo ri = mContext.getPackageManager()
11731                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11732                                STOCK_PM_FLAGS);
11733                CharSequence errorMsg = null;
11734                if (ri != null) {
11735                    ActivityInfo ai = ri.activityInfo;
11736                    ApplicationInfo app = ai.applicationInfo;
11737                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11738                        mTopAction = Intent.ACTION_FACTORY_TEST;
11739                        mTopData = null;
11740                        mTopComponent = new ComponentName(app.packageName,
11741                                ai.name);
11742                    } else {
11743                        errorMsg = mContext.getResources().getText(
11744                                com.android.internal.R.string.factorytest_not_system);
11745                    }
11746                } else {
11747                    errorMsg = mContext.getResources().getText(
11748                            com.android.internal.R.string.factorytest_no_action);
11749                }
11750                if (errorMsg != null) {
11751                    mTopAction = null;
11752                    mTopData = null;
11753                    mTopComponent = null;
11754                    Message msg = Message.obtain();
11755                    msg.what = SHOW_FACTORY_ERROR_MSG;
11756                    msg.getData().putCharSequence("msg", errorMsg);
11757                    mUiHandler.sendMessage(msg);
11758                }
11759            }
11760        }
11761
11762        retrieveSettings();
11763        loadResourcesOnSystemReady();
11764
11765        synchronized (this) {
11766            readGrantedUriPermissionsLocked();
11767        }
11768
11769        if (goingCallback != null) goingCallback.run();
11770
11771        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11772                Integer.toString(mCurrentUserId), mCurrentUserId);
11773        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11774                Integer.toString(mCurrentUserId), mCurrentUserId);
11775        mSystemServiceManager.startUser(mCurrentUserId);
11776
11777        synchronized (this) {
11778            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11779                try {
11780                    List apps = AppGlobals.getPackageManager().
11781                        getPersistentApplications(STOCK_PM_FLAGS);
11782                    if (apps != null) {
11783                        int N = apps.size();
11784                        int i;
11785                        for (i=0; i<N; i++) {
11786                            ApplicationInfo info
11787                                = (ApplicationInfo)apps.get(i);
11788                            if (info != null &&
11789                                    !info.packageName.equals("android")) {
11790                                addAppLocked(info, false, null /* ABI override */);
11791                            }
11792                        }
11793                    }
11794                } catch (RemoteException ex) {
11795                    // pm is in same process, this will never happen.
11796                }
11797            }
11798
11799            // Start up initial activity.
11800            mBooting = true;
11801            startHomeActivityLocked(mCurrentUserId, "systemReady");
11802
11803            try {
11804                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11805                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11806                            + " data partition or your device will be unstable.");
11807                    mUiHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11808                }
11809            } catch (RemoteException e) {
11810            }
11811
11812            if (!Build.isBuildConsistent()) {
11813                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11814                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11815            }
11816
11817            long ident = Binder.clearCallingIdentity();
11818            try {
11819                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11820                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11821                        | Intent.FLAG_RECEIVER_FOREGROUND);
11822                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11823                broadcastIntentLocked(null, null, intent,
11824                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11825                        null, false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11826                intent = new Intent(Intent.ACTION_USER_STARTING);
11827                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11828                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11829                broadcastIntentLocked(null, null, intent,
11830                        null, new IIntentReceiver.Stub() {
11831                            @Override
11832                            public void performReceive(Intent intent, int resultCode, String data,
11833                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11834                                    throws RemoteException {
11835                            }
11836                        }, 0, null, null,
11837                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
11838                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11839            } catch (Throwable t) {
11840                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11841            } finally {
11842                Binder.restoreCallingIdentity(ident);
11843            }
11844            mStackSupervisor.resumeTopActivitiesLocked();
11845            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11846        }
11847    }
11848
11849    private boolean makeAppCrashingLocked(ProcessRecord app,
11850            String shortMsg, String longMsg, String stackTrace) {
11851        app.crashing = true;
11852        app.crashingReport = generateProcessError(app,
11853                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11854        startAppProblemLocked(app);
11855        app.stopFreezingAllLocked();
11856        return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
11857    }
11858
11859    private void makeAppNotRespondingLocked(ProcessRecord app,
11860            String activity, String shortMsg, String longMsg) {
11861        app.notResponding = true;
11862        app.notRespondingReport = generateProcessError(app,
11863                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11864                activity, shortMsg, longMsg, null);
11865        startAppProblemLocked(app);
11866        app.stopFreezingAllLocked();
11867    }
11868
11869    /**
11870     * Generate a process error record, suitable for attachment to a ProcessRecord.
11871     *
11872     * @param app The ProcessRecord in which the error occurred.
11873     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11874     *                      ActivityManager.AppErrorStateInfo
11875     * @param activity The activity associated with the crash, if known.
11876     * @param shortMsg Short message describing the crash.
11877     * @param longMsg Long message describing the crash.
11878     * @param stackTrace Full crash stack trace, may be null.
11879     *
11880     * @return Returns a fully-formed AppErrorStateInfo record.
11881     */
11882    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11883            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11884        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11885
11886        report.condition = condition;
11887        report.processName = app.processName;
11888        report.pid = app.pid;
11889        report.uid = app.info.uid;
11890        report.tag = activity;
11891        report.shortMsg = shortMsg;
11892        report.longMsg = longMsg;
11893        report.stackTrace = stackTrace;
11894
11895        return report;
11896    }
11897
11898    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11899        synchronized (this) {
11900            app.crashing = false;
11901            app.crashingReport = null;
11902            app.notResponding = false;
11903            app.notRespondingReport = null;
11904            if (app.anrDialog == fromDialog) {
11905                app.anrDialog = null;
11906            }
11907            if (app.waitDialog == fromDialog) {
11908                app.waitDialog = null;
11909            }
11910            if (app.pid > 0 && app.pid != MY_PID) {
11911                handleAppCrashLocked(app, "user-terminated" /*reason*/,
11912                        null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
11913                app.kill("user request after error", true);
11914            }
11915        }
11916    }
11917
11918    private boolean handleAppCrashLocked(ProcessRecord app, String reason,
11919            String shortMsg, String longMsg, String stackTrace) {
11920        long now = SystemClock.uptimeMillis();
11921
11922        Long crashTime;
11923        if (!app.isolated) {
11924            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11925        } else {
11926            crashTime = null;
11927        }
11928        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11929            // This process loses!
11930            Slog.w(TAG, "Process " + app.info.processName
11931                    + " has crashed too many times: killing!");
11932            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11933                    app.userId, app.info.processName, app.uid);
11934            mStackSupervisor.handleAppCrashLocked(app);
11935            if (!app.persistent) {
11936                // We don't want to start this process again until the user
11937                // explicitly does so...  but for persistent process, we really
11938                // need to keep it running.  If a persistent process is actually
11939                // repeatedly crashing, then badness for everyone.
11940                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11941                        app.info.processName);
11942                if (!app.isolated) {
11943                    // XXX We don't have a way to mark isolated processes
11944                    // as bad, since they don't have a peristent identity.
11945                    mBadProcesses.put(app.info.processName, app.uid,
11946                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11947                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11948                }
11949                app.bad = true;
11950                app.removed = true;
11951                // Don't let services in this process be restarted and potentially
11952                // annoy the user repeatedly.  Unless it is persistent, since those
11953                // processes run critical code.
11954                removeProcessLocked(app, false, false, "crash");
11955                mStackSupervisor.resumeTopActivitiesLocked();
11956                return false;
11957            }
11958            mStackSupervisor.resumeTopActivitiesLocked();
11959        } else {
11960            mStackSupervisor.finishTopRunningActivityLocked(app, reason);
11961        }
11962
11963        // Bump up the crash count of any services currently running in the proc.
11964        for (int i=app.services.size()-1; i>=0; i--) {
11965            // Any services running in the application need to be placed
11966            // back in the pending list.
11967            ServiceRecord sr = app.services.valueAt(i);
11968            sr.crashCount++;
11969        }
11970
11971        // If the crashing process is what we consider to be the "home process" and it has been
11972        // replaced by a third-party app, clear the package preferred activities from packages
11973        // with a home activity running in the process to prevent a repeatedly crashing app
11974        // from blocking the user to manually clear the list.
11975        final ArrayList<ActivityRecord> activities = app.activities;
11976        if (app == mHomeProcess && activities.size() > 0
11977                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11978            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11979                final ActivityRecord r = activities.get(activityNdx);
11980                if (r.isHomeActivity()) {
11981                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11982                    try {
11983                        ActivityThread.getPackageManager()
11984                                .clearPackagePreferredActivities(r.packageName);
11985                    } catch (RemoteException c) {
11986                        // pm is in same process, this will never happen.
11987                    }
11988                }
11989            }
11990        }
11991
11992        if (!app.isolated) {
11993            // XXX Can't keep track of crash times for isolated processes,
11994            // because they don't have a perisistent identity.
11995            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11996        }
11997
11998        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11999        return true;
12000    }
12001
12002    void startAppProblemLocked(ProcessRecord app) {
12003        // If this app is not running under the current user, then we
12004        // can't give it a report button because that would require
12005        // launching the report UI under a different user.
12006        app.errorReportReceiver = null;
12007
12008        for (int userId : mCurrentProfileIds) {
12009            if (app.userId == userId) {
12010                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
12011                        mContext, app.info.packageName, app.info.flags);
12012            }
12013        }
12014        skipCurrentReceiverLocked(app);
12015    }
12016
12017    void skipCurrentReceiverLocked(ProcessRecord app) {
12018        for (BroadcastQueue queue : mBroadcastQueues) {
12019            queue.skipCurrentReceiverLocked(app);
12020        }
12021    }
12022
12023    /**
12024     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12025     * The application process will exit immediately after this call returns.
12026     * @param app object of the crashing app, null for the system server
12027     * @param crashInfo describing the exception
12028     */
12029    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12030        ProcessRecord r = findAppProcess(app, "Crash");
12031        final String processName = app == null ? "system_server"
12032                : (r == null ? "unknown" : r.processName);
12033
12034        handleApplicationCrashInner("crash", r, processName, crashInfo);
12035    }
12036
12037    /* Native crash reporting uses this inner version because it needs to be somewhat
12038     * decoupled from the AM-managed cleanup lifecycle
12039     */
12040    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12041            ApplicationErrorReport.CrashInfo crashInfo) {
12042        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12043                UserHandle.getUserId(Binder.getCallingUid()), processName,
12044                r == null ? -1 : r.info.flags,
12045                crashInfo.exceptionClassName,
12046                crashInfo.exceptionMessage,
12047                crashInfo.throwFileName,
12048                crashInfo.throwLineNumber);
12049
12050        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12051
12052        crashApplication(r, crashInfo);
12053    }
12054
12055    public void handleApplicationStrictModeViolation(
12056            IBinder app,
12057            int violationMask,
12058            StrictMode.ViolationInfo info) {
12059        ProcessRecord r = findAppProcess(app, "StrictMode");
12060        if (r == null) {
12061            return;
12062        }
12063
12064        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12065            Integer stackFingerprint = info.hashCode();
12066            boolean logIt = true;
12067            synchronized (mAlreadyLoggedViolatedStacks) {
12068                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12069                    logIt = false;
12070                    // TODO: sub-sample into EventLog for these, with
12071                    // the info.durationMillis?  Then we'd get
12072                    // the relative pain numbers, without logging all
12073                    // the stack traces repeatedly.  We'd want to do
12074                    // likewise in the client code, which also does
12075                    // dup suppression, before the Binder call.
12076                } else {
12077                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12078                        mAlreadyLoggedViolatedStacks.clear();
12079                    }
12080                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12081                }
12082            }
12083            if (logIt) {
12084                logStrictModeViolationToDropBox(r, info);
12085            }
12086        }
12087
12088        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12089            AppErrorResult result = new AppErrorResult();
12090            synchronized (this) {
12091                final long origId = Binder.clearCallingIdentity();
12092
12093                Message msg = Message.obtain();
12094                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
12095                HashMap<String, Object> data = new HashMap<String, Object>();
12096                data.put("result", result);
12097                data.put("app", r);
12098                data.put("violationMask", violationMask);
12099                data.put("info", info);
12100                msg.obj = data;
12101                mUiHandler.sendMessage(msg);
12102
12103                Binder.restoreCallingIdentity(origId);
12104            }
12105            int res = result.get();
12106            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12107        }
12108    }
12109
12110    // Depending on the policy in effect, there could be a bunch of
12111    // these in quick succession so we try to batch these together to
12112    // minimize disk writes, number of dropbox entries, and maximize
12113    // compression, by having more fewer, larger records.
12114    private void logStrictModeViolationToDropBox(
12115            ProcessRecord process,
12116            StrictMode.ViolationInfo info) {
12117        if (info == null) {
12118            return;
12119        }
12120        final boolean isSystemApp = process == null ||
12121                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12122                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12123        final String processName = process == null ? "unknown" : process.processName;
12124        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12125        final DropBoxManager dbox = (DropBoxManager)
12126                mContext.getSystemService(Context.DROPBOX_SERVICE);
12127
12128        // Exit early if the dropbox isn't configured to accept this report type.
12129        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12130
12131        boolean bufferWasEmpty;
12132        boolean needsFlush;
12133        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12134        synchronized (sb) {
12135            bufferWasEmpty = sb.length() == 0;
12136            appendDropBoxProcessHeaders(process, processName, sb);
12137            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12138            sb.append("System-App: ").append(isSystemApp).append("\n");
12139            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12140            if (info.violationNumThisLoop != 0) {
12141                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12142            }
12143            if (info.numAnimationsRunning != 0) {
12144                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12145            }
12146            if (info.broadcastIntentAction != null) {
12147                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12148            }
12149            if (info.durationMillis != -1) {
12150                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12151            }
12152            if (info.numInstances != -1) {
12153                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12154            }
12155            if (info.tags != null) {
12156                for (String tag : info.tags) {
12157                    sb.append("Span-Tag: ").append(tag).append("\n");
12158                }
12159            }
12160            sb.append("\n");
12161            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
12162                sb.append(info.crashInfo.stackTrace);
12163                sb.append("\n");
12164            }
12165            if (info.message != null) {
12166                sb.append(info.message);
12167                sb.append("\n");
12168            }
12169
12170            // Only buffer up to ~64k.  Various logging bits truncate
12171            // things at 128k.
12172            needsFlush = (sb.length() > 64 * 1024);
12173        }
12174
12175        // Flush immediately if the buffer's grown too large, or this
12176        // is a non-system app.  Non-system apps are isolated with a
12177        // different tag & policy and not batched.
12178        //
12179        // Batching is useful during internal testing with
12180        // StrictMode settings turned up high.  Without batching,
12181        // thousands of separate files could be created on boot.
12182        if (!isSystemApp || needsFlush) {
12183            new Thread("Error dump: " + dropboxTag) {
12184                @Override
12185                public void run() {
12186                    String report;
12187                    synchronized (sb) {
12188                        report = sb.toString();
12189                        sb.delete(0, sb.length());
12190                        sb.trimToSize();
12191                    }
12192                    if (report.length() != 0) {
12193                        dbox.addText(dropboxTag, report);
12194                    }
12195                }
12196            }.start();
12197            return;
12198        }
12199
12200        // System app batching:
12201        if (!bufferWasEmpty) {
12202            // An existing dropbox-writing thread is outstanding, so
12203            // we don't need to start it up.  The existing thread will
12204            // catch the buffer appends we just did.
12205            return;
12206        }
12207
12208        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
12209        // (After this point, we shouldn't access AMS internal data structures.)
12210        new Thread("Error dump: " + dropboxTag) {
12211            @Override
12212            public void run() {
12213                // 5 second sleep to let stacks arrive and be batched together
12214                try {
12215                    Thread.sleep(5000);  // 5 seconds
12216                } catch (InterruptedException e) {}
12217
12218                String errorReport;
12219                synchronized (mStrictModeBuffer) {
12220                    errorReport = mStrictModeBuffer.toString();
12221                    if (errorReport.length() == 0) {
12222                        return;
12223                    }
12224                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
12225                    mStrictModeBuffer.trimToSize();
12226                }
12227                dbox.addText(dropboxTag, errorReport);
12228            }
12229        }.start();
12230    }
12231
12232    /**
12233     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
12234     * @param app object of the crashing app, null for the system server
12235     * @param tag reported by the caller
12236     * @param system whether this wtf is coming from the system
12237     * @param crashInfo describing the context of the error
12238     * @return true if the process should exit immediately (WTF is fatal)
12239     */
12240    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
12241            final ApplicationErrorReport.CrashInfo crashInfo) {
12242        final int callingUid = Binder.getCallingUid();
12243        final int callingPid = Binder.getCallingPid();
12244
12245        if (system) {
12246            // If this is coming from the system, we could very well have low-level
12247            // system locks held, so we want to do this all asynchronously.  And we
12248            // never want this to become fatal, so there is that too.
12249            mHandler.post(new Runnable() {
12250                @Override public void run() {
12251                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
12252                }
12253            });
12254            return false;
12255        }
12256
12257        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
12258                crashInfo);
12259
12260        if (r != null && r.pid != Process.myPid() &&
12261                Settings.Global.getInt(mContext.getContentResolver(),
12262                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
12263            crashApplication(r, crashInfo);
12264            return true;
12265        } else {
12266            return false;
12267        }
12268    }
12269
12270    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
12271            final ApplicationErrorReport.CrashInfo crashInfo) {
12272        final ProcessRecord r = findAppProcess(app, "WTF");
12273        final String processName = app == null ? "system_server"
12274                : (r == null ? "unknown" : r.processName);
12275
12276        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
12277                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
12278
12279        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
12280
12281        return r;
12282    }
12283
12284    /**
12285     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
12286     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
12287     */
12288    private ProcessRecord findAppProcess(IBinder app, String reason) {
12289        if (app == null) {
12290            return null;
12291        }
12292
12293        synchronized (this) {
12294            final int NP = mProcessNames.getMap().size();
12295            for (int ip=0; ip<NP; ip++) {
12296                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12297                final int NA = apps.size();
12298                for (int ia=0; ia<NA; ia++) {
12299                    ProcessRecord p = apps.valueAt(ia);
12300                    if (p.thread != null && p.thread.asBinder() == app) {
12301                        return p;
12302                    }
12303                }
12304            }
12305
12306            Slog.w(TAG, "Can't find mystery application for " + reason
12307                    + " from pid=" + Binder.getCallingPid()
12308                    + " uid=" + Binder.getCallingUid() + ": " + app);
12309            return null;
12310        }
12311    }
12312
12313    /**
12314     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
12315     * to append various headers to the dropbox log text.
12316     */
12317    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
12318            StringBuilder sb) {
12319        // Watchdog thread ends up invoking this function (with
12320        // a null ProcessRecord) to add the stack file to dropbox.
12321        // Do not acquire a lock on this (am) in such cases, as it
12322        // could cause a potential deadlock, if and when watchdog
12323        // is invoked due to unavailability of lock on am and it
12324        // would prevent watchdog from killing system_server.
12325        if (process == null) {
12326            sb.append("Process: ").append(processName).append("\n");
12327            return;
12328        }
12329        // Note: ProcessRecord 'process' is guarded by the service
12330        // instance.  (notably process.pkgList, which could otherwise change
12331        // concurrently during execution of this method)
12332        synchronized (this) {
12333            sb.append("Process: ").append(processName).append("\n");
12334            int flags = process.info.flags;
12335            IPackageManager pm = AppGlobals.getPackageManager();
12336            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
12337            for (int ip=0; ip<process.pkgList.size(); ip++) {
12338                String pkg = process.pkgList.keyAt(ip);
12339                sb.append("Package: ").append(pkg);
12340                try {
12341                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
12342                    if (pi != null) {
12343                        sb.append(" v").append(pi.versionCode);
12344                        if (pi.versionName != null) {
12345                            sb.append(" (").append(pi.versionName).append(")");
12346                        }
12347                    }
12348                } catch (RemoteException e) {
12349                    Slog.e(TAG, "Error getting package info: " + pkg, e);
12350                }
12351                sb.append("\n");
12352            }
12353        }
12354    }
12355
12356    private static String processClass(ProcessRecord process) {
12357        if (process == null || process.pid == MY_PID) {
12358            return "system_server";
12359        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
12360            return "system_app";
12361        } else {
12362            return "data_app";
12363        }
12364    }
12365
12366    /**
12367     * Write a description of an error (crash, WTF, ANR) to the drop box.
12368     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
12369     * @param process which caused the error, null means the system server
12370     * @param activity which triggered the error, null if unknown
12371     * @param parent activity related to the error, null if unknown
12372     * @param subject line related to the error, null if absent
12373     * @param report in long form describing the error, null if absent
12374     * @param logFile to include in the report, null if none
12375     * @param crashInfo giving an application stack trace, null if absent
12376     */
12377    public void addErrorToDropBox(String eventType,
12378            ProcessRecord process, String processName, ActivityRecord activity,
12379            ActivityRecord parent, String subject,
12380            final String report, final File logFile,
12381            final ApplicationErrorReport.CrashInfo crashInfo) {
12382        // NOTE -- this must never acquire the ActivityManagerService lock,
12383        // otherwise the watchdog may be prevented from resetting the system.
12384
12385        final String dropboxTag = processClass(process) + "_" + eventType;
12386        final DropBoxManager dbox = (DropBoxManager)
12387                mContext.getSystemService(Context.DROPBOX_SERVICE);
12388
12389        // Exit early if the dropbox isn't configured to accept this report type.
12390        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12391
12392        final StringBuilder sb = new StringBuilder(1024);
12393        appendDropBoxProcessHeaders(process, processName, sb);
12394        if (activity != null) {
12395            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
12396        }
12397        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
12398            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
12399        }
12400        if (parent != null && parent != activity) {
12401            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
12402        }
12403        if (subject != null) {
12404            sb.append("Subject: ").append(subject).append("\n");
12405        }
12406        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12407        if (Debug.isDebuggerConnected()) {
12408            sb.append("Debugger: Connected\n");
12409        }
12410        sb.append("\n");
12411
12412        // Do the rest in a worker thread to avoid blocking the caller on I/O
12413        // (After this point, we shouldn't access AMS internal data structures.)
12414        Thread worker = new Thread("Error dump: " + dropboxTag) {
12415            @Override
12416            public void run() {
12417                if (report != null) {
12418                    sb.append(report);
12419                }
12420                if (logFile != null) {
12421                    try {
12422                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
12423                                    "\n\n[[TRUNCATED]]"));
12424                    } catch (IOException e) {
12425                        Slog.e(TAG, "Error reading " + logFile, e);
12426                    }
12427                }
12428                if (crashInfo != null && crashInfo.stackTrace != null) {
12429                    sb.append(crashInfo.stackTrace);
12430                }
12431
12432                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
12433                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
12434                if (lines > 0) {
12435                    sb.append("\n");
12436
12437                    // Merge several logcat streams, and take the last N lines
12438                    InputStreamReader input = null;
12439                    try {
12440                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
12441                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
12442                                "-b", "crash",
12443                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
12444
12445                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
12446                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
12447                        input = new InputStreamReader(logcat.getInputStream());
12448
12449                        int num;
12450                        char[] buf = new char[8192];
12451                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
12452                    } catch (IOException e) {
12453                        Slog.e(TAG, "Error running logcat", e);
12454                    } finally {
12455                        if (input != null) try { input.close(); } catch (IOException e) {}
12456                    }
12457                }
12458
12459                dbox.addText(dropboxTag, sb.toString());
12460            }
12461        };
12462
12463        if (process == null) {
12464            // If process is null, we are being called from some internal code
12465            // and may be about to die -- run this synchronously.
12466            worker.run();
12467        } else {
12468            worker.start();
12469        }
12470    }
12471
12472    /**
12473     * Bring up the "unexpected error" dialog box for a crashing app.
12474     * Deal with edge cases (intercepts from instrumented applications,
12475     * ActivityController, error intent receivers, that sort of thing).
12476     * @param r the application crashing
12477     * @param crashInfo describing the failure
12478     */
12479    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12480        long timeMillis = System.currentTimeMillis();
12481        String shortMsg = crashInfo.exceptionClassName;
12482        String longMsg = crashInfo.exceptionMessage;
12483        String stackTrace = crashInfo.stackTrace;
12484        if (shortMsg != null && longMsg != null) {
12485            longMsg = shortMsg + ": " + longMsg;
12486        } else if (shortMsg != null) {
12487            longMsg = shortMsg;
12488        }
12489
12490        AppErrorResult result = new AppErrorResult();
12491        synchronized (this) {
12492            if (mController != null) {
12493                try {
12494                    String name = r != null ? r.processName : null;
12495                    int pid = r != null ? r.pid : Binder.getCallingPid();
12496                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
12497                    if (!mController.appCrashed(name, pid,
12498                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12499                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12500                                && "Native crash".equals(crashInfo.exceptionClassName)) {
12501                            Slog.w(TAG, "Skip killing native crashed app " + name
12502                                    + "(" + pid + ") during testing");
12503                        } else {
12504                            Slog.w(TAG, "Force-killing crashed app " + name
12505                                    + " at watcher's request");
12506                            if (r != null) {
12507                                r.kill("crash", true);
12508                            } else {
12509                                // Huh.
12510                                Process.killProcess(pid);
12511                                killProcessGroup(uid, pid);
12512                            }
12513                        }
12514                        return;
12515                    }
12516                } catch (RemoteException e) {
12517                    mController = null;
12518                    Watchdog.getInstance().setActivityController(null);
12519                }
12520            }
12521
12522            final long origId = Binder.clearCallingIdentity();
12523
12524            // If this process is running instrumentation, finish it.
12525            if (r != null && r.instrumentationClass != null) {
12526                Slog.w(TAG, "Error in app " + r.processName
12527                      + " running instrumentation " + r.instrumentationClass + ":");
12528                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12529                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12530                Bundle info = new Bundle();
12531                info.putString("shortMsg", shortMsg);
12532                info.putString("longMsg", longMsg);
12533                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12534                Binder.restoreCallingIdentity(origId);
12535                return;
12536            }
12537
12538            // Log crash in battery stats.
12539            if (r != null) {
12540                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12541            }
12542
12543            // If we can't identify the process or it's already exceeded its crash quota,
12544            // quit right away without showing a crash dialog.
12545            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12546                Binder.restoreCallingIdentity(origId);
12547                return;
12548            }
12549
12550            Message msg = Message.obtain();
12551            msg.what = SHOW_ERROR_MSG;
12552            HashMap data = new HashMap();
12553            data.put("result", result);
12554            data.put("app", r);
12555            msg.obj = data;
12556            mUiHandler.sendMessage(msg);
12557
12558            Binder.restoreCallingIdentity(origId);
12559        }
12560
12561        int res = result.get();
12562
12563        Intent appErrorIntent = null;
12564        synchronized (this) {
12565            if (r != null && !r.isolated) {
12566                // XXX Can't keep track of crash time for isolated processes,
12567                // since they don't have a persistent identity.
12568                mProcessCrashTimes.put(r.info.processName, r.uid,
12569                        SystemClock.uptimeMillis());
12570            }
12571            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12572                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12573            }
12574        }
12575
12576        if (appErrorIntent != null) {
12577            try {
12578                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12579            } catch (ActivityNotFoundException e) {
12580                Slog.w(TAG, "bug report receiver dissappeared", e);
12581            }
12582        }
12583    }
12584
12585    Intent createAppErrorIntentLocked(ProcessRecord r,
12586            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12587        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12588        if (report == null) {
12589            return null;
12590        }
12591        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12592        result.setComponent(r.errorReportReceiver);
12593        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12594        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12595        return result;
12596    }
12597
12598    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12599            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12600        if (r.errorReportReceiver == null) {
12601            return null;
12602        }
12603
12604        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12605            return null;
12606        }
12607
12608        ApplicationErrorReport report = new ApplicationErrorReport();
12609        report.packageName = r.info.packageName;
12610        report.installerPackageName = r.errorReportReceiver.getPackageName();
12611        report.processName = r.processName;
12612        report.time = timeMillis;
12613        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12614
12615        if (r.crashing || r.forceCrashReport) {
12616            report.type = ApplicationErrorReport.TYPE_CRASH;
12617            report.crashInfo = crashInfo;
12618        } else if (r.notResponding) {
12619            report.type = ApplicationErrorReport.TYPE_ANR;
12620            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12621
12622            report.anrInfo.activity = r.notRespondingReport.tag;
12623            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12624            report.anrInfo.info = r.notRespondingReport.longMsg;
12625        }
12626
12627        return report;
12628    }
12629
12630    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12631        enforceNotIsolatedCaller("getProcessesInErrorState");
12632        // assume our apps are happy - lazy create the list
12633        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12634
12635        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12636                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12637        int userId = UserHandle.getUserId(Binder.getCallingUid());
12638
12639        synchronized (this) {
12640
12641            // iterate across all processes
12642            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12643                ProcessRecord app = mLruProcesses.get(i);
12644                if (!allUsers && app.userId != userId) {
12645                    continue;
12646                }
12647                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12648                    // This one's in trouble, so we'll generate a report for it
12649                    // crashes are higher priority (in case there's a crash *and* an anr)
12650                    ActivityManager.ProcessErrorStateInfo report = null;
12651                    if (app.crashing) {
12652                        report = app.crashingReport;
12653                    } else if (app.notResponding) {
12654                        report = app.notRespondingReport;
12655                    }
12656
12657                    if (report != null) {
12658                        if (errList == null) {
12659                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12660                        }
12661                        errList.add(report);
12662                    } else {
12663                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12664                                " crashing = " + app.crashing +
12665                                " notResponding = " + app.notResponding);
12666                    }
12667                }
12668            }
12669        }
12670
12671        return errList;
12672    }
12673
12674    static int procStateToImportance(int procState, int memAdj,
12675            ActivityManager.RunningAppProcessInfo currApp) {
12676        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12677        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12678            currApp.lru = memAdj;
12679        } else {
12680            currApp.lru = 0;
12681        }
12682        return imp;
12683    }
12684
12685    private void fillInProcMemInfo(ProcessRecord app,
12686            ActivityManager.RunningAppProcessInfo outInfo) {
12687        outInfo.pid = app.pid;
12688        outInfo.uid = app.info.uid;
12689        if (mHeavyWeightProcess == app) {
12690            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12691        }
12692        if (app.persistent) {
12693            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12694        }
12695        if (app.activities.size() > 0) {
12696            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12697        }
12698        outInfo.lastTrimLevel = app.trimMemoryLevel;
12699        int adj = app.curAdj;
12700        int procState = app.curProcState;
12701        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12702        outInfo.importanceReasonCode = app.adjTypeCode;
12703        outInfo.processState = app.curProcState;
12704    }
12705
12706    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12707        enforceNotIsolatedCaller("getRunningAppProcesses");
12708
12709        final int callingUid = Binder.getCallingUid();
12710
12711        // Lazy instantiation of list
12712        List<ActivityManager.RunningAppProcessInfo> runList = null;
12713        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12714                callingUid) == PackageManager.PERMISSION_GRANTED;
12715        final int userId = UserHandle.getUserId(callingUid);
12716        final boolean allUids = isGetTasksAllowed(
12717                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
12718
12719        synchronized (this) {
12720            // Iterate across all processes
12721            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
12722                ProcessRecord app = mLruProcesses.get(i);
12723                if ((!allUsers && app.userId != userId)
12724                        || (!allUids && app.uid != callingUid)) {
12725                    continue;
12726                }
12727                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12728                    // Generate process state info for running application
12729                    ActivityManager.RunningAppProcessInfo currApp =
12730                        new ActivityManager.RunningAppProcessInfo(app.processName,
12731                                app.pid, app.getPackageList());
12732                    fillInProcMemInfo(app, currApp);
12733                    if (app.adjSource instanceof ProcessRecord) {
12734                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12735                        currApp.importanceReasonImportance =
12736                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12737                                        app.adjSourceProcState);
12738                    } else if (app.adjSource instanceof ActivityRecord) {
12739                        ActivityRecord r = (ActivityRecord)app.adjSource;
12740                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12741                    }
12742                    if (app.adjTarget instanceof ComponentName) {
12743                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12744                    }
12745                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12746                    //        + " lru=" + currApp.lru);
12747                    if (runList == null) {
12748                        runList = new ArrayList<>();
12749                    }
12750                    runList.add(currApp);
12751                }
12752            }
12753        }
12754        return runList;
12755    }
12756
12757    public List<ApplicationInfo> getRunningExternalApplications() {
12758        enforceNotIsolatedCaller("getRunningExternalApplications");
12759        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12760        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12761        if (runningApps != null && runningApps.size() > 0) {
12762            Set<String> extList = new HashSet<String>();
12763            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12764                if (app.pkgList != null) {
12765                    for (String pkg : app.pkgList) {
12766                        extList.add(pkg);
12767                    }
12768                }
12769            }
12770            IPackageManager pm = AppGlobals.getPackageManager();
12771            for (String pkg : extList) {
12772                try {
12773                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12774                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12775                        retList.add(info);
12776                    }
12777                } catch (RemoteException e) {
12778                }
12779            }
12780        }
12781        return retList;
12782    }
12783
12784    @Override
12785    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12786        enforceNotIsolatedCaller("getMyMemoryState");
12787        synchronized (this) {
12788            ProcessRecord proc;
12789            synchronized (mPidsSelfLocked) {
12790                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12791            }
12792            fillInProcMemInfo(proc, outInfo);
12793        }
12794    }
12795
12796    @Override
12797    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12798        if (checkCallingPermission(android.Manifest.permission.DUMP)
12799                != PackageManager.PERMISSION_GRANTED) {
12800            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12801                    + Binder.getCallingPid()
12802                    + ", uid=" + Binder.getCallingUid()
12803                    + " without permission "
12804                    + android.Manifest.permission.DUMP);
12805            return;
12806        }
12807
12808        boolean dumpAll = false;
12809        boolean dumpClient = false;
12810        String dumpPackage = null;
12811
12812        int opti = 0;
12813        while (opti < args.length) {
12814            String opt = args[opti];
12815            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12816                break;
12817            }
12818            opti++;
12819            if ("-a".equals(opt)) {
12820                dumpAll = true;
12821            } else if ("-c".equals(opt)) {
12822                dumpClient = true;
12823            } else if ("-p".equals(opt)) {
12824                if (opti < args.length) {
12825                    dumpPackage = args[opti];
12826                    opti++;
12827                } else {
12828                    pw.println("Error: -p option requires package argument");
12829                    return;
12830                }
12831                dumpClient = true;
12832            } else if ("-h".equals(opt)) {
12833                pw.println("Activity manager dump options:");
12834                pw.println("  [-a] [-c] [-p package] [-h] [cmd] ...");
12835                pw.println("  cmd may be one of:");
12836                pw.println("    a[ctivities]: activity stack state");
12837                pw.println("    r[recents]: recent activities state");
12838                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12839                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12840                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12841                pw.println("    o[om]: out of memory management");
12842                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12843                pw.println("    provider [COMP_SPEC]: provider client-side state");
12844                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12845                pw.println("    as[sociations]: tracked app associations");
12846                pw.println("    service [COMP_SPEC]: service client-side state");
12847                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12848                pw.println("    all: dump all activities");
12849                pw.println("    top: dump the top activity");
12850                pw.println("    write: write all pending state to storage");
12851                pw.println("    track-associations: enable association tracking");
12852                pw.println("    untrack-associations: disable and clear association tracking");
12853                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12854                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12855                pw.println("    a partial substring in a component name, a");
12856                pw.println("    hex object identifier.");
12857                pw.println("  -a: include all available server state.");
12858                pw.println("  -c: include client state.");
12859                pw.println("  -p: limit output to given package.");
12860                return;
12861            } else {
12862                pw.println("Unknown argument: " + opt + "; use -h for help");
12863            }
12864        }
12865
12866        long origId = Binder.clearCallingIdentity();
12867        boolean more = false;
12868        // Is the caller requesting to dump a particular piece of data?
12869        if (opti < args.length) {
12870            String cmd = args[opti];
12871            opti++;
12872            if ("activities".equals(cmd) || "a".equals(cmd)) {
12873                synchronized (this) {
12874                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12875                }
12876            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12877                synchronized (this) {
12878                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
12879                }
12880            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12881                String[] newArgs;
12882                String name;
12883                if (opti >= args.length) {
12884                    name = null;
12885                    newArgs = EMPTY_STRING_ARRAY;
12886                } else {
12887                    dumpPackage = args[opti];
12888                    opti++;
12889                    newArgs = new String[args.length - opti];
12890                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12891                            args.length - opti);
12892                }
12893                synchronized (this) {
12894                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
12895                }
12896            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12897                String[] newArgs;
12898                String name;
12899                if (opti >= args.length) {
12900                    name = null;
12901                    newArgs = EMPTY_STRING_ARRAY;
12902                } else {
12903                    dumpPackage = args[opti];
12904                    opti++;
12905                    newArgs = new String[args.length - opti];
12906                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12907                            args.length - opti);
12908                }
12909                synchronized (this) {
12910                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
12911                }
12912            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12913                String[] newArgs;
12914                String name;
12915                if (opti >= args.length) {
12916                    name = null;
12917                    newArgs = EMPTY_STRING_ARRAY;
12918                } else {
12919                    dumpPackage = args[opti];
12920                    opti++;
12921                    newArgs = new String[args.length - opti];
12922                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12923                            args.length - opti);
12924                }
12925                synchronized (this) {
12926                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
12927                }
12928            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12929                synchronized (this) {
12930                    dumpOomLocked(fd, pw, args, opti, true);
12931                }
12932            } else if ("provider".equals(cmd)) {
12933                String[] newArgs;
12934                String name;
12935                if (opti >= args.length) {
12936                    name = null;
12937                    newArgs = EMPTY_STRING_ARRAY;
12938                } else {
12939                    name = args[opti];
12940                    opti++;
12941                    newArgs = new String[args.length - opti];
12942                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12943                }
12944                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12945                    pw.println("No providers match: " + name);
12946                    pw.println("Use -h for help.");
12947                }
12948            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12949                synchronized (this) {
12950                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12951                }
12952            } else if ("service".equals(cmd)) {
12953                String[] newArgs;
12954                String name;
12955                if (opti >= args.length) {
12956                    name = null;
12957                    newArgs = EMPTY_STRING_ARRAY;
12958                } else {
12959                    name = args[opti];
12960                    opti++;
12961                    newArgs = new String[args.length - opti];
12962                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12963                            args.length - opti);
12964                }
12965                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12966                    pw.println("No services match: " + name);
12967                    pw.println("Use -h for help.");
12968                }
12969            } else if ("package".equals(cmd)) {
12970                String[] newArgs;
12971                if (opti >= args.length) {
12972                    pw.println("package: no package name specified");
12973                    pw.println("Use -h for help.");
12974                } else {
12975                    dumpPackage = args[opti];
12976                    opti++;
12977                    newArgs = new String[args.length - opti];
12978                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12979                            args.length - opti);
12980                    args = newArgs;
12981                    opti = 0;
12982                    more = true;
12983                }
12984            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
12985                synchronized (this) {
12986                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12987                }
12988            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12989                synchronized (this) {
12990                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12991                }
12992            } else if ("write".equals(cmd)) {
12993                mTaskPersister.flush();
12994                pw.println("All tasks persisted.");
12995                return;
12996            } else if ("track-associations".equals(cmd)) {
12997                synchronized (this) {
12998                    if (!mTrackingAssociations) {
12999                        mTrackingAssociations = true;
13000                        pw.println("Association tracking started.");
13001                    } else {
13002                        pw.println("Association tracking already enabled.");
13003                    }
13004                }
13005                return;
13006            } else if ("untrack-associations".equals(cmd)) {
13007                synchronized (this) {
13008                    if (mTrackingAssociations) {
13009                        mTrackingAssociations = false;
13010                        mAssociations.clear();
13011                        pw.println("Association tracking stopped.");
13012                    } else {
13013                        pw.println("Association tracking not running.");
13014                    }
13015                }
13016                return;
13017            } else {
13018                // Dumping a single activity?
13019                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13020                    pw.println("Bad activity command, or no activities match: " + cmd);
13021                    pw.println("Use -h for help.");
13022                }
13023            }
13024            if (!more) {
13025                Binder.restoreCallingIdentity(origId);
13026                return;
13027            }
13028        }
13029
13030        // No piece of data specified, dump everything.
13031        synchronized (this) {
13032            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13033            pw.println();
13034            if (dumpAll) {
13035                pw.println("-------------------------------------------------------------------------------");
13036            }
13037            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13038            pw.println();
13039            if (dumpAll) {
13040                pw.println("-------------------------------------------------------------------------------");
13041            }
13042            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13043            pw.println();
13044            if (dumpAll) {
13045                pw.println("-------------------------------------------------------------------------------");
13046            }
13047            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13048            pw.println();
13049            if (dumpAll) {
13050                pw.println("-------------------------------------------------------------------------------");
13051            }
13052            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13053            pw.println();
13054            if (dumpAll) {
13055                pw.println("-------------------------------------------------------------------------------");
13056            }
13057            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13058            if (mAssociations.size() > 0) {
13059                pw.println();
13060                if (dumpAll) {
13061                    pw.println("-------------------------------------------------------------------------------");
13062                }
13063                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13064            }
13065            pw.println();
13066            if (dumpAll) {
13067                pw.println("-------------------------------------------------------------------------------");
13068            }
13069            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13070        }
13071        Binder.restoreCallingIdentity(origId);
13072    }
13073
13074    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13075            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13076        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13077
13078        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13079                dumpPackage);
13080        boolean needSep = printedAnything;
13081
13082        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13083                dumpPackage, needSep, "  mFocusedActivity: ");
13084        if (printed) {
13085            printedAnything = true;
13086            needSep = false;
13087        }
13088
13089        if (dumpPackage == null) {
13090            if (needSep) {
13091                pw.println();
13092            }
13093            needSep = true;
13094            printedAnything = true;
13095            mStackSupervisor.dump(pw, "  ");
13096        }
13097
13098        if (!printedAnything) {
13099            pw.println("  (nothing)");
13100        }
13101    }
13102
13103    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13104            int opti, boolean dumpAll, String dumpPackage) {
13105        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13106
13107        boolean printedAnything = false;
13108
13109        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13110            boolean printedHeader = false;
13111
13112            final int N = mRecentTasks.size();
13113            for (int i=0; i<N; i++) {
13114                TaskRecord tr = mRecentTasks.get(i);
13115                if (dumpPackage != null) {
13116                    if (tr.realActivity == null ||
13117                            !dumpPackage.equals(tr.realActivity)) {
13118                        continue;
13119                    }
13120                }
13121                if (!printedHeader) {
13122                    pw.println("  Recent tasks:");
13123                    printedHeader = true;
13124                    printedAnything = true;
13125                }
13126                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13127                        pw.println(tr);
13128                if (dumpAll) {
13129                    mRecentTasks.get(i).dump(pw, "    ");
13130                }
13131            }
13132        }
13133
13134        if (!printedAnything) {
13135            pw.println("  (nothing)");
13136        }
13137    }
13138
13139    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13140            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13141        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13142
13143        int dumpUid = 0;
13144        if (dumpPackage != null) {
13145            IPackageManager pm = AppGlobals.getPackageManager();
13146            try {
13147                dumpUid = pm.getPackageUid(dumpPackage, 0);
13148            } catch (RemoteException e) {
13149            }
13150        }
13151
13152        boolean printedAnything = false;
13153
13154        final long now = SystemClock.uptimeMillis();
13155
13156        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13157            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13158                    = mAssociations.valueAt(i1);
13159            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13160                SparseArray<ArrayMap<String, Association>> sourceUids
13161                        = targetComponents.valueAt(i2);
13162                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13163                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13164                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13165                        Association ass = sourceProcesses.valueAt(i4);
13166                        if (dumpPackage != null) {
13167                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13168                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13169                                continue;
13170                            }
13171                        }
13172                        printedAnything = true;
13173                        pw.print("  ");
13174                        pw.print(ass.mTargetProcess);
13175                        pw.print("/");
13176                        UserHandle.formatUid(pw, ass.mTargetUid);
13177                        pw.print(" <- ");
13178                        pw.print(ass.mSourceProcess);
13179                        pw.print("/");
13180                        UserHandle.formatUid(pw, ass.mSourceUid);
13181                        pw.println();
13182                        pw.print("    via ");
13183                        pw.print(ass.mTargetComponent.flattenToShortString());
13184                        pw.println();
13185                        pw.print("    ");
13186                        long dur = ass.mTime;
13187                        if (ass.mNesting > 0) {
13188                            dur += now - ass.mStartTime;
13189                        }
13190                        TimeUtils.formatDuration(dur, pw);
13191                        pw.print(" (");
13192                        pw.print(ass.mCount);
13193                        pw.println(" times)");
13194                        if (ass.mNesting > 0) {
13195                            pw.print("    ");
13196                            pw.print(" Currently active: ");
13197                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13198                            pw.println();
13199                        }
13200                    }
13201                }
13202            }
13203
13204        }
13205
13206        if (!printedAnything) {
13207            pw.println("  (nothing)");
13208        }
13209    }
13210
13211    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13212            int opti, boolean dumpAll, String dumpPackage) {
13213        boolean needSep = false;
13214        boolean printedAnything = false;
13215        int numPers = 0;
13216
13217        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13218
13219        if (dumpAll) {
13220            final int NP = mProcessNames.getMap().size();
13221            for (int ip=0; ip<NP; ip++) {
13222                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13223                final int NA = procs.size();
13224                for (int ia=0; ia<NA; ia++) {
13225                    ProcessRecord r = procs.valueAt(ia);
13226                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13227                        continue;
13228                    }
13229                    if (!needSep) {
13230                        pw.println("  All known processes:");
13231                        needSep = true;
13232                        printedAnything = true;
13233                    }
13234                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13235                        pw.print(" UID "); pw.print(procs.keyAt(ia));
13236                        pw.print(" "); pw.println(r);
13237                    r.dump(pw, "    ");
13238                    if (r.persistent) {
13239                        numPers++;
13240                    }
13241                }
13242            }
13243        }
13244
13245        if (mIsolatedProcesses.size() > 0) {
13246            boolean printed = false;
13247            for (int i=0; i<mIsolatedProcesses.size(); i++) {
13248                ProcessRecord r = mIsolatedProcesses.valueAt(i);
13249                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13250                    continue;
13251                }
13252                if (!printed) {
13253                    if (needSep) {
13254                        pw.println();
13255                    }
13256                    pw.println("  Isolated process list (sorted by uid):");
13257                    printedAnything = true;
13258                    printed = true;
13259                    needSep = true;
13260                }
13261                pw.println(String.format("%sIsolated #%2d: %s",
13262                        "    ", i, r.toString()));
13263            }
13264        }
13265
13266        if (mActiveUids.size() > 0) {
13267            if (needSep) {
13268                pw.println();
13269            }
13270            pw.println("  UID states:");
13271            for (int i=0; i<mActiveUids.size(); i++) {
13272                UidRecord uidRec = mActiveUids.valueAt(i);
13273                pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13274                pw.print(": "); pw.println(uidRec);
13275            }
13276            needSep = true;
13277            printedAnything = true;
13278        }
13279
13280        if (mLruProcesses.size() > 0) {
13281            if (needSep) {
13282                pw.println();
13283            }
13284            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
13285                    pw.print(" total, non-act at ");
13286                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13287                    pw.print(", non-svc at ");
13288                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13289                    pw.println("):");
13290            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
13291            needSep = true;
13292            printedAnything = true;
13293        }
13294
13295        if (dumpAll || dumpPackage != null) {
13296            synchronized (mPidsSelfLocked) {
13297                boolean printed = false;
13298                for (int i=0; i<mPidsSelfLocked.size(); i++) {
13299                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
13300                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13301                        continue;
13302                    }
13303                    if (!printed) {
13304                        if (needSep) pw.println();
13305                        needSep = true;
13306                        pw.println("  PID mappings:");
13307                        printed = true;
13308                        printedAnything = true;
13309                    }
13310                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
13311                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
13312                }
13313            }
13314        }
13315
13316        if (mForegroundProcesses.size() > 0) {
13317            synchronized (mPidsSelfLocked) {
13318                boolean printed = false;
13319                for (int i=0; i<mForegroundProcesses.size(); i++) {
13320                    ProcessRecord r = mPidsSelfLocked.get(
13321                            mForegroundProcesses.valueAt(i).pid);
13322                    if (dumpPackage != null && (r == null
13323                            || !r.pkgList.containsKey(dumpPackage))) {
13324                        continue;
13325                    }
13326                    if (!printed) {
13327                        if (needSep) pw.println();
13328                        needSep = true;
13329                        pw.println("  Foreground Processes:");
13330                        printed = true;
13331                        printedAnything = true;
13332                    }
13333                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
13334                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
13335                }
13336            }
13337        }
13338
13339        if (mPersistentStartingProcesses.size() > 0) {
13340            if (needSep) pw.println();
13341            needSep = true;
13342            printedAnything = true;
13343            pw.println("  Persisent processes that are starting:");
13344            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
13345                    "Starting Norm", "Restarting PERS", dumpPackage);
13346        }
13347
13348        if (mRemovedProcesses.size() > 0) {
13349            if (needSep) pw.println();
13350            needSep = true;
13351            printedAnything = true;
13352            pw.println("  Processes that are being removed:");
13353            dumpProcessList(pw, this, mRemovedProcesses, "    ",
13354                    "Removed Norm", "Removed PERS", dumpPackage);
13355        }
13356
13357        if (mProcessesOnHold.size() > 0) {
13358            if (needSep) pw.println();
13359            needSep = true;
13360            printedAnything = true;
13361            pw.println("  Processes that are on old until the system is ready:");
13362            dumpProcessList(pw, this, mProcessesOnHold, "    ",
13363                    "OnHold Norm", "OnHold PERS", dumpPackage);
13364        }
13365
13366        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
13367
13368        if (mProcessCrashTimes.getMap().size() > 0) {
13369            boolean printed = false;
13370            long now = SystemClock.uptimeMillis();
13371            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
13372            final int NP = pmap.size();
13373            for (int ip=0; ip<NP; ip++) {
13374                String pname = pmap.keyAt(ip);
13375                SparseArray<Long> uids = pmap.valueAt(ip);
13376                final int N = uids.size();
13377                for (int i=0; i<N; i++) {
13378                    int puid = uids.keyAt(i);
13379                    ProcessRecord r = mProcessNames.get(pname, puid);
13380                    if (dumpPackage != null && (r == null
13381                            || !r.pkgList.containsKey(dumpPackage))) {
13382                        continue;
13383                    }
13384                    if (!printed) {
13385                        if (needSep) pw.println();
13386                        needSep = true;
13387                        pw.println("  Time since processes crashed:");
13388                        printed = true;
13389                        printedAnything = true;
13390                    }
13391                    pw.print("    Process "); pw.print(pname);
13392                            pw.print(" uid "); pw.print(puid);
13393                            pw.print(": last crashed ");
13394                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
13395                            pw.println(" ago");
13396                }
13397            }
13398        }
13399
13400        if (mBadProcesses.getMap().size() > 0) {
13401            boolean printed = false;
13402            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
13403            final int NP = pmap.size();
13404            for (int ip=0; ip<NP; ip++) {
13405                String pname = pmap.keyAt(ip);
13406                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
13407                final int N = uids.size();
13408                for (int i=0; i<N; i++) {
13409                    int puid = uids.keyAt(i);
13410                    ProcessRecord r = mProcessNames.get(pname, puid);
13411                    if (dumpPackage != null && (r == null
13412                            || !r.pkgList.containsKey(dumpPackage))) {
13413                        continue;
13414                    }
13415                    if (!printed) {
13416                        if (needSep) pw.println();
13417                        needSep = true;
13418                        pw.println("  Bad processes:");
13419                        printedAnything = true;
13420                    }
13421                    BadProcessInfo info = uids.valueAt(i);
13422                    pw.print("    Bad process "); pw.print(pname);
13423                            pw.print(" uid "); pw.print(puid);
13424                            pw.print(": crashed at time "); pw.println(info.time);
13425                    if (info.shortMsg != null) {
13426                        pw.print("      Short msg: "); pw.println(info.shortMsg);
13427                    }
13428                    if (info.longMsg != null) {
13429                        pw.print("      Long msg: "); pw.println(info.longMsg);
13430                    }
13431                    if (info.stack != null) {
13432                        pw.println("      Stack:");
13433                        int lastPos = 0;
13434                        for (int pos=0; pos<info.stack.length(); pos++) {
13435                            if (info.stack.charAt(pos) == '\n') {
13436                                pw.print("        ");
13437                                pw.write(info.stack, lastPos, pos-lastPos);
13438                                pw.println();
13439                                lastPos = pos+1;
13440                            }
13441                        }
13442                        if (lastPos < info.stack.length()) {
13443                            pw.print("        ");
13444                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
13445                            pw.println();
13446                        }
13447                    }
13448                }
13449            }
13450        }
13451
13452        if (dumpPackage == null) {
13453            pw.println();
13454            needSep = false;
13455            pw.println("  mStartedUsers:");
13456            for (int i=0; i<mStartedUsers.size(); i++) {
13457                UserState uss = mStartedUsers.valueAt(i);
13458                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
13459                        pw.print(": "); uss.dump("", pw);
13460            }
13461            pw.print("  mStartedUserArray: [");
13462            for (int i=0; i<mStartedUserArray.length; i++) {
13463                if (i > 0) pw.print(", ");
13464                pw.print(mStartedUserArray[i]);
13465            }
13466            pw.println("]");
13467            pw.print("  mUserLru: [");
13468            for (int i=0; i<mUserLru.size(); i++) {
13469                if (i > 0) pw.print(", ");
13470                pw.print(mUserLru.get(i));
13471            }
13472            pw.println("]");
13473            if (dumpAll) {
13474                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
13475            }
13476            synchronized (mUserProfileGroupIdsSelfLocked) {
13477                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
13478                    pw.println("  mUserProfileGroupIds:");
13479                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
13480                        pw.print("    User #");
13481                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
13482                        pw.print(" -> profile #");
13483                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
13484                    }
13485                }
13486            }
13487        }
13488        if (mHomeProcess != null && (dumpPackage == null
13489                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13490            if (needSep) {
13491                pw.println();
13492                needSep = false;
13493            }
13494            pw.println("  mHomeProcess: " + mHomeProcess);
13495        }
13496        if (mPreviousProcess != null && (dumpPackage == null
13497                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13498            if (needSep) {
13499                pw.println();
13500                needSep = false;
13501            }
13502            pw.println("  mPreviousProcess: " + mPreviousProcess);
13503        }
13504        if (dumpAll) {
13505            StringBuilder sb = new StringBuilder(128);
13506            sb.append("  mPreviousProcessVisibleTime: ");
13507            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13508            pw.println(sb);
13509        }
13510        if (mHeavyWeightProcess != null && (dumpPackage == null
13511                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13512            if (needSep) {
13513                pw.println();
13514                needSep = false;
13515            }
13516            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13517        }
13518        if (dumpPackage == null) {
13519            pw.println("  mConfiguration: " + mConfiguration);
13520        }
13521        if (dumpAll) {
13522            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13523            if (mCompatModePackages.getPackages().size() > 0) {
13524                boolean printed = false;
13525                for (Map.Entry<String, Integer> entry
13526                        : mCompatModePackages.getPackages().entrySet()) {
13527                    String pkg = entry.getKey();
13528                    int mode = entry.getValue();
13529                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
13530                        continue;
13531                    }
13532                    if (!printed) {
13533                        pw.println("  mScreenCompatPackages:");
13534                        printed = true;
13535                    }
13536                    pw.print("    "); pw.print(pkg); pw.print(": ");
13537                            pw.print(mode); pw.println();
13538                }
13539            }
13540        }
13541        if (dumpPackage == null) {
13542            pw.println("  mWakefulness="
13543                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
13544            pw.println("  mSleepTokens=" + mSleepTokens);
13545            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
13546                    + lockScreenShownToString());
13547            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
13548            if (mRunningVoice != null) {
13549                pw.println("  mRunningVoice=" + mRunningVoice);
13550                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
13551            }
13552        }
13553        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
13554                || mOrigWaitForDebugger) {
13555            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
13556                    || dumpPackage.equals(mOrigDebugApp)) {
13557                if (needSep) {
13558                    pw.println();
13559                    needSep = false;
13560                }
13561                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
13562                        + " mDebugTransient=" + mDebugTransient
13563                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
13564            }
13565        }
13566        if (mCurAppTimeTracker != null) {
13567            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
13568        }
13569        if (mMemWatchProcesses.getMap().size() > 0) {
13570            pw.println("  Mem watch processes:");
13571            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
13572                    = mMemWatchProcesses.getMap();
13573            for (int i=0; i<procs.size(); i++) {
13574                final String proc = procs.keyAt(i);
13575                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
13576                for (int j=0; j<uids.size(); j++) {
13577                    if (needSep) {
13578                        pw.println();
13579                        needSep = false;
13580                    }
13581                    StringBuilder sb = new StringBuilder();
13582                    sb.append("    ").append(proc).append('/');
13583                    UserHandle.formatUid(sb, uids.keyAt(j));
13584                    Pair<Long, String> val = uids.valueAt(j);
13585                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
13586                    if (val.second != null) {
13587                        sb.append(", report to ").append(val.second);
13588                    }
13589                    pw.println(sb.toString());
13590                }
13591            }
13592            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
13593            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
13594            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
13595                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
13596        }
13597        if (mOpenGlTraceApp != null) {
13598            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
13599                if (needSep) {
13600                    pw.println();
13601                    needSep = false;
13602                }
13603                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
13604            }
13605        }
13606        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
13607                || mProfileFd != null) {
13608            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13609                if (needSep) {
13610                    pw.println();
13611                    needSep = false;
13612                }
13613                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13614                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13615                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13616                        + mAutoStopProfiler);
13617                pw.println("  mProfileType=" + mProfileType);
13618            }
13619        }
13620        if (dumpPackage == null) {
13621            if (mAlwaysFinishActivities || mController != null) {
13622                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
13623                        + " mController=" + mController);
13624            }
13625            if (dumpAll) {
13626                pw.println("  Total persistent processes: " + numPers);
13627                pw.println("  mProcessesReady=" + mProcessesReady
13628                        + " mSystemReady=" + mSystemReady
13629                        + " mBooted=" + mBooted
13630                        + " mFactoryTest=" + mFactoryTest);
13631                pw.println("  mBooting=" + mBooting
13632                        + " mCallFinishBooting=" + mCallFinishBooting
13633                        + " mBootAnimationComplete=" + mBootAnimationComplete);
13634                pw.print("  mLastPowerCheckRealtime=");
13635                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13636                        pw.println("");
13637                pw.print("  mLastPowerCheckUptime=");
13638                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13639                        pw.println("");
13640                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13641                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13642                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13643                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
13644                        + " (" + mLruProcesses.size() + " total)"
13645                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13646                        + " mNumServiceProcs=" + mNumServiceProcs
13647                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13648                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
13649                        + " mLastMemoryLevel" + mLastMemoryLevel
13650                        + " mLastNumProcesses" + mLastNumProcesses);
13651                long now = SystemClock.uptimeMillis();
13652                pw.print("  mLastIdleTime=");
13653                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
13654                        pw.print(" mLowRamSinceLastIdle=");
13655                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13656                        pw.println();
13657            }
13658        }
13659
13660        if (!printedAnything) {
13661            pw.println("  (nothing)");
13662        }
13663    }
13664
13665    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13666            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13667        if (mProcessesToGc.size() > 0) {
13668            boolean printed = false;
13669            long now = SystemClock.uptimeMillis();
13670            for (int i=0; i<mProcessesToGc.size(); i++) {
13671                ProcessRecord proc = mProcessesToGc.get(i);
13672                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13673                    continue;
13674                }
13675                if (!printed) {
13676                    if (needSep) pw.println();
13677                    needSep = true;
13678                    pw.println("  Processes that are waiting to GC:");
13679                    printed = true;
13680                }
13681                pw.print("    Process "); pw.println(proc);
13682                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13683                        pw.print(", last gced=");
13684                        pw.print(now-proc.lastRequestedGc);
13685                        pw.print(" ms ago, last lowMem=");
13686                        pw.print(now-proc.lastLowMemory);
13687                        pw.println(" ms ago");
13688
13689            }
13690        }
13691        return needSep;
13692    }
13693
13694    void printOomLevel(PrintWriter pw, String name, int adj) {
13695        pw.print("    ");
13696        if (adj >= 0) {
13697            pw.print(' ');
13698            if (adj < 10) pw.print(' ');
13699        } else {
13700            if (adj > -10) pw.print(' ');
13701        }
13702        pw.print(adj);
13703        pw.print(": ");
13704        pw.print(name);
13705        pw.print(" (");
13706        pw.print(mProcessList.getMemLevel(adj)/1024);
13707        pw.println(" kB)");
13708    }
13709
13710    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13711            int opti, boolean dumpAll) {
13712        boolean needSep = false;
13713
13714        if (mLruProcesses.size() > 0) {
13715            if (needSep) pw.println();
13716            needSep = true;
13717            pw.println("  OOM levels:");
13718            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13719            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13720            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13721            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13722            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13723            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13724            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13725            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13726            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13727            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13728            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13729            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13730            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13731            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13732
13733            if (needSep) pw.println();
13734            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13735                    pw.print(" total, non-act at ");
13736                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13737                    pw.print(", non-svc at ");
13738                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13739                    pw.println("):");
13740            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13741            needSep = true;
13742        }
13743
13744        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13745
13746        pw.println();
13747        pw.println("  mHomeProcess: " + mHomeProcess);
13748        pw.println("  mPreviousProcess: " + mPreviousProcess);
13749        if (mHeavyWeightProcess != null) {
13750            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13751        }
13752
13753        return true;
13754    }
13755
13756    /**
13757     * There are three ways to call this:
13758     *  - no provider specified: dump all the providers
13759     *  - a flattened component name that matched an existing provider was specified as the
13760     *    first arg: dump that one provider
13761     *  - the first arg isn't the flattened component name of an existing provider:
13762     *    dump all providers whose component contains the first arg as a substring
13763     */
13764    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13765            int opti, boolean dumpAll) {
13766        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13767    }
13768
13769    static class ItemMatcher {
13770        ArrayList<ComponentName> components;
13771        ArrayList<String> strings;
13772        ArrayList<Integer> objects;
13773        boolean all;
13774
13775        ItemMatcher() {
13776            all = true;
13777        }
13778
13779        void build(String name) {
13780            ComponentName componentName = ComponentName.unflattenFromString(name);
13781            if (componentName != null) {
13782                if (components == null) {
13783                    components = new ArrayList<ComponentName>();
13784                }
13785                components.add(componentName);
13786                all = false;
13787            } else {
13788                int objectId = 0;
13789                // Not a '/' separated full component name; maybe an object ID?
13790                try {
13791                    objectId = Integer.parseInt(name, 16);
13792                    if (objects == null) {
13793                        objects = new ArrayList<Integer>();
13794                    }
13795                    objects.add(objectId);
13796                    all = false;
13797                } catch (RuntimeException e) {
13798                    // Not an integer; just do string match.
13799                    if (strings == null) {
13800                        strings = new ArrayList<String>();
13801                    }
13802                    strings.add(name);
13803                    all = false;
13804                }
13805            }
13806        }
13807
13808        int build(String[] args, int opti) {
13809            for (; opti<args.length; opti++) {
13810                String name = args[opti];
13811                if ("--".equals(name)) {
13812                    return opti+1;
13813                }
13814                build(name);
13815            }
13816            return opti;
13817        }
13818
13819        boolean match(Object object, ComponentName comp) {
13820            if (all) {
13821                return true;
13822            }
13823            if (components != null) {
13824                for (int i=0; i<components.size(); i++) {
13825                    if (components.get(i).equals(comp)) {
13826                        return true;
13827                    }
13828                }
13829            }
13830            if (objects != null) {
13831                for (int i=0; i<objects.size(); i++) {
13832                    if (System.identityHashCode(object) == objects.get(i)) {
13833                        return true;
13834                    }
13835                }
13836            }
13837            if (strings != null) {
13838                String flat = comp.flattenToString();
13839                for (int i=0; i<strings.size(); i++) {
13840                    if (flat.contains(strings.get(i))) {
13841                        return true;
13842                    }
13843                }
13844            }
13845            return false;
13846        }
13847    }
13848
13849    /**
13850     * There are three things that cmd can be:
13851     *  - a flattened component name that matches an existing activity
13852     *  - the cmd arg isn't the flattened component name of an existing activity:
13853     *    dump all activity whose component contains the cmd as a substring
13854     *  - A hex number of the ActivityRecord object instance.
13855     */
13856    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13857            int opti, boolean dumpAll) {
13858        ArrayList<ActivityRecord> activities;
13859
13860        synchronized (this) {
13861            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13862        }
13863
13864        if (activities.size() <= 0) {
13865            return false;
13866        }
13867
13868        String[] newArgs = new String[args.length - opti];
13869        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13870
13871        TaskRecord lastTask = null;
13872        boolean needSep = false;
13873        for (int i=activities.size()-1; i>=0; i--) {
13874            ActivityRecord r = activities.get(i);
13875            if (needSep) {
13876                pw.println();
13877            }
13878            needSep = true;
13879            synchronized (this) {
13880                if (lastTask != r.task) {
13881                    lastTask = r.task;
13882                    pw.print("TASK "); pw.print(lastTask.affinity);
13883                            pw.print(" id="); pw.println(lastTask.taskId);
13884                    if (dumpAll) {
13885                        lastTask.dump(pw, "  ");
13886                    }
13887                }
13888            }
13889            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13890        }
13891        return true;
13892    }
13893
13894    /**
13895     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13896     * there is a thread associated with the activity.
13897     */
13898    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13899            final ActivityRecord r, String[] args, boolean dumpAll) {
13900        String innerPrefix = prefix + "  ";
13901        synchronized (this) {
13902            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13903                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13904                    pw.print(" pid=");
13905                    if (r.app != null) pw.println(r.app.pid);
13906                    else pw.println("(not running)");
13907            if (dumpAll) {
13908                r.dump(pw, innerPrefix);
13909            }
13910        }
13911        if (r.app != null && r.app.thread != null) {
13912            // flush anything that is already in the PrintWriter since the thread is going
13913            // to write to the file descriptor directly
13914            pw.flush();
13915            try {
13916                TransferPipe tp = new TransferPipe();
13917                try {
13918                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13919                            r.appToken, innerPrefix, args);
13920                    tp.go(fd);
13921                } finally {
13922                    tp.kill();
13923                }
13924            } catch (IOException e) {
13925                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13926            } catch (RemoteException e) {
13927                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13928            }
13929        }
13930    }
13931
13932    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13933            int opti, boolean dumpAll, String dumpPackage) {
13934        boolean needSep = false;
13935        boolean onlyHistory = false;
13936        boolean printedAnything = false;
13937
13938        if ("history".equals(dumpPackage)) {
13939            if (opti < args.length && "-s".equals(args[opti])) {
13940                dumpAll = false;
13941            }
13942            onlyHistory = true;
13943            dumpPackage = null;
13944        }
13945
13946        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13947        if (!onlyHistory && dumpAll) {
13948            if (mRegisteredReceivers.size() > 0) {
13949                boolean printed = false;
13950                Iterator it = mRegisteredReceivers.values().iterator();
13951                while (it.hasNext()) {
13952                    ReceiverList r = (ReceiverList)it.next();
13953                    if (dumpPackage != null && (r.app == null ||
13954                            !dumpPackage.equals(r.app.info.packageName))) {
13955                        continue;
13956                    }
13957                    if (!printed) {
13958                        pw.println("  Registered Receivers:");
13959                        needSep = true;
13960                        printed = true;
13961                        printedAnything = true;
13962                    }
13963                    pw.print("  * "); pw.println(r);
13964                    r.dump(pw, "    ");
13965                }
13966            }
13967
13968            if (mReceiverResolver.dump(pw, needSep ?
13969                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13970                    "    ", dumpPackage, false, false)) {
13971                needSep = true;
13972                printedAnything = true;
13973            }
13974        }
13975
13976        for (BroadcastQueue q : mBroadcastQueues) {
13977            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13978            printedAnything |= needSep;
13979        }
13980
13981        needSep = true;
13982
13983        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13984            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13985                if (needSep) {
13986                    pw.println();
13987                }
13988                needSep = true;
13989                printedAnything = true;
13990                pw.print("  Sticky broadcasts for user ");
13991                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13992                StringBuilder sb = new StringBuilder(128);
13993                for (Map.Entry<String, ArrayList<Intent>> ent
13994                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13995                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13996                    if (dumpAll) {
13997                        pw.println(":");
13998                        ArrayList<Intent> intents = ent.getValue();
13999                        final int N = intents.size();
14000                        for (int i=0; i<N; i++) {
14001                            sb.setLength(0);
14002                            sb.append("    Intent: ");
14003                            intents.get(i).toShortString(sb, false, true, false, false);
14004                            pw.println(sb.toString());
14005                            Bundle bundle = intents.get(i).getExtras();
14006                            if (bundle != null) {
14007                                pw.print("      ");
14008                                pw.println(bundle.toString());
14009                            }
14010                        }
14011                    } else {
14012                        pw.println("");
14013                    }
14014                }
14015            }
14016        }
14017
14018        if (!onlyHistory && dumpAll) {
14019            pw.println();
14020            for (BroadcastQueue queue : mBroadcastQueues) {
14021                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14022                        + queue.mBroadcastsScheduled);
14023            }
14024            pw.println("  mHandler:");
14025            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14026            needSep = true;
14027            printedAnything = true;
14028        }
14029
14030        if (!printedAnything) {
14031            pw.println("  (nothing)");
14032        }
14033    }
14034
14035    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14036            int opti, boolean dumpAll, String dumpPackage) {
14037        boolean needSep;
14038        boolean printedAnything = false;
14039
14040        ItemMatcher matcher = new ItemMatcher();
14041        matcher.build(args, opti);
14042
14043        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14044
14045        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14046        printedAnything |= needSep;
14047
14048        if (mLaunchingProviders.size() > 0) {
14049            boolean printed = false;
14050            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14051                ContentProviderRecord r = mLaunchingProviders.get(i);
14052                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14053                    continue;
14054                }
14055                if (!printed) {
14056                    if (needSep) pw.println();
14057                    needSep = true;
14058                    pw.println("  Launching content providers:");
14059                    printed = true;
14060                    printedAnything = true;
14061                }
14062                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14063                        pw.println(r);
14064            }
14065        }
14066
14067        if (mGrantedUriPermissions.size() > 0) {
14068            boolean printed = false;
14069            int dumpUid = -2;
14070            if (dumpPackage != null) {
14071                try {
14072                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
14073                } catch (NameNotFoundException e) {
14074                    dumpUid = -1;
14075                }
14076            }
14077            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14078                int uid = mGrantedUriPermissions.keyAt(i);
14079                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14080                    continue;
14081                }
14082                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14083                if (!printed) {
14084                    if (needSep) pw.println();
14085                    needSep = true;
14086                    pw.println("  Granted Uri Permissions:");
14087                    printed = true;
14088                    printedAnything = true;
14089                }
14090                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14091                for (UriPermission perm : perms.values()) {
14092                    pw.print("    "); pw.println(perm);
14093                    if (dumpAll) {
14094                        perm.dump(pw, "      ");
14095                    }
14096                }
14097            }
14098        }
14099
14100        if (!printedAnything) {
14101            pw.println("  (nothing)");
14102        }
14103    }
14104
14105    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14106            int opti, boolean dumpAll, String dumpPackage) {
14107        boolean printed = false;
14108
14109        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14110
14111        if (mIntentSenderRecords.size() > 0) {
14112            Iterator<WeakReference<PendingIntentRecord>> it
14113                    = mIntentSenderRecords.values().iterator();
14114            while (it.hasNext()) {
14115                WeakReference<PendingIntentRecord> ref = it.next();
14116                PendingIntentRecord rec = ref != null ? ref.get(): null;
14117                if (dumpPackage != null && (rec == null
14118                        || !dumpPackage.equals(rec.key.packageName))) {
14119                    continue;
14120                }
14121                printed = true;
14122                if (rec != null) {
14123                    pw.print("  * "); pw.println(rec);
14124                    if (dumpAll) {
14125                        rec.dump(pw, "    ");
14126                    }
14127                } else {
14128                    pw.print("  * "); pw.println(ref);
14129                }
14130            }
14131        }
14132
14133        if (!printed) {
14134            pw.println("  (nothing)");
14135        }
14136    }
14137
14138    private static final int dumpProcessList(PrintWriter pw,
14139            ActivityManagerService service, List list,
14140            String prefix, String normalLabel, String persistentLabel,
14141            String dumpPackage) {
14142        int numPers = 0;
14143        final int N = list.size()-1;
14144        for (int i=N; i>=0; i--) {
14145            ProcessRecord r = (ProcessRecord)list.get(i);
14146            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14147                continue;
14148            }
14149            pw.println(String.format("%s%s #%2d: %s",
14150                    prefix, (r.persistent ? persistentLabel : normalLabel),
14151                    i, r.toString()));
14152            if (r.persistent) {
14153                numPers++;
14154            }
14155        }
14156        return numPers;
14157    }
14158
14159    private static final boolean dumpProcessOomList(PrintWriter pw,
14160            ActivityManagerService service, List<ProcessRecord> origList,
14161            String prefix, String normalLabel, String persistentLabel,
14162            boolean inclDetails, String dumpPackage) {
14163
14164        ArrayList<Pair<ProcessRecord, Integer>> list
14165                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14166        for (int i=0; i<origList.size(); i++) {
14167            ProcessRecord r = origList.get(i);
14168            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14169                continue;
14170            }
14171            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14172        }
14173
14174        if (list.size() <= 0) {
14175            return false;
14176        }
14177
14178        Comparator<Pair<ProcessRecord, Integer>> comparator
14179                = new Comparator<Pair<ProcessRecord, Integer>>() {
14180            @Override
14181            public int compare(Pair<ProcessRecord, Integer> object1,
14182                    Pair<ProcessRecord, Integer> object2) {
14183                if (object1.first.setAdj != object2.first.setAdj) {
14184                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14185                }
14186                if (object1.second.intValue() != object2.second.intValue()) {
14187                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14188                }
14189                return 0;
14190            }
14191        };
14192
14193        Collections.sort(list, comparator);
14194
14195        final long curRealtime = SystemClock.elapsedRealtime();
14196        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14197        final long curUptime = SystemClock.uptimeMillis();
14198        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14199
14200        for (int i=list.size()-1; i>=0; i--) {
14201            ProcessRecord r = list.get(i).first;
14202            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14203            char schedGroup;
14204            switch (r.setSchedGroup) {
14205                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
14206                    schedGroup = 'B';
14207                    break;
14208                case Process.THREAD_GROUP_DEFAULT:
14209                    schedGroup = 'F';
14210                    break;
14211                default:
14212                    schedGroup = '?';
14213                    break;
14214            }
14215            char foreground;
14216            if (r.foregroundActivities) {
14217                foreground = 'A';
14218            } else if (r.foregroundServices) {
14219                foreground = 'S';
14220            } else {
14221                foreground = ' ';
14222            }
14223            String procState = ProcessList.makeProcStateString(r.curProcState);
14224            pw.print(prefix);
14225            pw.print(r.persistent ? persistentLabel : normalLabel);
14226            pw.print(" #");
14227            int num = (origList.size()-1)-list.get(i).second;
14228            if (num < 10) pw.print(' ');
14229            pw.print(num);
14230            pw.print(": ");
14231            pw.print(oomAdj);
14232            pw.print(' ');
14233            pw.print(schedGroup);
14234            pw.print('/');
14235            pw.print(foreground);
14236            pw.print('/');
14237            pw.print(procState);
14238            pw.print(" trm:");
14239            if (r.trimMemoryLevel < 10) pw.print(' ');
14240            pw.print(r.trimMemoryLevel);
14241            pw.print(' ');
14242            pw.print(r.toShortString());
14243            pw.print(" (");
14244            pw.print(r.adjType);
14245            pw.println(')');
14246            if (r.adjSource != null || r.adjTarget != null) {
14247                pw.print(prefix);
14248                pw.print("    ");
14249                if (r.adjTarget instanceof ComponentName) {
14250                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14251                } else if (r.adjTarget != null) {
14252                    pw.print(r.adjTarget.toString());
14253                } else {
14254                    pw.print("{null}");
14255                }
14256                pw.print("<=");
14257                if (r.adjSource instanceof ProcessRecord) {
14258                    pw.print("Proc{");
14259                    pw.print(((ProcessRecord)r.adjSource).toShortString());
14260                    pw.println("}");
14261                } else if (r.adjSource != null) {
14262                    pw.println(r.adjSource.toString());
14263                } else {
14264                    pw.println("{null}");
14265                }
14266            }
14267            if (inclDetails) {
14268                pw.print(prefix);
14269                pw.print("    ");
14270                pw.print("oom: max="); pw.print(r.maxAdj);
14271                pw.print(" curRaw="); pw.print(r.curRawAdj);
14272                pw.print(" setRaw="); pw.print(r.setRawAdj);
14273                pw.print(" cur="); pw.print(r.curAdj);
14274                pw.print(" set="); pw.println(r.setAdj);
14275                pw.print(prefix);
14276                pw.print("    ");
14277                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14278                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14279                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14280                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14281                pw.println();
14282                pw.print(prefix);
14283                pw.print("    ");
14284                pw.print("cached="); pw.print(r.cached);
14285                pw.print(" empty="); pw.print(r.empty);
14286                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14287
14288                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14289                    if (r.lastWakeTime != 0) {
14290                        long wtime;
14291                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14292                        synchronized (stats) {
14293                            wtime = stats.getProcessWakeTime(r.info.uid,
14294                                    r.pid, curRealtime);
14295                        }
14296                        long timeUsed = wtime - r.lastWakeTime;
14297                        pw.print(prefix);
14298                        pw.print("    ");
14299                        pw.print("keep awake over ");
14300                        TimeUtils.formatDuration(realtimeSince, pw);
14301                        pw.print(" used ");
14302                        TimeUtils.formatDuration(timeUsed, pw);
14303                        pw.print(" (");
14304                        pw.print((timeUsed*100)/realtimeSince);
14305                        pw.println("%)");
14306                    }
14307                    if (r.lastCpuTime != 0) {
14308                        long timeUsed = r.curCpuTime - r.lastCpuTime;
14309                        pw.print(prefix);
14310                        pw.print("    ");
14311                        pw.print("run cpu over ");
14312                        TimeUtils.formatDuration(uptimeSince, pw);
14313                        pw.print(" used ");
14314                        TimeUtils.formatDuration(timeUsed, pw);
14315                        pw.print(" (");
14316                        pw.print((timeUsed*100)/uptimeSince);
14317                        pw.println("%)");
14318                    }
14319                }
14320            }
14321        }
14322        return true;
14323    }
14324
14325    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14326            String[] args) {
14327        ArrayList<ProcessRecord> procs;
14328        synchronized (this) {
14329            if (args != null && args.length > start
14330                    && args[start].charAt(0) != '-') {
14331                procs = new ArrayList<ProcessRecord>();
14332                int pid = -1;
14333                try {
14334                    pid = Integer.parseInt(args[start]);
14335                } catch (NumberFormatException e) {
14336                }
14337                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14338                    ProcessRecord proc = mLruProcesses.get(i);
14339                    if (proc.pid == pid) {
14340                        procs.add(proc);
14341                    } else if (allPkgs && proc.pkgList != null
14342                            && proc.pkgList.containsKey(args[start])) {
14343                        procs.add(proc);
14344                    } else if (proc.processName.equals(args[start])) {
14345                        procs.add(proc);
14346                    }
14347                }
14348                if (procs.size() <= 0) {
14349                    return null;
14350                }
14351            } else {
14352                procs = new ArrayList<ProcessRecord>(mLruProcesses);
14353            }
14354        }
14355        return procs;
14356    }
14357
14358    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
14359            PrintWriter pw, String[] args) {
14360        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14361        if (procs == null) {
14362            pw.println("No process found for: " + args[0]);
14363            return;
14364        }
14365
14366        long uptime = SystemClock.uptimeMillis();
14367        long realtime = SystemClock.elapsedRealtime();
14368        pw.println("Applications Graphics Acceleration Info:");
14369        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
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** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
14375                pw.flush();
14376                try {
14377                    TransferPipe tp = new TransferPipe();
14378                    try {
14379                        r.thread.dumpGfxInfo(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 void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
14396        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14397        if (procs == null) {
14398            pw.println("No process found for: " + args[0]);
14399            return;
14400        }
14401
14402        pw.println("Applications Database Info:");
14403
14404        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14405            ProcessRecord r = procs.get(i);
14406            if (r.thread != null) {
14407                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
14408                pw.flush();
14409                try {
14410                    TransferPipe tp = new TransferPipe();
14411                    try {
14412                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
14413                        tp.go(fd);
14414                    } finally {
14415                        tp.kill();
14416                    }
14417                } catch (IOException e) {
14418                    pw.println("Failure while dumping the app: " + r);
14419                    pw.flush();
14420                } catch (RemoteException e) {
14421                    pw.println("Got a RemoteException while dumping the app " + r);
14422                    pw.flush();
14423                }
14424            }
14425        }
14426    }
14427
14428    final static class MemItem {
14429        final boolean isProc;
14430        final String label;
14431        final String shortLabel;
14432        final long pss;
14433        final int id;
14434        final boolean hasActivities;
14435        ArrayList<MemItem> subitems;
14436
14437        public MemItem(String _label, String _shortLabel, long _pss, int _id,
14438                boolean _hasActivities) {
14439            isProc = true;
14440            label = _label;
14441            shortLabel = _shortLabel;
14442            pss = _pss;
14443            id = _id;
14444            hasActivities = _hasActivities;
14445        }
14446
14447        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
14448            isProc = false;
14449            label = _label;
14450            shortLabel = _shortLabel;
14451            pss = _pss;
14452            id = _id;
14453            hasActivities = false;
14454        }
14455    }
14456
14457    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
14458            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
14459        if (sort && !isCompact) {
14460            Collections.sort(items, new Comparator<MemItem>() {
14461                @Override
14462                public int compare(MemItem lhs, MemItem rhs) {
14463                    if (lhs.pss < rhs.pss) {
14464                        return 1;
14465                    } else if (lhs.pss > rhs.pss) {
14466                        return -1;
14467                    }
14468                    return 0;
14469                }
14470            });
14471        }
14472
14473        for (int i=0; i<items.size(); i++) {
14474            MemItem mi = items.get(i);
14475            if (!isCompact) {
14476                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
14477            } else if (mi.isProc) {
14478                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
14479                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
14480                pw.println(mi.hasActivities ? ",a" : ",e");
14481            } else {
14482                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
14483                pw.println(mi.pss);
14484            }
14485            if (mi.subitems != null) {
14486                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
14487                        true, isCompact);
14488            }
14489        }
14490    }
14491
14492    // These are in KB.
14493    static final long[] DUMP_MEM_BUCKETS = new long[] {
14494        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
14495        120*1024, 160*1024, 200*1024,
14496        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
14497        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
14498    };
14499
14500    static final void appendMemBucket(StringBuilder out, long memKB, String label,
14501            boolean stackLike) {
14502        int start = label.lastIndexOf('.');
14503        if (start >= 0) start++;
14504        else start = 0;
14505        int end = label.length();
14506        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
14507            if (DUMP_MEM_BUCKETS[i] >= memKB) {
14508                long bucket = DUMP_MEM_BUCKETS[i]/1024;
14509                out.append(bucket);
14510                out.append(stackLike ? "MB." : "MB ");
14511                out.append(label, start, end);
14512                return;
14513            }
14514        }
14515        out.append(memKB/1024);
14516        out.append(stackLike ? "MB." : "MB ");
14517        out.append(label, start, end);
14518    }
14519
14520    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
14521            ProcessList.NATIVE_ADJ,
14522            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
14523            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
14524            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
14525            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
14526            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
14527            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
14528    };
14529    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
14530            "Native",
14531            "System", "Persistent", "Persistent Service", "Foreground",
14532            "Visible", "Perceptible",
14533            "Heavy Weight", "Backup",
14534            "A Services", "Home",
14535            "Previous", "B Services", "Cached"
14536    };
14537    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
14538            "native",
14539            "sys", "pers", "persvc", "fore",
14540            "vis", "percept",
14541            "heavy", "backup",
14542            "servicea", "home",
14543            "prev", "serviceb", "cached"
14544    };
14545
14546    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
14547            long realtime, boolean isCheckinRequest, boolean isCompact) {
14548        if (isCheckinRequest || isCompact) {
14549            // short checkin version
14550            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
14551        } else {
14552            pw.println("Applications Memory Usage (kB):");
14553            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14554        }
14555    }
14556
14557    private static final int KSM_SHARED = 0;
14558    private static final int KSM_SHARING = 1;
14559    private static final int KSM_UNSHARED = 2;
14560    private static final int KSM_VOLATILE = 3;
14561
14562    private final long[] getKsmInfo() {
14563        long[] longOut = new long[4];
14564        final int[] SINGLE_LONG_FORMAT = new int[] {
14565            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14566        };
14567        long[] longTmp = new long[1];
14568        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14569                SINGLE_LONG_FORMAT, null, longTmp, null);
14570        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14571        longTmp[0] = 0;
14572        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14573                SINGLE_LONG_FORMAT, null, longTmp, null);
14574        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14575        longTmp[0] = 0;
14576        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14577                SINGLE_LONG_FORMAT, null, longTmp, null);
14578        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14579        longTmp[0] = 0;
14580        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14581                SINGLE_LONG_FORMAT, null, longTmp, null);
14582        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14583        return longOut;
14584    }
14585
14586    final void dumpApplicationMemoryUsage(FileDescriptor fd,
14587            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
14588        boolean dumpDetails = false;
14589        boolean dumpFullDetails = false;
14590        boolean dumpDalvik = false;
14591        boolean dumpSummaryOnly = false;
14592        boolean oomOnly = false;
14593        boolean isCompact = false;
14594        boolean localOnly = false;
14595        boolean packages = false;
14596
14597        int opti = 0;
14598        while (opti < args.length) {
14599            String opt = args[opti];
14600            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14601                break;
14602            }
14603            opti++;
14604            if ("-a".equals(opt)) {
14605                dumpDetails = true;
14606                dumpFullDetails = true;
14607                dumpDalvik = true;
14608            } else if ("-d".equals(opt)) {
14609                dumpDalvik = true;
14610            } else if ("-c".equals(opt)) {
14611                isCompact = true;
14612            } else if ("-s".equals(opt)) {
14613                dumpDetails = true;
14614                dumpSummaryOnly = true;
14615            } else if ("--oom".equals(opt)) {
14616                oomOnly = true;
14617            } else if ("--local".equals(opt)) {
14618                localOnly = true;
14619            } else if ("--package".equals(opt)) {
14620                packages = true;
14621            } else if ("-h".equals(opt)) {
14622                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
14623                pw.println("  -a: include all available information for each process.");
14624                pw.println("  -d: include dalvik details.");
14625                pw.println("  -c: dump in a compact machine-parseable representation.");
14626                pw.println("  -s: dump only summary of application memory usage.");
14627                pw.println("  --oom: only show processes organized by oom adj.");
14628                pw.println("  --local: only collect details locally, don't call process.");
14629                pw.println("  --package: interpret process arg as package, dumping all");
14630                pw.println("             processes that have loaded that package.");
14631                pw.println("If [process] is specified it can be the name or ");
14632                pw.println("pid of a specific process to dump.");
14633                return;
14634            } else {
14635                pw.println("Unknown argument: " + opt + "; use -h for help");
14636            }
14637        }
14638
14639        final boolean isCheckinRequest = scanArgs(args, "--checkin");
14640        long uptime = SystemClock.uptimeMillis();
14641        long realtime = SystemClock.elapsedRealtime();
14642        final long[] tmpLong = new long[1];
14643
14644        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
14645        if (procs == null) {
14646            // No Java processes.  Maybe they want to print a native process.
14647            if (args != null && args.length > opti
14648                    && args[opti].charAt(0) != '-') {
14649                ArrayList<ProcessCpuTracker.Stats> nativeProcs
14650                        = new ArrayList<ProcessCpuTracker.Stats>();
14651                updateCpuStatsNow();
14652                int findPid = -1;
14653                try {
14654                    findPid = Integer.parseInt(args[opti]);
14655                } catch (NumberFormatException e) {
14656                }
14657                synchronized (mProcessCpuTracker) {
14658                    final int N = mProcessCpuTracker.countStats();
14659                    for (int i=0; i<N; i++) {
14660                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14661                        if (st.pid == findPid || (st.baseName != null
14662                                && st.baseName.equals(args[opti]))) {
14663                            nativeProcs.add(st);
14664                        }
14665                    }
14666                }
14667                if (nativeProcs.size() > 0) {
14668                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14669                            isCompact);
14670                    Debug.MemoryInfo mi = null;
14671                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14672                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14673                        final int pid = r.pid;
14674                        if (!isCheckinRequest && dumpDetails) {
14675                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14676                        }
14677                        if (mi == null) {
14678                            mi = new Debug.MemoryInfo();
14679                        }
14680                        if (dumpDetails || (!brief && !oomOnly)) {
14681                            Debug.getMemoryInfo(pid, mi);
14682                        } else {
14683                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14684                            mi.dalvikPrivateDirty = (int)tmpLong[0];
14685                        }
14686                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14687                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14688                        if (isCheckinRequest) {
14689                            pw.println();
14690                        }
14691                    }
14692                    return;
14693                }
14694            }
14695            pw.println("No process found for: " + args[opti]);
14696            return;
14697        }
14698
14699        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14700            dumpDetails = true;
14701        }
14702
14703        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14704
14705        String[] innerArgs = new String[args.length-opti];
14706        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14707
14708        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14709        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14710        long nativePss = 0;
14711        long dalvikPss = 0;
14712        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
14713                EmptyArray.LONG;
14714        long otherPss = 0;
14715        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14716
14717        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14718        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14719                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14720
14721        long totalPss = 0;
14722        long cachedPss = 0;
14723
14724        Debug.MemoryInfo mi = null;
14725        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14726            final ProcessRecord r = procs.get(i);
14727            final IApplicationThread thread;
14728            final int pid;
14729            final int oomAdj;
14730            final boolean hasActivities;
14731            synchronized (this) {
14732                thread = r.thread;
14733                pid = r.pid;
14734                oomAdj = r.getSetAdjWithServices();
14735                hasActivities = r.activities.size() > 0;
14736            }
14737            if (thread != null) {
14738                if (!isCheckinRequest && dumpDetails) {
14739                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14740                }
14741                if (mi == null) {
14742                    mi = new Debug.MemoryInfo();
14743                }
14744                if (dumpDetails || (!brief && !oomOnly)) {
14745                    Debug.getMemoryInfo(pid, mi);
14746                } else {
14747                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14748                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14749                }
14750                if (dumpDetails) {
14751                    if (localOnly) {
14752                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14753                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
14754                        if (isCheckinRequest) {
14755                            pw.println();
14756                        }
14757                    } else {
14758                        try {
14759                            pw.flush();
14760                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14761                                    dumpDalvik, dumpSummaryOnly, innerArgs);
14762                        } catch (RemoteException e) {
14763                            if (!isCheckinRequest) {
14764                                pw.println("Got RemoteException!");
14765                                pw.flush();
14766                            }
14767                        }
14768                    }
14769                }
14770
14771                final long myTotalPss = mi.getTotalPss();
14772                final long myTotalUss = mi.getTotalUss();
14773
14774                synchronized (this) {
14775                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14776                        // Record this for posterity if the process has been stable.
14777                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14778                    }
14779                }
14780
14781                if (!isCheckinRequest && mi != null) {
14782                    totalPss += myTotalPss;
14783                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14784                            (hasActivities ? " / activities)" : ")"),
14785                            r.processName, myTotalPss, pid, hasActivities);
14786                    procMems.add(pssItem);
14787                    procMemsMap.put(pid, pssItem);
14788
14789                    nativePss += mi.nativePss;
14790                    dalvikPss += mi.dalvikPss;
14791                    for (int j=0; j<dalvikSubitemPss.length; j++) {
14792                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
14793                    }
14794                    otherPss += mi.otherPss;
14795                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14796                        long mem = mi.getOtherPss(j);
14797                        miscPss[j] += mem;
14798                        otherPss -= mem;
14799                    }
14800
14801                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14802                        cachedPss += myTotalPss;
14803                    }
14804
14805                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14806                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14807                                || oomIndex == (oomPss.length-1)) {
14808                            oomPss[oomIndex] += myTotalPss;
14809                            if (oomProcs[oomIndex] == null) {
14810                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14811                            }
14812                            oomProcs[oomIndex].add(pssItem);
14813                            break;
14814                        }
14815                    }
14816                }
14817            }
14818        }
14819
14820        long nativeProcTotalPss = 0;
14821
14822        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14823            // If we are showing aggregations, also look for native processes to
14824            // include so that our aggregations are more accurate.
14825            updateCpuStatsNow();
14826            mi = null;
14827            synchronized (mProcessCpuTracker) {
14828                final int N = mProcessCpuTracker.countStats();
14829                for (int i=0; i<N; i++) {
14830                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14831                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14832                        if (mi == null) {
14833                            mi = new Debug.MemoryInfo();
14834                        }
14835                        if (!brief && !oomOnly) {
14836                            Debug.getMemoryInfo(st.pid, mi);
14837                        } else {
14838                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14839                            mi.nativePrivateDirty = (int)tmpLong[0];
14840                        }
14841
14842                        final long myTotalPss = mi.getTotalPss();
14843                        totalPss += myTotalPss;
14844                        nativeProcTotalPss += myTotalPss;
14845
14846                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14847                                st.name, myTotalPss, st.pid, false);
14848                        procMems.add(pssItem);
14849
14850                        nativePss += mi.nativePss;
14851                        dalvikPss += mi.dalvikPss;
14852                        for (int j=0; j<dalvikSubitemPss.length; j++) {
14853                            dalvikSubitemPss[j] += mi.getOtherPss(
14854                                    Debug.MemoryInfo.NUM_OTHER_STATS + j);
14855                        }
14856                        otherPss += mi.otherPss;
14857                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14858                            long mem = mi.getOtherPss(j);
14859                            miscPss[j] += mem;
14860                            otherPss -= mem;
14861                        }
14862                        oomPss[0] += myTotalPss;
14863                        if (oomProcs[0] == null) {
14864                            oomProcs[0] = new ArrayList<MemItem>();
14865                        }
14866                        oomProcs[0].add(pssItem);
14867                    }
14868                }
14869            }
14870
14871            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14872
14873            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14874            final MemItem dalvikItem = new MemItem("Dalvik", "Dalvik", dalvikPss, -2);
14875            if (dalvikSubitemPss.length > 0) {
14876                dalvikItem.subitems = new ArrayList<MemItem>();
14877                for (int j=0; j<dalvikSubitemPss.length; j++) {
14878                    final String name = Debug.MemoryInfo.getOtherLabel(
14879                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
14880                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j], j));
14881                }
14882            }
14883            catMems.add(dalvikItem);
14884            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14885            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14886                String label = Debug.MemoryInfo.getOtherLabel(j);
14887                catMems.add(new MemItem(label, label, miscPss[j], j));
14888            }
14889
14890            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14891            for (int j=0; j<oomPss.length; j++) {
14892                if (oomPss[j] != 0) {
14893                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14894                            : DUMP_MEM_OOM_LABEL[j];
14895                    MemItem item = new MemItem(label, label, oomPss[j],
14896                            DUMP_MEM_OOM_ADJ[j]);
14897                    item.subitems = oomProcs[j];
14898                    oomMems.add(item);
14899                }
14900            }
14901
14902            if (!brief && !oomOnly && !isCompact) {
14903                pw.println();
14904                pw.println("Total PSS by process:");
14905                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14906                pw.println();
14907            }
14908            if (!isCompact) {
14909                pw.println("Total PSS by OOM adjustment:");
14910            }
14911            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14912            if (!brief && !oomOnly) {
14913                PrintWriter out = categoryPw != null ? categoryPw : pw;
14914                if (!isCompact) {
14915                    out.println();
14916                    out.println("Total PSS by category:");
14917                }
14918                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14919            }
14920            if (!isCompact) {
14921                pw.println();
14922            }
14923            MemInfoReader memInfo = new MemInfoReader();
14924            memInfo.readMemInfo();
14925            if (nativeProcTotalPss > 0) {
14926                synchronized (this) {
14927                    final long cachedKb = memInfo.getCachedSizeKb();
14928                    final long freeKb = memInfo.getFreeSizeKb();
14929                    final long zramKb = memInfo.getZramTotalSizeKb();
14930                    final long kernelKb = memInfo.getKernelUsedSizeKb();
14931                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
14932                            kernelKb*1024, nativeProcTotalPss*1024);
14933                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
14934                            nativeProcTotalPss);
14935                }
14936            }
14937            if (!brief) {
14938                if (!isCompact) {
14939                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14940                    pw.print(" kB (status ");
14941                    switch (mLastMemoryLevel) {
14942                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14943                            pw.println("normal)");
14944                            break;
14945                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14946                            pw.println("moderate)");
14947                            break;
14948                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14949                            pw.println("low)");
14950                            break;
14951                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14952                            pw.println("critical)");
14953                            break;
14954                        default:
14955                            pw.print(mLastMemoryLevel);
14956                            pw.println(")");
14957                            break;
14958                    }
14959                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14960                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14961                            pw.print(cachedPss); pw.print(" cached pss + ");
14962                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14963                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14964                } else {
14965                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14966                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14967                            + memInfo.getFreeSizeKb()); pw.print(",");
14968                    pw.println(totalPss - cachedPss);
14969                }
14970            }
14971            if (!isCompact) {
14972                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14973                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14974                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14975                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14976                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14977                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14978                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14979            }
14980            if (!brief) {
14981                if (memInfo.getZramTotalSizeKb() != 0) {
14982                    if (!isCompact) {
14983                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14984                                pw.print(" kB physical used for ");
14985                                pw.print(memInfo.getSwapTotalSizeKb()
14986                                        - memInfo.getSwapFreeSizeKb());
14987                                pw.print(" kB in swap (");
14988                                pw.print(memInfo.getSwapTotalSizeKb());
14989                                pw.println(" kB total swap)");
14990                    } else {
14991                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14992                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14993                                pw.println(memInfo.getSwapFreeSizeKb());
14994                    }
14995                }
14996                final long[] ksm = getKsmInfo();
14997                if (!isCompact) {
14998                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14999                            || ksm[KSM_VOLATILE] != 0) {
15000                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
15001                                pw.print(" kB saved from shared ");
15002                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
15003                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
15004                                pw.print(" kB unshared; ");
15005                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
15006                    }
15007                    pw.print("   Tuning: ");
15008                    pw.print(ActivityManager.staticGetMemoryClass());
15009                    pw.print(" (large ");
15010                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15011                    pw.print("), oom ");
15012                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15013                    pw.print(" kB");
15014                    pw.print(", restore limit ");
15015                    pw.print(mProcessList.getCachedRestoreThresholdKb());
15016                    pw.print(" kB");
15017                    if (ActivityManager.isLowRamDeviceStatic()) {
15018                        pw.print(" (low-ram)");
15019                    }
15020                    if (ActivityManager.isHighEndGfx()) {
15021                        pw.print(" (high-end-gfx)");
15022                    }
15023                    pw.println();
15024                } else {
15025                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15026                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15027                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15028                    pw.print("tuning,");
15029                    pw.print(ActivityManager.staticGetMemoryClass());
15030                    pw.print(',');
15031                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15032                    pw.print(',');
15033                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15034                    if (ActivityManager.isLowRamDeviceStatic()) {
15035                        pw.print(",low-ram");
15036                    }
15037                    if (ActivityManager.isHighEndGfx()) {
15038                        pw.print(",high-end-gfx");
15039                    }
15040                    pw.println();
15041                }
15042            }
15043        }
15044    }
15045
15046    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15047            long memtrack, String name) {
15048        sb.append("  ");
15049        sb.append(ProcessList.makeOomAdjString(oomAdj));
15050        sb.append(' ');
15051        sb.append(ProcessList.makeProcStateString(procState));
15052        sb.append(' ');
15053        ProcessList.appendRamKb(sb, pss);
15054        sb.append(" kB: ");
15055        sb.append(name);
15056        if (memtrack > 0) {
15057            sb.append(" (");
15058            sb.append(memtrack);
15059            sb.append(" kB memtrack)");
15060        }
15061    }
15062
15063    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15064        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15065        sb.append(" (pid ");
15066        sb.append(mi.pid);
15067        sb.append(") ");
15068        sb.append(mi.adjType);
15069        sb.append('\n');
15070        if (mi.adjReason != null) {
15071            sb.append("                      ");
15072            sb.append(mi.adjReason);
15073            sb.append('\n');
15074        }
15075    }
15076
15077    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15078        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15079        for (int i=0, N=memInfos.size(); i<N; i++) {
15080            ProcessMemInfo mi = memInfos.get(i);
15081            infoMap.put(mi.pid, mi);
15082        }
15083        updateCpuStatsNow();
15084        long[] memtrackTmp = new long[1];
15085        synchronized (mProcessCpuTracker) {
15086            final int N = mProcessCpuTracker.countStats();
15087            for (int i=0; i<N; i++) {
15088                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15089                if (st.vsize > 0) {
15090                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
15091                    if (pss > 0) {
15092                        if (infoMap.indexOfKey(st.pid) < 0) {
15093                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15094                                    ProcessList.NATIVE_ADJ, -1, "native", null);
15095                            mi.pss = pss;
15096                            mi.memtrack = memtrackTmp[0];
15097                            memInfos.add(mi);
15098                        }
15099                    }
15100                }
15101            }
15102        }
15103
15104        long totalPss = 0;
15105        long totalMemtrack = 0;
15106        for (int i=0, N=memInfos.size(); i<N; i++) {
15107            ProcessMemInfo mi = memInfos.get(i);
15108            if (mi.pss == 0) {
15109                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15110                mi.memtrack = memtrackTmp[0];
15111            }
15112            totalPss += mi.pss;
15113            totalMemtrack += mi.memtrack;
15114        }
15115        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15116            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15117                if (lhs.oomAdj != rhs.oomAdj) {
15118                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15119                }
15120                if (lhs.pss != rhs.pss) {
15121                    return lhs.pss < rhs.pss ? 1 : -1;
15122                }
15123                return 0;
15124            }
15125        });
15126
15127        StringBuilder tag = new StringBuilder(128);
15128        StringBuilder stack = new StringBuilder(128);
15129        tag.append("Low on memory -- ");
15130        appendMemBucket(tag, totalPss, "total", false);
15131        appendMemBucket(stack, totalPss, "total", true);
15132
15133        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15134        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15135        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15136
15137        boolean firstLine = true;
15138        int lastOomAdj = Integer.MIN_VALUE;
15139        long extraNativeRam = 0;
15140        long extraNativeMemtrack = 0;
15141        long cachedPss = 0;
15142        for (int i=0, N=memInfos.size(); i<N; i++) {
15143            ProcessMemInfo mi = memInfos.get(i);
15144
15145            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15146                cachedPss += mi.pss;
15147            }
15148
15149            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15150                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15151                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15152                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15153                if (lastOomAdj != mi.oomAdj) {
15154                    lastOomAdj = mi.oomAdj;
15155                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15156                        tag.append(" / ");
15157                    }
15158                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15159                        if (firstLine) {
15160                            stack.append(":");
15161                            firstLine = false;
15162                        }
15163                        stack.append("\n\t at ");
15164                    } else {
15165                        stack.append("$");
15166                    }
15167                } else {
15168                    tag.append(" ");
15169                    stack.append("$");
15170                }
15171                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15172                    appendMemBucket(tag, mi.pss, mi.name, false);
15173                }
15174                appendMemBucket(stack, mi.pss, mi.name, true);
15175                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15176                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15177                    stack.append("(");
15178                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15179                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15180                            stack.append(DUMP_MEM_OOM_LABEL[k]);
15181                            stack.append(":");
15182                            stack.append(DUMP_MEM_OOM_ADJ[k]);
15183                        }
15184                    }
15185                    stack.append(")");
15186                }
15187            }
15188
15189            appendMemInfo(fullNativeBuilder, mi);
15190            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15191                // The short form only has native processes that are >= 512K.
15192                if (mi.pss >= 512) {
15193                    appendMemInfo(shortNativeBuilder, mi);
15194                } else {
15195                    extraNativeRam += mi.pss;
15196                    extraNativeMemtrack += mi.memtrack;
15197                }
15198            } else {
15199                // Short form has all other details, but if we have collected RAM
15200                // from smaller native processes let's dump a summary of that.
15201                if (extraNativeRam > 0) {
15202                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15203                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15204                    shortNativeBuilder.append('\n');
15205                    extraNativeRam = 0;
15206                }
15207                appendMemInfo(fullJavaBuilder, mi);
15208            }
15209        }
15210
15211        fullJavaBuilder.append("           ");
15212        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15213        fullJavaBuilder.append(" kB: TOTAL");
15214        if (totalMemtrack > 0) {
15215            fullJavaBuilder.append(" (");
15216            fullJavaBuilder.append(totalMemtrack);
15217            fullJavaBuilder.append(" kB memtrack)");
15218        } else {
15219        }
15220        fullJavaBuilder.append("\n");
15221
15222        MemInfoReader memInfo = new MemInfoReader();
15223        memInfo.readMemInfo();
15224        final long[] infos = memInfo.getRawInfo();
15225
15226        StringBuilder memInfoBuilder = new StringBuilder(1024);
15227        Debug.getMemInfo(infos);
15228        memInfoBuilder.append("  MemInfo: ");
15229        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
15230        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
15231        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
15232        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
15233        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
15234        memInfoBuilder.append("           ");
15235        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
15236        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
15237        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
15238        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
15239        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15240            memInfoBuilder.append("  ZRAM: ");
15241            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
15242            memInfoBuilder.append(" kB RAM, ");
15243            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
15244            memInfoBuilder.append(" kB swap total, ");
15245            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
15246            memInfoBuilder.append(" kB swap free\n");
15247        }
15248        final long[] ksm = getKsmInfo();
15249        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15250                || ksm[KSM_VOLATILE] != 0) {
15251            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
15252            memInfoBuilder.append(" kB saved from shared ");
15253            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
15254            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
15255            memInfoBuilder.append(" kB unshared; ");
15256            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
15257        }
15258        memInfoBuilder.append("  Free RAM: ");
15259        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
15260                + memInfo.getFreeSizeKb());
15261        memInfoBuilder.append(" kB\n");
15262        memInfoBuilder.append("  Used RAM: ");
15263        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
15264        memInfoBuilder.append(" kB\n");
15265        memInfoBuilder.append("  Lost RAM: ");
15266        memInfoBuilder.append(memInfo.getTotalSizeKb()
15267                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15268                - memInfo.getKernelUsedSizeKb());
15269        memInfoBuilder.append(" kB\n");
15270        Slog.i(TAG, "Low on memory:");
15271        Slog.i(TAG, shortNativeBuilder.toString());
15272        Slog.i(TAG, fullJavaBuilder.toString());
15273        Slog.i(TAG, memInfoBuilder.toString());
15274
15275        StringBuilder dropBuilder = new StringBuilder(1024);
15276        /*
15277        StringWriter oomSw = new StringWriter();
15278        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
15279        StringWriter catSw = new StringWriter();
15280        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15281        String[] emptyArgs = new String[] { };
15282        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
15283        oomPw.flush();
15284        String oomString = oomSw.toString();
15285        */
15286        dropBuilder.append("Low on memory:");
15287        dropBuilder.append(stack);
15288        dropBuilder.append('\n');
15289        dropBuilder.append(fullNativeBuilder);
15290        dropBuilder.append(fullJavaBuilder);
15291        dropBuilder.append('\n');
15292        dropBuilder.append(memInfoBuilder);
15293        dropBuilder.append('\n');
15294        /*
15295        dropBuilder.append(oomString);
15296        dropBuilder.append('\n');
15297        */
15298        StringWriter catSw = new StringWriter();
15299        synchronized (ActivityManagerService.this) {
15300            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15301            String[] emptyArgs = new String[] { };
15302            catPw.println();
15303            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
15304            catPw.println();
15305            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
15306                    false, false, null);
15307            catPw.println();
15308            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
15309            catPw.flush();
15310        }
15311        dropBuilder.append(catSw.toString());
15312        addErrorToDropBox("lowmem", null, "system_server", null,
15313                null, tag.toString(), dropBuilder.toString(), null, null);
15314        //Slog.i(TAG, "Sent to dropbox:");
15315        //Slog.i(TAG, dropBuilder.toString());
15316        synchronized (ActivityManagerService.this) {
15317            long now = SystemClock.uptimeMillis();
15318            if (mLastMemUsageReportTime < now) {
15319                mLastMemUsageReportTime = now;
15320            }
15321        }
15322    }
15323
15324    /**
15325     * Searches array of arguments for the specified string
15326     * @param args array of argument strings
15327     * @param value value to search for
15328     * @return true if the value is contained in the array
15329     */
15330    private static boolean scanArgs(String[] args, String value) {
15331        if (args != null) {
15332            for (String arg : args) {
15333                if (value.equals(arg)) {
15334                    return true;
15335                }
15336            }
15337        }
15338        return false;
15339    }
15340
15341    private final boolean removeDyingProviderLocked(ProcessRecord proc,
15342            ContentProviderRecord cpr, boolean always) {
15343        final boolean inLaunching = mLaunchingProviders.contains(cpr);
15344
15345        if (!inLaunching || always) {
15346            synchronized (cpr) {
15347                cpr.launchingApp = null;
15348                cpr.notifyAll();
15349            }
15350            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
15351            String names[] = cpr.info.authority.split(";");
15352            for (int j = 0; j < names.length; j++) {
15353                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
15354            }
15355        }
15356
15357        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
15358            ContentProviderConnection conn = cpr.connections.get(i);
15359            if (conn.waiting) {
15360                // If this connection is waiting for the provider, then we don't
15361                // need to mess with its process unless we are always removing
15362                // or for some reason the provider is not currently launching.
15363                if (inLaunching && !always) {
15364                    continue;
15365                }
15366            }
15367            ProcessRecord capp = conn.client;
15368            conn.dead = true;
15369            if (conn.stableCount > 0) {
15370                if (!capp.persistent && capp.thread != null
15371                        && capp.pid != 0
15372                        && capp.pid != MY_PID) {
15373                    capp.kill("depends on provider "
15374                            + cpr.name.flattenToShortString()
15375                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
15376                }
15377            } else if (capp.thread != null && conn.provider.provider != null) {
15378                try {
15379                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
15380                } catch (RemoteException e) {
15381                }
15382                // In the protocol here, we don't expect the client to correctly
15383                // clean up this connection, we'll just remove it.
15384                cpr.connections.remove(i);
15385                if (conn.client.conProviders.remove(conn)) {
15386                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
15387                }
15388            }
15389        }
15390
15391        if (inLaunching && always) {
15392            mLaunchingProviders.remove(cpr);
15393        }
15394        return inLaunching;
15395    }
15396
15397    /**
15398     * Main code for cleaning up a process when it has gone away.  This is
15399     * called both as a result of the process dying, or directly when stopping
15400     * a process when running in single process mode.
15401     *
15402     * @return Returns true if the given process has been restarted, so the
15403     * app that was passed in must remain on the process lists.
15404     */
15405    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
15406            boolean restarting, boolean allowRestart, int index) {
15407        if (index >= 0) {
15408            removeLruProcessLocked(app);
15409            ProcessList.remove(app.pid);
15410        }
15411
15412        mProcessesToGc.remove(app);
15413        mPendingPssProcesses.remove(app);
15414
15415        // Dismiss any open dialogs.
15416        if (app.crashDialog != null && !app.forceCrashReport) {
15417            app.crashDialog.dismiss();
15418            app.crashDialog = null;
15419        }
15420        if (app.anrDialog != null) {
15421            app.anrDialog.dismiss();
15422            app.anrDialog = null;
15423        }
15424        if (app.waitDialog != null) {
15425            app.waitDialog.dismiss();
15426            app.waitDialog = null;
15427        }
15428
15429        app.crashing = false;
15430        app.notResponding = false;
15431
15432        app.resetPackageList(mProcessStats);
15433        app.unlinkDeathRecipient();
15434        app.makeInactive(mProcessStats);
15435        app.waitingToKill = null;
15436        app.forcingToForeground = null;
15437        updateProcessForegroundLocked(app, false, false);
15438        app.foregroundActivities = false;
15439        app.hasShownUi = false;
15440        app.treatLikeActivity = false;
15441        app.hasAboveClient = false;
15442        app.hasClientActivities = false;
15443
15444        mServices.killServicesLocked(app, allowRestart);
15445
15446        boolean restart = false;
15447
15448        // Remove published content providers.
15449        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
15450            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
15451            final boolean always = app.bad || !allowRestart;
15452            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
15453            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
15454                // We left the provider in the launching list, need to
15455                // restart it.
15456                restart = true;
15457            }
15458
15459            cpr.provider = null;
15460            cpr.proc = null;
15461        }
15462        app.pubProviders.clear();
15463
15464        // Take care of any launching providers waiting for this process.
15465        if (checkAppInLaunchingProvidersLocked(app, false)) {
15466            restart = true;
15467        }
15468
15469        // Unregister from connected content providers.
15470        if (!app.conProviders.isEmpty()) {
15471            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
15472                ContentProviderConnection conn = app.conProviders.get(i);
15473                conn.provider.connections.remove(conn);
15474                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
15475                        conn.provider.name);
15476            }
15477            app.conProviders.clear();
15478        }
15479
15480        // At this point there may be remaining entries in mLaunchingProviders
15481        // where we were the only one waiting, so they are no longer of use.
15482        // Look for these and clean up if found.
15483        // XXX Commented out for now.  Trying to figure out a way to reproduce
15484        // the actual situation to identify what is actually going on.
15485        if (false) {
15486            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15487                ContentProviderRecord cpr = mLaunchingProviders.get(i);
15488                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
15489                    synchronized (cpr) {
15490                        cpr.launchingApp = null;
15491                        cpr.notifyAll();
15492                    }
15493                }
15494            }
15495        }
15496
15497        skipCurrentReceiverLocked(app);
15498
15499        // Unregister any receivers.
15500        for (int i = app.receivers.size() - 1; i >= 0; i--) {
15501            removeReceiverLocked(app.receivers.valueAt(i));
15502        }
15503        app.receivers.clear();
15504
15505        // If the app is undergoing backup, tell the backup manager about it
15506        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
15507            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
15508                    + mBackupTarget.appInfo + " died during backup");
15509            try {
15510                IBackupManager bm = IBackupManager.Stub.asInterface(
15511                        ServiceManager.getService(Context.BACKUP_SERVICE));
15512                bm.agentDisconnected(app.info.packageName);
15513            } catch (RemoteException e) {
15514                // can't happen; backup manager is local
15515            }
15516        }
15517
15518        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
15519            ProcessChangeItem item = mPendingProcessChanges.get(i);
15520            if (item.pid == app.pid) {
15521                mPendingProcessChanges.remove(i);
15522                mAvailProcessChanges.add(item);
15523            }
15524        }
15525        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
15526
15527        // If the caller is restarting this app, then leave it in its
15528        // current lists and let the caller take care of it.
15529        if (restarting) {
15530            return false;
15531        }
15532
15533        if (!app.persistent || app.isolated) {
15534            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
15535                    "Removing non-persistent process during cleanup: " + app);
15536            removeProcessNameLocked(app.processName, app.uid);
15537            if (mHeavyWeightProcess == app) {
15538                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
15539                        mHeavyWeightProcess.userId, 0));
15540                mHeavyWeightProcess = null;
15541            }
15542        } else if (!app.removed) {
15543            // This app is persistent, so we need to keep its record around.
15544            // If it is not already on the pending app list, add it there
15545            // and start a new process for it.
15546            if (mPersistentStartingProcesses.indexOf(app) < 0) {
15547                mPersistentStartingProcesses.add(app);
15548                restart = true;
15549            }
15550        }
15551        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
15552                TAG_CLEANUP, "Clean-up removing on hold: " + app);
15553        mProcessesOnHold.remove(app);
15554
15555        if (app == mHomeProcess) {
15556            mHomeProcess = null;
15557        }
15558        if (app == mPreviousProcess) {
15559            mPreviousProcess = null;
15560        }
15561
15562        if (restart && !app.isolated) {
15563            // We have components that still need to be running in the
15564            // process, so re-launch it.
15565            if (index < 0) {
15566                ProcessList.remove(app.pid);
15567            }
15568            addProcessNameLocked(app);
15569            startProcessLocked(app, "restart", app.processName);
15570            return true;
15571        } else if (app.pid > 0 && app.pid != MY_PID) {
15572            // Goodbye!
15573            boolean removed;
15574            synchronized (mPidsSelfLocked) {
15575                mPidsSelfLocked.remove(app.pid);
15576                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
15577            }
15578            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
15579            if (app.isolated) {
15580                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
15581            }
15582            app.setPid(0);
15583        }
15584        return false;
15585    }
15586
15587    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
15588        // Look through the content providers we are waiting to have launched,
15589        // and if any run in this process then either schedule a restart of
15590        // the process or kill the client waiting for it if this process has
15591        // gone bad.
15592        boolean restart = false;
15593        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15594            ContentProviderRecord cpr = mLaunchingProviders.get(i);
15595            if (cpr.launchingApp == app) {
15596                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
15597                    restart = true;
15598                } else {
15599                    removeDyingProviderLocked(app, cpr, true);
15600                }
15601            }
15602        }
15603        return restart;
15604    }
15605
15606    // =========================================================
15607    // SERVICES
15608    // =========================================================
15609
15610    @Override
15611    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
15612            int flags) {
15613        enforceNotIsolatedCaller("getServices");
15614        synchronized (this) {
15615            return mServices.getRunningServiceInfoLocked(maxNum, flags);
15616        }
15617    }
15618
15619    @Override
15620    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
15621        enforceNotIsolatedCaller("getRunningServiceControlPanel");
15622        synchronized (this) {
15623            return mServices.getRunningServiceControlPanelLocked(name);
15624        }
15625    }
15626
15627    @Override
15628    public ComponentName startService(IApplicationThread caller, Intent service,
15629            String resolvedType, String callingPackage, int userId)
15630            throws TransactionTooLargeException {
15631        enforceNotIsolatedCaller("startService");
15632        // Refuse possible leaked file descriptors
15633        if (service != null && service.hasFileDescriptors() == true) {
15634            throw new IllegalArgumentException("File descriptors passed in Intent");
15635        }
15636
15637        if (callingPackage == null) {
15638            throw new IllegalArgumentException("callingPackage cannot be null");
15639        }
15640
15641        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15642                "startService: " + service + " type=" + resolvedType);
15643        synchronized(this) {
15644            final int callingPid = Binder.getCallingPid();
15645            final int callingUid = Binder.getCallingUid();
15646            final long origId = Binder.clearCallingIdentity();
15647            ComponentName res = mServices.startServiceLocked(caller, service,
15648                    resolvedType, callingPid, callingUid, callingPackage, userId);
15649            Binder.restoreCallingIdentity(origId);
15650            return res;
15651        }
15652    }
15653
15654    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
15655            String callingPackage, int userId)
15656            throws TransactionTooLargeException {
15657        synchronized(this) {
15658            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15659                    "startServiceInPackage: " + service + " type=" + resolvedType);
15660            final long origId = Binder.clearCallingIdentity();
15661            ComponentName res = mServices.startServiceLocked(null, service,
15662                    resolvedType, -1, uid, callingPackage, userId);
15663            Binder.restoreCallingIdentity(origId);
15664            return res;
15665        }
15666    }
15667
15668    @Override
15669    public int stopService(IApplicationThread caller, Intent service,
15670            String resolvedType, int userId) {
15671        enforceNotIsolatedCaller("stopService");
15672        // Refuse possible leaked file descriptors
15673        if (service != null && service.hasFileDescriptors() == true) {
15674            throw new IllegalArgumentException("File descriptors passed in Intent");
15675        }
15676
15677        synchronized(this) {
15678            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
15679        }
15680    }
15681
15682    @Override
15683    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
15684        enforceNotIsolatedCaller("peekService");
15685        // Refuse possible leaked file descriptors
15686        if (service != null && service.hasFileDescriptors() == true) {
15687            throw new IllegalArgumentException("File descriptors passed in Intent");
15688        }
15689
15690        if (callingPackage == null) {
15691            throw new IllegalArgumentException("callingPackage cannot be null");
15692        }
15693
15694        synchronized(this) {
15695            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
15696        }
15697    }
15698
15699    @Override
15700    public boolean stopServiceToken(ComponentName className, IBinder token,
15701            int startId) {
15702        synchronized(this) {
15703            return mServices.stopServiceTokenLocked(className, token, startId);
15704        }
15705    }
15706
15707    @Override
15708    public void setServiceForeground(ComponentName className, IBinder token,
15709            int id, Notification notification, boolean removeNotification) {
15710        synchronized(this) {
15711            mServices.setServiceForegroundLocked(className, token, id, notification,
15712                    removeNotification);
15713        }
15714    }
15715
15716    @Override
15717    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15718            boolean requireFull, String name, String callerPackage) {
15719        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15720                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15721    }
15722
15723    int unsafeConvertIncomingUser(int userId) {
15724        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15725                ? mCurrentUserId : userId;
15726    }
15727
15728    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15729            int allowMode, String name, String callerPackage) {
15730        final int callingUserId = UserHandle.getUserId(callingUid);
15731        if (callingUserId == userId) {
15732            return userId;
15733        }
15734
15735        // Note that we may be accessing mCurrentUserId outside of a lock...
15736        // shouldn't be a big deal, if this is being called outside
15737        // of a locked context there is intrinsically a race with
15738        // the value the caller will receive and someone else changing it.
15739        // We assume that USER_CURRENT_OR_SELF will use the current user; later
15740        // we will switch to the calling user if access to the current user fails.
15741        int targetUserId = unsafeConvertIncomingUser(userId);
15742
15743        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15744            final boolean allow;
15745            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15746                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15747                // If the caller has this permission, they always pass go.  And collect $200.
15748                allow = true;
15749            } else if (allowMode == ALLOW_FULL_ONLY) {
15750                // We require full access, sucks to be you.
15751                allow = false;
15752            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15753                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15754                // If the caller does not have either permission, they are always doomed.
15755                allow = false;
15756            } else if (allowMode == ALLOW_NON_FULL) {
15757                // We are blanket allowing non-full access, you lucky caller!
15758                allow = true;
15759            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15760                // We may or may not allow this depending on whether the two users are
15761                // in the same profile.
15762                synchronized (mUserProfileGroupIdsSelfLocked) {
15763                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15764                            UserInfo.NO_PROFILE_GROUP_ID);
15765                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15766                            UserInfo.NO_PROFILE_GROUP_ID);
15767                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15768                            && callingProfile == targetProfile;
15769                }
15770            } else {
15771                throw new IllegalArgumentException("Unknown mode: " + allowMode);
15772            }
15773            if (!allow) {
15774                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15775                    // In this case, they would like to just execute as their
15776                    // owner user instead of failing.
15777                    targetUserId = callingUserId;
15778                } else {
15779                    StringBuilder builder = new StringBuilder(128);
15780                    builder.append("Permission Denial: ");
15781                    builder.append(name);
15782                    if (callerPackage != null) {
15783                        builder.append(" from ");
15784                        builder.append(callerPackage);
15785                    }
15786                    builder.append(" asks to run as user ");
15787                    builder.append(userId);
15788                    builder.append(" but is calling from user ");
15789                    builder.append(UserHandle.getUserId(callingUid));
15790                    builder.append("; this requires ");
15791                    builder.append(INTERACT_ACROSS_USERS_FULL);
15792                    if (allowMode != ALLOW_FULL_ONLY) {
15793                        builder.append(" or ");
15794                        builder.append(INTERACT_ACROSS_USERS);
15795                    }
15796                    String msg = builder.toString();
15797                    Slog.w(TAG, msg);
15798                    throw new SecurityException(msg);
15799                }
15800            }
15801        }
15802        if (!allowAll && targetUserId < 0) {
15803            throw new IllegalArgumentException(
15804                    "Call does not support special user #" + targetUserId);
15805        }
15806        // Check shell permission
15807        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15808            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15809                    targetUserId)) {
15810                throw new SecurityException("Shell does not have permission to access user "
15811                        + targetUserId + "\n " + Debug.getCallers(3));
15812            }
15813        }
15814        return targetUserId;
15815    }
15816
15817    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15818            String className, int flags) {
15819        boolean result = false;
15820        // For apps that don't have pre-defined UIDs, check for permission
15821        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15822            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15823                if (ActivityManager.checkUidPermission(
15824                        INTERACT_ACROSS_USERS,
15825                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15826                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15827                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15828                            + " requests FLAG_SINGLE_USER, but app does not hold "
15829                            + INTERACT_ACROSS_USERS;
15830                    Slog.w(TAG, msg);
15831                    throw new SecurityException(msg);
15832                }
15833                // Permission passed
15834                result = true;
15835            }
15836        } else if ("system".equals(componentProcessName)) {
15837            result = true;
15838        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15839            // Phone app and persistent apps are allowed to export singleuser providers.
15840            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15841                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15842        }
15843        if (DEBUG_MU) Slog.v(TAG_MU,
15844                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
15845                + Integer.toHexString(flags) + ") = " + result);
15846        return result;
15847    }
15848
15849    /**
15850     * Checks to see if the caller is in the same app as the singleton
15851     * component, or the component is in a special app. It allows special apps
15852     * to export singleton components but prevents exporting singleton
15853     * components for regular apps.
15854     */
15855    boolean isValidSingletonCall(int callingUid, int componentUid) {
15856        int componentAppId = UserHandle.getAppId(componentUid);
15857        return UserHandle.isSameApp(callingUid, componentUid)
15858                || componentAppId == Process.SYSTEM_UID
15859                || componentAppId == Process.PHONE_UID
15860                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15861                        == PackageManager.PERMISSION_GRANTED;
15862    }
15863
15864    public int bindService(IApplicationThread caller, IBinder token, Intent service,
15865            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
15866            int userId) throws TransactionTooLargeException {
15867        enforceNotIsolatedCaller("bindService");
15868
15869        // Refuse possible leaked file descriptors
15870        if (service != null && service.hasFileDescriptors() == true) {
15871            throw new IllegalArgumentException("File descriptors passed in Intent");
15872        }
15873
15874        if (callingPackage == null) {
15875            throw new IllegalArgumentException("callingPackage cannot be null");
15876        }
15877
15878        synchronized(this) {
15879            return mServices.bindServiceLocked(caller, token, service,
15880                    resolvedType, connection, flags, callingPackage, userId);
15881        }
15882    }
15883
15884    public boolean unbindService(IServiceConnection connection) {
15885        synchronized (this) {
15886            return mServices.unbindServiceLocked(connection);
15887        }
15888    }
15889
15890    public void publishService(IBinder token, Intent intent, IBinder service) {
15891        // Refuse possible leaked file descriptors
15892        if (intent != null && intent.hasFileDescriptors() == true) {
15893            throw new IllegalArgumentException("File descriptors passed in Intent");
15894        }
15895
15896        synchronized(this) {
15897            if (!(token instanceof ServiceRecord)) {
15898                throw new IllegalArgumentException("Invalid service token");
15899            }
15900            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15901        }
15902    }
15903
15904    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15905        // Refuse possible leaked file descriptors
15906        if (intent != null && intent.hasFileDescriptors() == true) {
15907            throw new IllegalArgumentException("File descriptors passed in Intent");
15908        }
15909
15910        synchronized(this) {
15911            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15912        }
15913    }
15914
15915    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15916        synchronized(this) {
15917            if (!(token instanceof ServiceRecord)) {
15918                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
15919                throw new IllegalArgumentException("Invalid service token");
15920            }
15921            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15922        }
15923    }
15924
15925    // =========================================================
15926    // BACKUP AND RESTORE
15927    // =========================================================
15928
15929    // Cause the target app to be launched if necessary and its backup agent
15930    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15931    // activity manager to announce its creation.
15932    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15933        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
15934                "bindBackupAgent: app=" + app + " mode=" + backupMode);
15935        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15936
15937        synchronized(this) {
15938            // !!! TODO: currently no check here that we're already bound
15939            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15940            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15941            synchronized (stats) {
15942                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15943            }
15944
15945            // Backup agent is now in use, its package can't be stopped.
15946            try {
15947                AppGlobals.getPackageManager().setPackageStoppedState(
15948                        app.packageName, false, UserHandle.getUserId(app.uid));
15949            } catch (RemoteException e) {
15950            } catch (IllegalArgumentException e) {
15951                Slog.w(TAG, "Failed trying to unstop package "
15952                        + app.packageName + ": " + e);
15953            }
15954
15955            BackupRecord r = new BackupRecord(ss, app, backupMode);
15956            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15957                    ? new ComponentName(app.packageName, app.backupAgentName)
15958                    : new ComponentName("android", "FullBackupAgent");
15959            // startProcessLocked() returns existing proc's record if it's already running
15960            ProcessRecord proc = startProcessLocked(app.processName, app,
15961                    false, 0, "backup", hostingName, false, false, false);
15962            if (proc == null) {
15963                Slog.e(TAG, "Unable to start backup agent process " + r);
15964                return false;
15965            }
15966
15967            r.app = proc;
15968            mBackupTarget = r;
15969            mBackupAppName = app.packageName;
15970
15971            // Try not to kill the process during backup
15972            updateOomAdjLocked(proc);
15973
15974            // If the process is already attached, schedule the creation of the backup agent now.
15975            // If it is not yet live, this will be done when it attaches to the framework.
15976            if (proc.thread != null) {
15977                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
15978                try {
15979                    proc.thread.scheduleCreateBackupAgent(app,
15980                            compatibilityInfoForPackageLocked(app), backupMode);
15981                } catch (RemoteException e) {
15982                    // Will time out on the backup manager side
15983                }
15984            } else {
15985                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
15986            }
15987            // Invariants: at this point, the target app process exists and the application
15988            // is either already running or in the process of coming up.  mBackupTarget and
15989            // mBackupAppName describe the app, so that when it binds back to the AM we
15990            // know that it's scheduled for a backup-agent operation.
15991        }
15992
15993        return true;
15994    }
15995
15996    @Override
15997    public void clearPendingBackup() {
15998        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
15999        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16000
16001        synchronized (this) {
16002            mBackupTarget = null;
16003            mBackupAppName = null;
16004        }
16005    }
16006
16007    // A backup agent has just come up
16008    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16009        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16010                + " = " + agent);
16011
16012        synchronized(this) {
16013            if (!agentPackageName.equals(mBackupAppName)) {
16014                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16015                return;
16016            }
16017        }
16018
16019        long oldIdent = Binder.clearCallingIdentity();
16020        try {
16021            IBackupManager bm = IBackupManager.Stub.asInterface(
16022                    ServiceManager.getService(Context.BACKUP_SERVICE));
16023            bm.agentConnected(agentPackageName, agent);
16024        } catch (RemoteException e) {
16025            // can't happen; the backup manager service is local
16026        } catch (Exception e) {
16027            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16028            e.printStackTrace();
16029        } finally {
16030            Binder.restoreCallingIdentity(oldIdent);
16031        }
16032    }
16033
16034    // done with this agent
16035    public void unbindBackupAgent(ApplicationInfo appInfo) {
16036        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16037        if (appInfo == null) {
16038            Slog.w(TAG, "unbind backup agent for null app");
16039            return;
16040        }
16041
16042        synchronized(this) {
16043            try {
16044                if (mBackupAppName == null) {
16045                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16046                    return;
16047                }
16048
16049                if (!mBackupAppName.equals(appInfo.packageName)) {
16050                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16051                    return;
16052                }
16053
16054                // Not backing this app up any more; reset its OOM adjustment
16055                final ProcessRecord proc = mBackupTarget.app;
16056                updateOomAdjLocked(proc);
16057
16058                // If the app crashed during backup, 'thread' will be null here
16059                if (proc.thread != null) {
16060                    try {
16061                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16062                                compatibilityInfoForPackageLocked(appInfo));
16063                    } catch (Exception e) {
16064                        Slog.e(TAG, "Exception when unbinding backup agent:");
16065                        e.printStackTrace();
16066                    }
16067                }
16068            } finally {
16069                mBackupTarget = null;
16070                mBackupAppName = null;
16071            }
16072        }
16073    }
16074    // =========================================================
16075    // BROADCASTS
16076    // =========================================================
16077
16078    boolean isPendingBroadcastProcessLocked(int pid) {
16079        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16080                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16081    }
16082
16083    void skipPendingBroadcastLocked(int pid) {
16084            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16085            for (BroadcastQueue queue : mBroadcastQueues) {
16086                queue.skipPendingBroadcastLocked(pid);
16087            }
16088    }
16089
16090    // The app just attached; send any pending broadcasts that it should receive
16091    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16092        boolean didSomething = false;
16093        for (BroadcastQueue queue : mBroadcastQueues) {
16094            didSomething |= queue.sendPendingBroadcastsLocked(app);
16095        }
16096        return didSomething;
16097    }
16098
16099    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16100            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16101        enforceNotIsolatedCaller("registerReceiver");
16102        ArrayList<Intent> stickyIntents = null;
16103        ProcessRecord callerApp = null;
16104        int callingUid;
16105        int callingPid;
16106        synchronized(this) {
16107            if (caller != null) {
16108                callerApp = getRecordForAppLocked(caller);
16109                if (callerApp == null) {
16110                    throw new SecurityException(
16111                            "Unable to find app for caller " + caller
16112                            + " (pid=" + Binder.getCallingPid()
16113                            + ") when registering receiver " + receiver);
16114                }
16115                if (callerApp.info.uid != Process.SYSTEM_UID &&
16116                        !callerApp.pkgList.containsKey(callerPackage) &&
16117                        !"android".equals(callerPackage)) {
16118                    throw new SecurityException("Given caller package " + callerPackage
16119                            + " is not running in process " + callerApp);
16120                }
16121                callingUid = callerApp.info.uid;
16122                callingPid = callerApp.pid;
16123            } else {
16124                callerPackage = null;
16125                callingUid = Binder.getCallingUid();
16126                callingPid = Binder.getCallingPid();
16127            }
16128
16129            userId = handleIncomingUser(callingPid, callingUid, userId,
16130                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16131
16132            Iterator<String> actions = filter.actionsIterator();
16133            if (actions == null) {
16134                ArrayList<String> noAction = new ArrayList<String>(1);
16135                noAction.add(null);
16136                actions = noAction.iterator();
16137            }
16138
16139            // Collect stickies of users
16140            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16141            while (actions.hasNext()) {
16142                String action = actions.next();
16143                for (int id : userIds) {
16144                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16145                    if (stickies != null) {
16146                        ArrayList<Intent> intents = stickies.get(action);
16147                        if (intents != null) {
16148                            if (stickyIntents == null) {
16149                                stickyIntents = new ArrayList<Intent>();
16150                            }
16151                            stickyIntents.addAll(intents);
16152                        }
16153                    }
16154                }
16155            }
16156        }
16157
16158        ArrayList<Intent> allSticky = null;
16159        if (stickyIntents != null) {
16160            final ContentResolver resolver = mContext.getContentResolver();
16161            // Look for any matching sticky broadcasts...
16162            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16163                Intent intent = stickyIntents.get(i);
16164                // If intent has scheme "content", it will need to acccess
16165                // provider that needs to lock mProviderMap in ActivityThread
16166                // and also it may need to wait application response, so we
16167                // cannot lock ActivityManagerService here.
16168                if (filter.match(resolver, intent, true, TAG) >= 0) {
16169                    if (allSticky == null) {
16170                        allSticky = new ArrayList<Intent>();
16171                    }
16172                    allSticky.add(intent);
16173                }
16174            }
16175        }
16176
16177        // The first sticky in the list is returned directly back to the client.
16178        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16179        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16180        if (receiver == null) {
16181            return sticky;
16182        }
16183
16184        synchronized (this) {
16185            if (callerApp != null && (callerApp.thread == null
16186                    || callerApp.thread.asBinder() != caller.asBinder())) {
16187                // Original caller already died
16188                return null;
16189            }
16190            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16191            if (rl == null) {
16192                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16193                        userId, receiver);
16194                if (rl.app != null) {
16195                    rl.app.receivers.add(rl);
16196                } else {
16197                    try {
16198                        receiver.asBinder().linkToDeath(rl, 0);
16199                    } catch (RemoteException e) {
16200                        return sticky;
16201                    }
16202                    rl.linkedToDeath = true;
16203                }
16204                mRegisteredReceivers.put(receiver.asBinder(), rl);
16205            } else if (rl.uid != callingUid) {
16206                throw new IllegalArgumentException(
16207                        "Receiver requested to register for uid " + callingUid
16208                        + " was previously registered for uid " + rl.uid);
16209            } else if (rl.pid != callingPid) {
16210                throw new IllegalArgumentException(
16211                        "Receiver requested to register for pid " + callingPid
16212                        + " was previously registered for pid " + rl.pid);
16213            } else if (rl.userId != userId) {
16214                throw new IllegalArgumentException(
16215                        "Receiver requested to register for user " + userId
16216                        + " was previously registered for user " + rl.userId);
16217            }
16218            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16219                    permission, callingUid, userId);
16220            rl.add(bf);
16221            if (!bf.debugCheck()) {
16222                Slog.w(TAG, "==> For Dynamic broadcast");
16223            }
16224            mReceiverResolver.addFilter(bf);
16225
16226            // Enqueue broadcasts for all existing stickies that match
16227            // this filter.
16228            if (allSticky != null) {
16229                ArrayList receivers = new ArrayList();
16230                receivers.add(bf);
16231
16232                final int stickyCount = allSticky.size();
16233                for (int i = 0; i < stickyCount; i++) {
16234                    Intent intent = allSticky.get(i);
16235                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16236                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16237                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16238                            null, 0, null, null, false, true, true, -1);
16239                    queue.enqueueParallelBroadcastLocked(r);
16240                    queue.scheduleBroadcastsLocked();
16241                }
16242            }
16243
16244            return sticky;
16245        }
16246    }
16247
16248    public void unregisterReceiver(IIntentReceiver receiver) {
16249        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16250
16251        final long origId = Binder.clearCallingIdentity();
16252        try {
16253            boolean doTrim = false;
16254
16255            synchronized(this) {
16256                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16257                if (rl != null) {
16258                    final BroadcastRecord r = rl.curBroadcast;
16259                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16260                        final boolean doNext = r.queue.finishReceiverLocked(
16261                                r, r.resultCode, r.resultData, r.resultExtras,
16262                                r.resultAbort, false);
16263                        if (doNext) {
16264                            doTrim = true;
16265                            r.queue.processNextBroadcast(false);
16266                        }
16267                    }
16268
16269                    if (rl.app != null) {
16270                        rl.app.receivers.remove(rl);
16271                    }
16272                    removeReceiverLocked(rl);
16273                    if (rl.linkedToDeath) {
16274                        rl.linkedToDeath = false;
16275                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
16276                    }
16277                }
16278            }
16279
16280            // If we actually concluded any broadcasts, we might now be able
16281            // to trim the recipients' apps from our working set
16282            if (doTrim) {
16283                trimApplications();
16284                return;
16285            }
16286
16287        } finally {
16288            Binder.restoreCallingIdentity(origId);
16289        }
16290    }
16291
16292    void removeReceiverLocked(ReceiverList rl) {
16293        mRegisteredReceivers.remove(rl.receiver.asBinder());
16294        for (int i = rl.size() - 1; i >= 0; i--) {
16295            mReceiverResolver.removeFilter(rl.get(i));
16296        }
16297    }
16298
16299    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16300        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16301            ProcessRecord r = mLruProcesses.get(i);
16302            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16303                try {
16304                    r.thread.dispatchPackageBroadcast(cmd, packages);
16305                } catch (RemoteException ex) {
16306                }
16307            }
16308        }
16309    }
16310
16311    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16312            int callingUid, int[] users) {
16313        List<ResolveInfo> receivers = null;
16314        try {
16315            HashSet<ComponentName> singleUserReceivers = null;
16316            boolean scannedFirstReceivers = false;
16317            for (int user : users) {
16318                // Skip users that have Shell restrictions
16319                if (callingUid == Process.SHELL_UID
16320                        && getUserManagerLocked().hasUserRestriction(
16321                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
16322                    continue;
16323                }
16324                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16325                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
16326                if (user != UserHandle.USER_OWNER && newReceivers != null) {
16327                    // If this is not the primary user, we need to check for
16328                    // any receivers that should be filtered out.
16329                    for (int i=0; i<newReceivers.size(); i++) {
16330                        ResolveInfo ri = newReceivers.get(i);
16331                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
16332                            newReceivers.remove(i);
16333                            i--;
16334                        }
16335                    }
16336                }
16337                if (newReceivers != null && newReceivers.size() == 0) {
16338                    newReceivers = null;
16339                }
16340                if (receivers == null) {
16341                    receivers = newReceivers;
16342                } else if (newReceivers != null) {
16343                    // We need to concatenate the additional receivers
16344                    // found with what we have do far.  This would be easy,
16345                    // but we also need to de-dup any receivers that are
16346                    // singleUser.
16347                    if (!scannedFirstReceivers) {
16348                        // Collect any single user receivers we had already retrieved.
16349                        scannedFirstReceivers = true;
16350                        for (int i=0; i<receivers.size(); i++) {
16351                            ResolveInfo ri = receivers.get(i);
16352                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16353                                ComponentName cn = new ComponentName(
16354                                        ri.activityInfo.packageName, ri.activityInfo.name);
16355                                if (singleUserReceivers == null) {
16356                                    singleUserReceivers = new HashSet<ComponentName>();
16357                                }
16358                                singleUserReceivers.add(cn);
16359                            }
16360                        }
16361                    }
16362                    // Add the new results to the existing results, tracking
16363                    // and de-dupping single user receivers.
16364                    for (int i=0; i<newReceivers.size(); i++) {
16365                        ResolveInfo ri = newReceivers.get(i);
16366                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16367                            ComponentName cn = new ComponentName(
16368                                    ri.activityInfo.packageName, ri.activityInfo.name);
16369                            if (singleUserReceivers == null) {
16370                                singleUserReceivers = new HashSet<ComponentName>();
16371                            }
16372                            if (!singleUserReceivers.contains(cn)) {
16373                                singleUserReceivers.add(cn);
16374                                receivers.add(ri);
16375                            }
16376                        } else {
16377                            receivers.add(ri);
16378                        }
16379                    }
16380                }
16381            }
16382        } catch (RemoteException ex) {
16383            // pm is in same process, this will never happen.
16384        }
16385        return receivers;
16386    }
16387
16388    private final int broadcastIntentLocked(ProcessRecord callerApp,
16389            String callerPackage, Intent intent, String resolvedType,
16390            IIntentReceiver resultTo, int resultCode, String resultData,
16391            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle options,
16392            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
16393        intent = new Intent(intent);
16394
16395        // By default broadcasts do not go to stopped apps.
16396        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
16397
16398        // If we have not finished booting, don't allow this to launch new processes.
16399        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
16400            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16401        }
16402
16403        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
16404                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
16405                + " ordered=" + ordered + " userid=" + userId);
16406        if ((resultTo != null) && !ordered) {
16407            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
16408        }
16409
16410        userId = handleIncomingUser(callingPid, callingUid, userId,
16411                true, ALLOW_NON_FULL, "broadcast", callerPackage);
16412
16413        // Make sure that the user who is receiving this broadcast is running.
16414        // If not, we will just skip it. Make an exception for shutdown broadcasts
16415        // and upgrade steps.
16416
16417        if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
16418            if ((callingUid != Process.SYSTEM_UID
16419                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
16420                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
16421                Slog.w(TAG, "Skipping broadcast of " + intent
16422                        + ": user " + userId + " is stopped");
16423                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
16424            }
16425        }
16426
16427        BroadcastOptions brOptions = null;
16428        if (options != null) {
16429            brOptions = new BroadcastOptions(options);
16430            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
16431                // See if the caller is allowed to do this.  Note we are checking against
16432                // the actual real caller (not whoever provided the operation as say a
16433                // PendingIntent), because that who is actually supplied the arguments.
16434                if (checkComponentPermission(
16435                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
16436                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
16437                        != PackageManager.PERMISSION_GRANTED) {
16438                    String msg = "Permission Denial: " + intent.getAction()
16439                            + " broadcast from " + callerPackage + " (pid=" + callingPid
16440                            + ", uid=" + callingUid + ")"
16441                            + " requires "
16442                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
16443                    Slog.w(TAG, msg);
16444                    throw new SecurityException(msg);
16445                }
16446            }
16447        }
16448
16449        /*
16450         * Prevent non-system code (defined here to be non-persistent
16451         * processes) from sending protected broadcasts.
16452         */
16453        int callingAppId = UserHandle.getAppId(callingUid);
16454        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
16455            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
16456            || callingAppId == Process.NFC_UID || callingUid == 0) {
16457            // Always okay.
16458        } else if (callerApp == null || !callerApp.persistent) {
16459            try {
16460                if (AppGlobals.getPackageManager().isProtectedBroadcast(
16461                        intent.getAction())) {
16462                    String msg = "Permission Denial: not allowed to send broadcast "
16463                            + intent.getAction() + " from pid="
16464                            + callingPid + ", uid=" + callingUid;
16465                    Slog.w(TAG, msg);
16466                    throw new SecurityException(msg);
16467                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
16468                    // Special case for compatibility: we don't want apps to send this,
16469                    // but historically it has not been protected and apps may be using it
16470                    // to poke their own app widget.  So, instead of making it protected,
16471                    // just limit it to the caller.
16472                    if (callerApp == null) {
16473                        String msg = "Permission Denial: not allowed to send broadcast "
16474                                + intent.getAction() + " from unknown caller.";
16475                        Slog.w(TAG, msg);
16476                        throw new SecurityException(msg);
16477                    } else if (intent.getComponent() != null) {
16478                        // They are good enough to send to an explicit component...  verify
16479                        // it is being sent to the calling app.
16480                        if (!intent.getComponent().getPackageName().equals(
16481                                callerApp.info.packageName)) {
16482                            String msg = "Permission Denial: not allowed to send broadcast "
16483                                    + intent.getAction() + " to "
16484                                    + intent.getComponent().getPackageName() + " from "
16485                                    + callerApp.info.packageName;
16486                            Slog.w(TAG, msg);
16487                            throw new SecurityException(msg);
16488                        }
16489                    } else {
16490                        // Limit broadcast to their own package.
16491                        intent.setPackage(callerApp.info.packageName);
16492                    }
16493                }
16494            } catch (RemoteException e) {
16495                Slog.w(TAG, "Remote exception", e);
16496                return ActivityManager.BROADCAST_SUCCESS;
16497            }
16498        }
16499
16500        final String action = intent.getAction();
16501        if (action != null) {
16502            switch (action) {
16503                case Intent.ACTION_UID_REMOVED:
16504                case Intent.ACTION_PACKAGE_REMOVED:
16505                case Intent.ACTION_PACKAGE_CHANGED:
16506                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16507                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16508                    // Handle special intents: if this broadcast is from the package
16509                    // manager about a package being removed, we need to remove all of
16510                    // its activities from the history stack.
16511                    if (checkComponentPermission(
16512                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
16513                            callingPid, callingUid, -1, true)
16514                            != PackageManager.PERMISSION_GRANTED) {
16515                        String msg = "Permission Denial: " + intent.getAction()
16516                                + " broadcast from " + callerPackage + " (pid=" + callingPid
16517                                + ", uid=" + callingUid + ")"
16518                                + " requires "
16519                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
16520                        Slog.w(TAG, msg);
16521                        throw new SecurityException(msg);
16522                    }
16523                    switch (action) {
16524                        case Intent.ACTION_UID_REMOVED:
16525                            final Bundle intentExtras = intent.getExtras();
16526                            final int uid = intentExtras != null
16527                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
16528                            if (uid >= 0) {
16529                                mBatteryStatsService.removeUid(uid);
16530                                mAppOpsService.uidRemoved(uid);
16531                            }
16532                            break;
16533                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16534                            // If resources are unavailable just force stop all those packages
16535                            // and flush the attribute cache as well.
16536                            String list[] =
16537                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16538                            if (list != null && list.length > 0) {
16539                                for (int i = 0; i < list.length; i++) {
16540                                    forceStopPackageLocked(list[i], -1, false, true, true,
16541                                            false, false, userId, "storage unmount");
16542                                }
16543                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16544                                sendPackageBroadcastLocked(
16545                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
16546                                        userId);
16547                            }
16548                            break;
16549                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16550                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16551                            break;
16552                        case Intent.ACTION_PACKAGE_REMOVED:
16553                        case Intent.ACTION_PACKAGE_CHANGED:
16554                            Uri data = intent.getData();
16555                            String ssp;
16556                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
16557                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
16558                                boolean fullUninstall = removed &&
16559                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16560                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
16561                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
16562                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
16563                                            false, true, true, false, fullUninstall, userId,
16564                                            removed ? "pkg removed" : "pkg changed");
16565                                }
16566                                if (removed) {
16567                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
16568                                            new String[] {ssp}, userId);
16569                                    if (fullUninstall) {
16570                                        mAppOpsService.packageRemoved(
16571                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
16572
16573                                        // Remove all permissions granted from/to this package
16574                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
16575
16576                                        removeTasksByPackageNameLocked(ssp, userId);
16577                                        mBatteryStatsService.notePackageUninstalled(ssp);
16578                                    }
16579                                } else {
16580                                    cleanupDisabledPackageComponentsLocked(ssp, userId,
16581                                            intent.getStringArrayExtra(
16582                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
16583                                }
16584                            }
16585                            break;
16586                    }
16587                    break;
16588                case Intent.ACTION_PACKAGE_ADDED:
16589                    // Special case for adding a package: by default turn on compatibility mode.
16590                    Uri data = intent.getData();
16591                    String ssp;
16592                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
16593                        final boolean replacing =
16594                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16595                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
16596
16597                        try {
16598                            ApplicationInfo ai = AppGlobals.getPackageManager().
16599                                    getApplicationInfo(ssp, 0, 0);
16600                            mBatteryStatsService.notePackageInstalled(ssp,
16601                                    ai != null ? ai.versionCode : 0);
16602                        } catch (RemoteException e) {
16603                        }
16604                    }
16605                    break;
16606                case Intent.ACTION_TIMEZONE_CHANGED:
16607                    // If this is the time zone changed action, queue up a message that will reset
16608                    // the timezone of all currently running processes. This message will get
16609                    // queued up before the broadcast happens.
16610                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
16611                    break;
16612                case Intent.ACTION_TIME_CHANGED:
16613                    // If the user set the time, let all running processes know.
16614                    final int is24Hour =
16615                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
16616                                    : 0;
16617                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
16618                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16619                    synchronized (stats) {
16620                        stats.noteCurrentTimeChangedLocked();
16621                    }
16622                    break;
16623                case Intent.ACTION_CLEAR_DNS_CACHE:
16624                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
16625                    break;
16626                case Proxy.PROXY_CHANGE_ACTION:
16627                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
16628                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
16629                    break;
16630            }
16631        }
16632
16633        // Add to the sticky list if requested.
16634        if (sticky) {
16635            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
16636                    callingPid, callingUid)
16637                    != PackageManager.PERMISSION_GRANTED) {
16638                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
16639                        + callingPid + ", uid=" + callingUid
16640                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16641                Slog.w(TAG, msg);
16642                throw new SecurityException(msg);
16643            }
16644            if (requiredPermissions != null && requiredPermissions.length > 0) {
16645                Slog.w(TAG, "Can't broadcast sticky intent " + intent
16646                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
16647                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
16648            }
16649            if (intent.getComponent() != null) {
16650                throw new SecurityException(
16651                        "Sticky broadcasts can't target a specific component");
16652            }
16653            // We use userId directly here, since the "all" target is maintained
16654            // as a separate set of sticky broadcasts.
16655            if (userId != UserHandle.USER_ALL) {
16656                // But first, if this is not a broadcast to all users, then
16657                // make sure it doesn't conflict with an existing broadcast to
16658                // all users.
16659                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
16660                        UserHandle.USER_ALL);
16661                if (stickies != null) {
16662                    ArrayList<Intent> list = stickies.get(intent.getAction());
16663                    if (list != null) {
16664                        int N = list.size();
16665                        int i;
16666                        for (i=0; i<N; i++) {
16667                            if (intent.filterEquals(list.get(i))) {
16668                                throw new IllegalArgumentException(
16669                                        "Sticky broadcast " + intent + " for user "
16670                                        + userId + " conflicts with existing global broadcast");
16671                            }
16672                        }
16673                    }
16674                }
16675            }
16676            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16677            if (stickies == null) {
16678                stickies = new ArrayMap<>();
16679                mStickyBroadcasts.put(userId, stickies);
16680            }
16681            ArrayList<Intent> list = stickies.get(intent.getAction());
16682            if (list == null) {
16683                list = new ArrayList<>();
16684                stickies.put(intent.getAction(), list);
16685            }
16686            final int stickiesCount = list.size();
16687            int i;
16688            for (i = 0; i < stickiesCount; i++) {
16689                if (intent.filterEquals(list.get(i))) {
16690                    // This sticky already exists, replace it.
16691                    list.set(i, new Intent(intent));
16692                    break;
16693                }
16694            }
16695            if (i >= stickiesCount) {
16696                list.add(new Intent(intent));
16697            }
16698        }
16699
16700        int[] users;
16701        if (userId == UserHandle.USER_ALL) {
16702            // Caller wants broadcast to go to all started users.
16703            users = mStartedUserArray;
16704        } else {
16705            // Caller wants broadcast to go to one specific user.
16706            users = new int[] {userId};
16707        }
16708
16709        // Figure out who all will receive this broadcast.
16710        List receivers = null;
16711        List<BroadcastFilter> registeredReceivers = null;
16712        // Need to resolve the intent to interested receivers...
16713        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
16714                 == 0) {
16715            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
16716        }
16717        if (intent.getComponent() == null) {
16718            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
16719                // Query one target user at a time, excluding shell-restricted users
16720                UserManagerService ums = getUserManagerLocked();
16721                for (int i = 0; i < users.length; i++) {
16722                    if (ums.hasUserRestriction(
16723                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
16724                        continue;
16725                    }
16726                    List<BroadcastFilter> registeredReceiversForUser =
16727                            mReceiverResolver.queryIntent(intent,
16728                                    resolvedType, false, users[i]);
16729                    if (registeredReceivers == null) {
16730                        registeredReceivers = registeredReceiversForUser;
16731                    } else if (registeredReceiversForUser != null) {
16732                        registeredReceivers.addAll(registeredReceiversForUser);
16733                    }
16734                }
16735            } else {
16736                registeredReceivers = mReceiverResolver.queryIntent(intent,
16737                        resolvedType, false, userId);
16738            }
16739        }
16740
16741        final boolean replacePending =
16742                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16743
16744        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
16745                + " replacePending=" + replacePending);
16746
16747        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16748        if (!ordered && NR > 0) {
16749            // If we are not serializing this broadcast, then send the
16750            // registered receivers separately so they don't wait for the
16751            // components to be launched.
16752            final BroadcastQueue queue = broadcastQueueForIntent(intent);
16753            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16754                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
16755                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
16756                    resultExtras, ordered, sticky, false, userId);
16757            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
16758            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16759            if (!replaced) {
16760                queue.enqueueParallelBroadcastLocked(r);
16761                queue.scheduleBroadcastsLocked();
16762            }
16763            registeredReceivers = null;
16764            NR = 0;
16765        }
16766
16767        // Merge into one list.
16768        int ir = 0;
16769        if (receivers != null) {
16770            // A special case for PACKAGE_ADDED: do not allow the package
16771            // being added to see this broadcast.  This prevents them from
16772            // using this as a back door to get run as soon as they are
16773            // installed.  Maybe in the future we want to have a special install
16774            // broadcast or such for apps, but we'd like to deliberately make
16775            // this decision.
16776            String skipPackages[] = null;
16777            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16778                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16779                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16780                Uri data = intent.getData();
16781                if (data != null) {
16782                    String pkgName = data.getSchemeSpecificPart();
16783                    if (pkgName != null) {
16784                        skipPackages = new String[] { pkgName };
16785                    }
16786                }
16787            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16788                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16789            }
16790            if (skipPackages != null && (skipPackages.length > 0)) {
16791                for (String skipPackage : skipPackages) {
16792                    if (skipPackage != null) {
16793                        int NT = receivers.size();
16794                        for (int it=0; it<NT; it++) {
16795                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
16796                            if (curt.activityInfo.packageName.equals(skipPackage)) {
16797                                receivers.remove(it);
16798                                it--;
16799                                NT--;
16800                            }
16801                        }
16802                    }
16803                }
16804            }
16805
16806            int NT = receivers != null ? receivers.size() : 0;
16807            int it = 0;
16808            ResolveInfo curt = null;
16809            BroadcastFilter curr = null;
16810            while (it < NT && ir < NR) {
16811                if (curt == null) {
16812                    curt = (ResolveInfo)receivers.get(it);
16813                }
16814                if (curr == null) {
16815                    curr = registeredReceivers.get(ir);
16816                }
16817                if (curr.getPriority() >= curt.priority) {
16818                    // Insert this broadcast record into the final list.
16819                    receivers.add(it, curr);
16820                    ir++;
16821                    curr = null;
16822                    it++;
16823                    NT++;
16824                } else {
16825                    // Skip to the next ResolveInfo in the final list.
16826                    it++;
16827                    curt = null;
16828                }
16829            }
16830        }
16831        while (ir < NR) {
16832            if (receivers == null) {
16833                receivers = new ArrayList();
16834            }
16835            receivers.add(registeredReceivers.get(ir));
16836            ir++;
16837        }
16838
16839        if ((receivers != null && receivers.size() > 0)
16840                || resultTo != null) {
16841            BroadcastQueue queue = broadcastQueueForIntent(intent);
16842            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16843                    callerPackage, callingPid, callingUid, resolvedType,
16844                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
16845                    resultData, resultExtras, ordered, sticky, false, userId);
16846
16847            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
16848                    + ": prev had " + queue.mOrderedBroadcasts.size());
16849            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
16850                    "Enqueueing broadcast " + r.intent.getAction());
16851
16852            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16853            if (!replaced) {
16854                queue.enqueueOrderedBroadcastLocked(r);
16855                queue.scheduleBroadcastsLocked();
16856            }
16857        }
16858
16859        return ActivityManager.BROADCAST_SUCCESS;
16860    }
16861
16862    final Intent verifyBroadcastLocked(Intent intent) {
16863        // Refuse possible leaked file descriptors
16864        if (intent != null && intent.hasFileDescriptors() == true) {
16865            throw new IllegalArgumentException("File descriptors passed in Intent");
16866        }
16867
16868        int flags = intent.getFlags();
16869
16870        if (!mProcessesReady) {
16871            // if the caller really truly claims to know what they're doing, go
16872            // ahead and allow the broadcast without launching any receivers
16873            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16874                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
16875            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16876                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16877                        + " before boot completion");
16878                throw new IllegalStateException("Cannot broadcast before boot completed");
16879            }
16880        }
16881
16882        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16883            throw new IllegalArgumentException(
16884                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16885        }
16886
16887        return intent;
16888    }
16889
16890    public final int broadcastIntent(IApplicationThread caller,
16891            Intent intent, String resolvedType, IIntentReceiver resultTo,
16892            int resultCode, String resultData, Bundle resultExtras,
16893            String[] requiredPermissions, int appOp, Bundle options,
16894            boolean serialized, boolean sticky, int userId) {
16895        enforceNotIsolatedCaller("broadcastIntent");
16896        synchronized(this) {
16897            intent = verifyBroadcastLocked(intent);
16898
16899            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16900            final int callingPid = Binder.getCallingPid();
16901            final int callingUid = Binder.getCallingUid();
16902            final long origId = Binder.clearCallingIdentity();
16903            int res = broadcastIntentLocked(callerApp,
16904                    callerApp != null ? callerApp.info.packageName : null,
16905                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
16906                    requiredPermissions, appOp, null, serialized, sticky,
16907                    callingPid, callingUid, userId);
16908            Binder.restoreCallingIdentity(origId);
16909            return res;
16910        }
16911    }
16912
16913
16914    int broadcastIntentInPackage(String packageName, int uid,
16915            Intent intent, String resolvedType, IIntentReceiver resultTo,
16916            int resultCode, String resultData, Bundle resultExtras,
16917            String requiredPermission, Bundle options, boolean serialized, boolean sticky,
16918            int userId) {
16919        synchronized(this) {
16920            intent = verifyBroadcastLocked(intent);
16921
16922            final long origId = Binder.clearCallingIdentity();
16923            String[] requiredPermissions = requiredPermission == null ? null
16924                    : new String[] {requiredPermission};
16925            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16926                    resultTo, resultCode, resultData, resultExtras,
16927                    requiredPermissions, AppOpsManager.OP_NONE, options, serialized,
16928                    sticky, -1, uid, userId);
16929            Binder.restoreCallingIdentity(origId);
16930            return res;
16931        }
16932    }
16933
16934    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16935        // Refuse possible leaked file descriptors
16936        if (intent != null && intent.hasFileDescriptors() == true) {
16937            throw new IllegalArgumentException("File descriptors passed in Intent");
16938        }
16939
16940        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16941                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16942
16943        synchronized(this) {
16944            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16945                    != PackageManager.PERMISSION_GRANTED) {
16946                String msg = "Permission Denial: unbroadcastIntent() from pid="
16947                        + Binder.getCallingPid()
16948                        + ", uid=" + Binder.getCallingUid()
16949                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16950                Slog.w(TAG, msg);
16951                throw new SecurityException(msg);
16952            }
16953            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16954            if (stickies != null) {
16955                ArrayList<Intent> list = stickies.get(intent.getAction());
16956                if (list != null) {
16957                    int N = list.size();
16958                    int i;
16959                    for (i=0; i<N; i++) {
16960                        if (intent.filterEquals(list.get(i))) {
16961                            list.remove(i);
16962                            break;
16963                        }
16964                    }
16965                    if (list.size() <= 0) {
16966                        stickies.remove(intent.getAction());
16967                    }
16968                }
16969                if (stickies.size() <= 0) {
16970                    mStickyBroadcasts.remove(userId);
16971                }
16972            }
16973        }
16974    }
16975
16976    void backgroundServicesFinishedLocked(int userId) {
16977        for (BroadcastQueue queue : mBroadcastQueues) {
16978            queue.backgroundServicesFinishedLocked(userId);
16979        }
16980    }
16981
16982    public void finishReceiver(IBinder who, int resultCode, String resultData,
16983            Bundle resultExtras, boolean resultAbort, int flags) {
16984        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
16985
16986        // Refuse possible leaked file descriptors
16987        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16988            throw new IllegalArgumentException("File descriptors passed in Bundle");
16989        }
16990
16991        final long origId = Binder.clearCallingIdentity();
16992        try {
16993            boolean doNext = false;
16994            BroadcastRecord r;
16995
16996            synchronized(this) {
16997                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
16998                        ? mFgBroadcastQueue : mBgBroadcastQueue;
16999                r = queue.getMatchingOrderedReceiver(who);
17000                if (r != null) {
17001                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17002                        resultData, resultExtras, resultAbort, true);
17003                }
17004            }
17005
17006            if (doNext) {
17007                r.queue.processNextBroadcast(false);
17008            }
17009            trimApplications();
17010        } finally {
17011            Binder.restoreCallingIdentity(origId);
17012        }
17013    }
17014
17015    // =========================================================
17016    // INSTRUMENTATION
17017    // =========================================================
17018
17019    public boolean startInstrumentation(ComponentName className,
17020            String profileFile, int flags, Bundle arguments,
17021            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17022            int userId, String abiOverride) {
17023        enforceNotIsolatedCaller("startInstrumentation");
17024        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17025                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17026        // Refuse possible leaked file descriptors
17027        if (arguments != null && arguments.hasFileDescriptors()) {
17028            throw new IllegalArgumentException("File descriptors passed in Bundle");
17029        }
17030
17031        synchronized(this) {
17032            InstrumentationInfo ii = null;
17033            ApplicationInfo ai = null;
17034            try {
17035                ii = mContext.getPackageManager().getInstrumentationInfo(
17036                    className, STOCK_PM_FLAGS);
17037                ai = AppGlobals.getPackageManager().getApplicationInfo(
17038                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17039            } catch (PackageManager.NameNotFoundException e) {
17040            } catch (RemoteException e) {
17041            }
17042            if (ii == null) {
17043                reportStartInstrumentationFailure(watcher, className,
17044                        "Unable to find instrumentation info for: " + className);
17045                return false;
17046            }
17047            if (ai == null) {
17048                reportStartInstrumentationFailure(watcher, className,
17049                        "Unable to find instrumentation target package: " + ii.targetPackage);
17050                return false;
17051            }
17052
17053            int match = mContext.getPackageManager().checkSignatures(
17054                    ii.targetPackage, ii.packageName);
17055            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17056                String msg = "Permission Denial: starting instrumentation "
17057                        + className + " from pid="
17058                        + Binder.getCallingPid()
17059                        + ", uid=" + Binder.getCallingPid()
17060                        + " not allowed because package " + ii.packageName
17061                        + " does not have a signature matching the target "
17062                        + ii.targetPackage;
17063                reportStartInstrumentationFailure(watcher, className, msg);
17064                throw new SecurityException(msg);
17065            }
17066
17067            final long origId = Binder.clearCallingIdentity();
17068            // Instrumentation can kill and relaunch even persistent processes
17069            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17070                    "start instr");
17071            ProcessRecord app = addAppLocked(ai, false, abiOverride);
17072            app.instrumentationClass = className;
17073            app.instrumentationInfo = ai;
17074            app.instrumentationProfileFile = profileFile;
17075            app.instrumentationArguments = arguments;
17076            app.instrumentationWatcher = watcher;
17077            app.instrumentationUiAutomationConnection = uiAutomationConnection;
17078            app.instrumentationResultClass = className;
17079            Binder.restoreCallingIdentity(origId);
17080        }
17081
17082        return true;
17083    }
17084
17085    /**
17086     * Report errors that occur while attempting to start Instrumentation.  Always writes the
17087     * error to the logs, but if somebody is watching, send the report there too.  This enables
17088     * the "am" command to report errors with more information.
17089     *
17090     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17091     * @param cn The component name of the instrumentation.
17092     * @param report The error report.
17093     */
17094    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
17095            ComponentName cn, String report) {
17096        Slog.w(TAG, report);
17097        try {
17098            if (watcher != null) {
17099                Bundle results = new Bundle();
17100                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17101                results.putString("Error", report);
17102                watcher.instrumentationStatus(cn, -1, results);
17103            }
17104        } catch (RemoteException e) {
17105            Slog.w(TAG, e);
17106        }
17107    }
17108
17109    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17110        if (app.instrumentationWatcher != null) {
17111            try {
17112                // NOTE:  IInstrumentationWatcher *must* be oneway here
17113                app.instrumentationWatcher.instrumentationFinished(
17114                    app.instrumentationClass,
17115                    resultCode,
17116                    results);
17117            } catch (RemoteException e) {
17118            }
17119        }
17120
17121        // Can't call out of the system process with a lock held, so post a message.
17122        mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17123                app.instrumentationUiAutomationConnection).sendToTarget();
17124
17125        app.instrumentationWatcher = null;
17126        app.instrumentationUiAutomationConnection = null;
17127        app.instrumentationClass = null;
17128        app.instrumentationInfo = null;
17129        app.instrumentationProfileFile = null;
17130        app.instrumentationArguments = null;
17131
17132        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17133                "finished inst");
17134    }
17135
17136    public void finishInstrumentation(IApplicationThread target,
17137            int resultCode, Bundle results) {
17138        int userId = UserHandle.getCallingUserId();
17139        // Refuse possible leaked file descriptors
17140        if (results != null && results.hasFileDescriptors()) {
17141            throw new IllegalArgumentException("File descriptors passed in Intent");
17142        }
17143
17144        synchronized(this) {
17145            ProcessRecord app = getRecordForAppLocked(target);
17146            if (app == null) {
17147                Slog.w(TAG, "finishInstrumentation: no app for " + target);
17148                return;
17149            }
17150            final long origId = Binder.clearCallingIdentity();
17151            finishInstrumentationLocked(app, resultCode, results);
17152            Binder.restoreCallingIdentity(origId);
17153        }
17154    }
17155
17156    // =========================================================
17157    // CONFIGURATION
17158    // =========================================================
17159
17160    public ConfigurationInfo getDeviceConfigurationInfo() {
17161        ConfigurationInfo config = new ConfigurationInfo();
17162        synchronized (this) {
17163            config.reqTouchScreen = mConfiguration.touchscreen;
17164            config.reqKeyboardType = mConfiguration.keyboard;
17165            config.reqNavigation = mConfiguration.navigation;
17166            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17167                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17168                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17169            }
17170            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17171                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17172                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17173            }
17174            config.reqGlEsVersion = GL_ES_VERSION;
17175        }
17176        return config;
17177    }
17178
17179    ActivityStack getFocusedStack() {
17180        return mStackSupervisor.getFocusedStack();
17181    }
17182
17183    @Override
17184    public int getFocusedStackId() throws RemoteException {
17185        ActivityStack focusedStack = getFocusedStack();
17186        if (focusedStack != null) {
17187            return focusedStack.getStackId();
17188        }
17189        return -1;
17190    }
17191
17192    public Configuration getConfiguration() {
17193        Configuration ci;
17194        synchronized(this) {
17195            ci = new Configuration(mConfiguration);
17196            ci.userSetLocale = false;
17197        }
17198        return ci;
17199    }
17200
17201    public void updatePersistentConfiguration(Configuration values) {
17202        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17203                "updateConfiguration()");
17204        enforceWriteSettingsPermission("updateConfiguration()");
17205        if (values == null) {
17206            throw new NullPointerException("Configuration must not be null");
17207        }
17208
17209        synchronized(this) {
17210            final long origId = Binder.clearCallingIdentity();
17211            updateConfigurationLocked(values, null, true, false);
17212            Binder.restoreCallingIdentity(origId);
17213        }
17214    }
17215
17216    private void enforceWriteSettingsPermission(String func) {
17217        int uid = Binder.getCallingUid();
17218        if (uid == Process.ROOT_UID) {
17219            return;
17220        }
17221
17222        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
17223                Settings.getPackageNameForUid(mContext, uid), false)) {
17224            return;
17225        }
17226
17227        String msg = "Permission Denial: " + func + " from pid="
17228                + Binder.getCallingPid()
17229                + ", uid=" + uid
17230                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
17231        Slog.w(TAG, msg);
17232        throw new SecurityException(msg);
17233    }
17234
17235    public void updateConfiguration(Configuration values) {
17236        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17237                "updateConfiguration()");
17238
17239        synchronized(this) {
17240            if (values == null && mWindowManager != null) {
17241                // sentinel: fetch the current configuration from the window manager
17242                values = mWindowManager.computeNewConfiguration();
17243            }
17244
17245            if (mWindowManager != null) {
17246                mProcessList.applyDisplaySize(mWindowManager);
17247            }
17248
17249            final long origId = Binder.clearCallingIdentity();
17250            if (values != null) {
17251                Settings.System.clearConfiguration(values);
17252            }
17253            updateConfigurationLocked(values, null, false, false);
17254            Binder.restoreCallingIdentity(origId);
17255        }
17256    }
17257
17258    /**
17259     * Do either or both things: (1) change the current configuration, and (2)
17260     * make sure the given activity is running with the (now) current
17261     * configuration.  Returns true if the activity has been left running, or
17262     * false if <var>starting</var> is being destroyed to match the new
17263     * configuration.
17264     * @param persistent TODO
17265     */
17266    boolean updateConfigurationLocked(Configuration values,
17267            ActivityRecord starting, boolean persistent, boolean initLocale) {
17268        int changes = 0;
17269
17270        if (values != null) {
17271            Configuration newConfig = new Configuration(mConfiguration);
17272            changes = newConfig.updateFrom(values);
17273            if (changes != 0) {
17274                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
17275                        "Updating configuration to: " + values);
17276
17277                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
17278
17279                if (!initLocale && values.locale != null && values.userSetLocale) {
17280                    final String languageTag = values.locale.toLanguageTag();
17281                    SystemProperties.set("persist.sys.locale", languageTag);
17282                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
17283                            values.locale));
17284                }
17285
17286                mConfigurationSeq++;
17287                if (mConfigurationSeq <= 0) {
17288                    mConfigurationSeq = 1;
17289                }
17290                newConfig.seq = mConfigurationSeq;
17291                mConfiguration = newConfig;
17292                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
17293                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
17294                //mUsageStatsService.noteStartConfig(newConfig);
17295
17296                final Configuration configCopy = new Configuration(mConfiguration);
17297
17298                // TODO: If our config changes, should we auto dismiss any currently
17299                // showing dialogs?
17300                mShowDialogs = shouldShowDialogs(newConfig);
17301
17302                AttributeCache ac = AttributeCache.instance();
17303                if (ac != null) {
17304                    ac.updateConfiguration(configCopy);
17305                }
17306
17307                // Make sure all resources in our process are updated
17308                // right now, so that anyone who is going to retrieve
17309                // resource values after we return will be sure to get
17310                // the new ones.  This is especially important during
17311                // boot, where the first config change needs to guarantee
17312                // all resources have that config before following boot
17313                // code is executed.
17314                mSystemThread.applyConfigurationToResources(configCopy);
17315
17316                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
17317                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
17318                    msg.obj = new Configuration(configCopy);
17319                    mHandler.sendMessage(msg);
17320                }
17321
17322                for (int i=mLruProcesses.size()-1; i>=0; i--) {
17323                    ProcessRecord app = mLruProcesses.get(i);
17324                    try {
17325                        if (app.thread != null) {
17326                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
17327                                    + app.processName + " new config " + mConfiguration);
17328                            app.thread.scheduleConfigurationChanged(configCopy);
17329                        }
17330                    } catch (Exception e) {
17331                    }
17332                }
17333                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
17334                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17335                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
17336                        | Intent.FLAG_RECEIVER_FOREGROUND);
17337                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
17338                        null, AppOpsManager.OP_NONE, null, false, false,
17339                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17340                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
17341                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
17342                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17343                    if (!mProcessesReady) {
17344                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17345                    }
17346                    broadcastIntentLocked(null, null, intent,
17347                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17348                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17349                }
17350            }
17351        }
17352
17353        boolean kept = true;
17354        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
17355        // mainStack is null during startup.
17356        if (mainStack != null) {
17357            if (changes != 0 && starting == null) {
17358                // If the configuration changed, and the caller is not already
17359                // in the process of starting an activity, then find the top
17360                // activity to check if its configuration needs to change.
17361                starting = mainStack.topRunningActivityLocked(null);
17362            }
17363
17364            if (starting != null) {
17365                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
17366                // And we need to make sure at this point that all other activities
17367                // are made visible with the correct configuration.
17368                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
17369            }
17370        }
17371
17372        if (values != null && mWindowManager != null) {
17373            mWindowManager.setNewConfiguration(mConfiguration);
17374        }
17375
17376        return kept;
17377    }
17378
17379    /**
17380     * Decide based on the configuration whether we should shouw the ANR,
17381     * crash, etc dialogs.  The idea is that if there is no affordnace to
17382     * press the on-screen buttons, we shouldn't show the dialog.
17383     *
17384     * A thought: SystemUI might also want to get told about this, the Power
17385     * dialog / global actions also might want different behaviors.
17386     */
17387    private static final boolean shouldShowDialogs(Configuration config) {
17388        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
17389                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
17390                && config.navigation == Configuration.NAVIGATION_NONAV);
17391    }
17392
17393    @Override
17394    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
17395        synchronized (this) {
17396            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
17397            if (srec != null) {
17398                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
17399            }
17400        }
17401        return false;
17402    }
17403
17404    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
17405            Intent resultData) {
17406
17407        synchronized (this) {
17408            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
17409            if (r != null) {
17410                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
17411            }
17412            return false;
17413        }
17414    }
17415
17416    public int getLaunchedFromUid(IBinder activityToken) {
17417        ActivityRecord srec;
17418        synchronized (this) {
17419            srec = ActivityRecord.forTokenLocked(activityToken);
17420        }
17421        if (srec == null) {
17422            return -1;
17423        }
17424        return srec.launchedFromUid;
17425    }
17426
17427    public String getLaunchedFromPackage(IBinder activityToken) {
17428        ActivityRecord srec;
17429        synchronized (this) {
17430            srec = ActivityRecord.forTokenLocked(activityToken);
17431        }
17432        if (srec == null) {
17433            return null;
17434        }
17435        return srec.launchedFromPackage;
17436    }
17437
17438    // =========================================================
17439    // LIFETIME MANAGEMENT
17440    // =========================================================
17441
17442    // Returns which broadcast queue the app is the current [or imminent] receiver
17443    // on, or 'null' if the app is not an active broadcast recipient.
17444    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
17445        BroadcastRecord r = app.curReceiver;
17446        if (r != null) {
17447            return r.queue;
17448        }
17449
17450        // It's not the current receiver, but it might be starting up to become one
17451        synchronized (this) {
17452            for (BroadcastQueue queue : mBroadcastQueues) {
17453                r = queue.mPendingBroadcast;
17454                if (r != null && r.curApp == app) {
17455                    // found it; report which queue it's in
17456                    return queue;
17457                }
17458            }
17459        }
17460
17461        return null;
17462    }
17463
17464    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17465            ComponentName targetComponent, String targetProcess) {
17466        if (!mTrackingAssociations) {
17467            return null;
17468        }
17469        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17470                = mAssociations.get(targetUid);
17471        if (components == null) {
17472            components = new ArrayMap<>();
17473            mAssociations.put(targetUid, components);
17474        }
17475        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17476        if (sourceUids == null) {
17477            sourceUids = new SparseArray<>();
17478            components.put(targetComponent, sourceUids);
17479        }
17480        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17481        if (sourceProcesses == null) {
17482            sourceProcesses = new ArrayMap<>();
17483            sourceUids.put(sourceUid, sourceProcesses);
17484        }
17485        Association ass = sourceProcesses.get(sourceProcess);
17486        if (ass == null) {
17487            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
17488                    targetProcess);
17489            sourceProcesses.put(sourceProcess, ass);
17490        }
17491        ass.mCount++;
17492        ass.mNesting++;
17493        if (ass.mNesting == 1) {
17494            ass.mStartTime = SystemClock.uptimeMillis();
17495        }
17496        return ass;
17497    }
17498
17499    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17500            ComponentName targetComponent) {
17501        if (!mTrackingAssociations) {
17502            return;
17503        }
17504        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17505                = mAssociations.get(targetUid);
17506        if (components == null) {
17507            return;
17508        }
17509        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17510        if (sourceUids == null) {
17511            return;
17512        }
17513        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17514        if (sourceProcesses == null) {
17515            return;
17516        }
17517        Association ass = sourceProcesses.get(sourceProcess);
17518        if (ass == null || ass.mNesting <= 0) {
17519            return;
17520        }
17521        ass.mNesting--;
17522        if (ass.mNesting == 0) {
17523            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
17524        }
17525    }
17526
17527    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
17528            boolean doingAll, long now) {
17529        if (mAdjSeq == app.adjSeq) {
17530            // This adjustment has already been computed.
17531            return app.curRawAdj;
17532        }
17533
17534        if (app.thread == null) {
17535            app.adjSeq = mAdjSeq;
17536            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17537            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17538            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
17539        }
17540
17541        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
17542        app.adjSource = null;
17543        app.adjTarget = null;
17544        app.empty = false;
17545        app.cached = false;
17546
17547        final int activitiesSize = app.activities.size();
17548
17549        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17550            // The max adjustment doesn't allow this app to be anything
17551            // below foreground, so it is not worth doing work for it.
17552            app.adjType = "fixed";
17553            app.adjSeq = mAdjSeq;
17554            app.curRawAdj = app.maxAdj;
17555            app.foregroundActivities = false;
17556            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
17557            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
17558            // System processes can do UI, and when they do we want to have
17559            // them trim their memory after the user leaves the UI.  To
17560            // facilitate this, here we need to determine whether or not it
17561            // is currently showing UI.
17562            app.systemNoUi = true;
17563            if (app == TOP_APP) {
17564                app.systemNoUi = false;
17565            } else if (activitiesSize > 0) {
17566                for (int j = 0; j < activitiesSize; j++) {
17567                    final ActivityRecord r = app.activities.get(j);
17568                    if (r.visible) {
17569                        app.systemNoUi = false;
17570                    }
17571                }
17572            }
17573            if (!app.systemNoUi) {
17574                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
17575            }
17576            return (app.curAdj=app.maxAdj);
17577        }
17578
17579        app.systemNoUi = false;
17580
17581        final int PROCESS_STATE_TOP = mTopProcessState;
17582
17583        // Determine the importance of the process, starting with most
17584        // important to least, and assign an appropriate OOM adjustment.
17585        int adj;
17586        int schedGroup;
17587        int procState;
17588        boolean foregroundActivities = false;
17589        BroadcastQueue queue;
17590        if (app == TOP_APP) {
17591            // The last app on the list is the foreground app.
17592            adj = ProcessList.FOREGROUND_APP_ADJ;
17593            schedGroup = Process.THREAD_GROUP_DEFAULT;
17594            app.adjType = "top-activity";
17595            foregroundActivities = true;
17596            procState = PROCESS_STATE_TOP;
17597        } else if (app.instrumentationClass != null) {
17598            // Don't want to kill running instrumentation.
17599            adj = ProcessList.FOREGROUND_APP_ADJ;
17600            schedGroup = Process.THREAD_GROUP_DEFAULT;
17601            app.adjType = "instrumentation";
17602            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17603        } else if ((queue = isReceivingBroadcast(app)) != null) {
17604            // An app that is currently receiving a broadcast also
17605            // counts as being in the foreground for OOM killer purposes.
17606            // It's placed in a sched group based on the nature of the
17607            // broadcast as reflected by which queue it's active in.
17608            adj = ProcessList.FOREGROUND_APP_ADJ;
17609            schedGroup = (queue == mFgBroadcastQueue)
17610                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17611            app.adjType = "broadcast";
17612            procState = ActivityManager.PROCESS_STATE_RECEIVER;
17613        } else if (app.executingServices.size() > 0) {
17614            // An app that is currently executing a service callback also
17615            // counts as being in the foreground.
17616            adj = ProcessList.FOREGROUND_APP_ADJ;
17617            schedGroup = app.execServicesFg ?
17618                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17619            app.adjType = "exec-service";
17620            procState = ActivityManager.PROCESS_STATE_SERVICE;
17621            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
17622        } else {
17623            // As far as we know the process is empty.  We may change our mind later.
17624            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17625            // At this point we don't actually know the adjustment.  Use the cached adj
17626            // value that the caller wants us to.
17627            adj = cachedAdj;
17628            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17629            app.cached = true;
17630            app.empty = true;
17631            app.adjType = "cch-empty";
17632        }
17633
17634        // Examine all activities if not already foreground.
17635        if (!foregroundActivities && activitiesSize > 0) {
17636            for (int j = 0; j < activitiesSize; j++) {
17637                final ActivityRecord r = app.activities.get(j);
17638                if (r.app != app) {
17639                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
17640                            + app + "?!? Using " + r.app + " instead.");
17641                    continue;
17642                }
17643                if (r.visible) {
17644                    // App has a visible activity; only upgrade adjustment.
17645                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17646                        adj = ProcessList.VISIBLE_APP_ADJ;
17647                        app.adjType = "visible";
17648                    }
17649                    if (procState > PROCESS_STATE_TOP) {
17650                        procState = PROCESS_STATE_TOP;
17651                    }
17652                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17653                    app.cached = false;
17654                    app.empty = false;
17655                    foregroundActivities = true;
17656                    break;
17657                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
17658                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17659                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17660                        app.adjType = "pausing";
17661                    }
17662                    if (procState > PROCESS_STATE_TOP) {
17663                        procState = PROCESS_STATE_TOP;
17664                    }
17665                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17666                    app.cached = false;
17667                    app.empty = false;
17668                    foregroundActivities = true;
17669                } else if (r.state == ActivityState.STOPPING) {
17670                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17671                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17672                        app.adjType = "stopping";
17673                    }
17674                    // For the process state, we will at this point consider the
17675                    // process to be cached.  It will be cached either as an activity
17676                    // or empty depending on whether the activity is finishing.  We do
17677                    // this so that we can treat the process as cached for purposes of
17678                    // memory trimming (determing current memory level, trim command to
17679                    // send to process) since there can be an arbitrary number of stopping
17680                    // processes and they should soon all go into the cached state.
17681                    if (!r.finishing) {
17682                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17683                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17684                        }
17685                    }
17686                    app.cached = false;
17687                    app.empty = false;
17688                    foregroundActivities = true;
17689                } else {
17690                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17691                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17692                        app.adjType = "cch-act";
17693                    }
17694                }
17695            }
17696        }
17697
17698        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17699            if (app.foregroundServices) {
17700                // The user is aware of this app, so make it visible.
17701                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17702                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17703                app.cached = false;
17704                app.adjType = "fg-service";
17705                schedGroup = Process.THREAD_GROUP_DEFAULT;
17706            } else if (app.forcingToForeground != null) {
17707                // The user is aware of this app, so make it visible.
17708                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17709                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17710                app.cached = false;
17711                app.adjType = "force-fg";
17712                app.adjSource = app.forcingToForeground;
17713                schedGroup = Process.THREAD_GROUP_DEFAULT;
17714            }
17715        }
17716
17717        if (app == mHeavyWeightProcess) {
17718            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
17719                // We don't want to kill the current heavy-weight process.
17720                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
17721                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17722                app.cached = false;
17723                app.adjType = "heavy";
17724            }
17725            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17726                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
17727            }
17728        }
17729
17730        if (app == mHomeProcess) {
17731            if (adj > ProcessList.HOME_APP_ADJ) {
17732                // This process is hosting what we currently consider to be the
17733                // home app, so we don't want to let it go into the background.
17734                adj = ProcessList.HOME_APP_ADJ;
17735                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17736                app.cached = false;
17737                app.adjType = "home";
17738            }
17739            if (procState > ActivityManager.PROCESS_STATE_HOME) {
17740                procState = ActivityManager.PROCESS_STATE_HOME;
17741            }
17742        }
17743
17744        if (app == mPreviousProcess && app.activities.size() > 0) {
17745            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
17746                // This was the previous process that showed UI to the user.
17747                // We want to try to keep it around more aggressively, to give
17748                // a good experience around switching between two apps.
17749                adj = ProcessList.PREVIOUS_APP_ADJ;
17750                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17751                app.cached = false;
17752                app.adjType = "previous";
17753            }
17754            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17755                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17756            }
17757        }
17758
17759        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
17760                + " reason=" + app.adjType);
17761
17762        // By default, we use the computed adjustment.  It may be changed if
17763        // there are applications dependent on our services or providers, but
17764        // this gives us a baseline and makes sure we don't get into an
17765        // infinite recursion.
17766        app.adjSeq = mAdjSeq;
17767        app.curRawAdj = adj;
17768        app.hasStartedServices = false;
17769
17770        if (mBackupTarget != null && app == mBackupTarget.app) {
17771            // If possible we want to avoid killing apps while they're being backed up
17772            if (adj > ProcessList.BACKUP_APP_ADJ) {
17773                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
17774                adj = ProcessList.BACKUP_APP_ADJ;
17775                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17776                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17777                }
17778                app.adjType = "backup";
17779                app.cached = false;
17780            }
17781            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
17782                procState = ActivityManager.PROCESS_STATE_BACKUP;
17783            }
17784        }
17785
17786        boolean mayBeTop = false;
17787
17788        for (int is = app.services.size()-1;
17789                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17790                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17791                        || procState > ActivityManager.PROCESS_STATE_TOP);
17792                is--) {
17793            ServiceRecord s = app.services.valueAt(is);
17794            if (s.startRequested) {
17795                app.hasStartedServices = true;
17796                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
17797                    procState = ActivityManager.PROCESS_STATE_SERVICE;
17798                }
17799                if (app.hasShownUi && app != mHomeProcess) {
17800                    // If this process has shown some UI, let it immediately
17801                    // go to the LRU list because it may be pretty heavy with
17802                    // UI stuff.  We'll tag it with a label just to help
17803                    // debug and understand what is going on.
17804                    if (adj > ProcessList.SERVICE_ADJ) {
17805                        app.adjType = "cch-started-ui-services";
17806                    }
17807                } else {
17808                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17809                        // This service has seen some activity within
17810                        // recent memory, so we will keep its process ahead
17811                        // of the background processes.
17812                        if (adj > ProcessList.SERVICE_ADJ) {
17813                            adj = ProcessList.SERVICE_ADJ;
17814                            app.adjType = "started-services";
17815                            app.cached = false;
17816                        }
17817                    }
17818                    // If we have let the service slide into the background
17819                    // state, still have some text describing what it is doing
17820                    // even though the service no longer has an impact.
17821                    if (adj > ProcessList.SERVICE_ADJ) {
17822                        app.adjType = "cch-started-services";
17823                    }
17824                }
17825            }
17826            for (int conni = s.connections.size()-1;
17827                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17828                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17829                            || procState > ActivityManager.PROCESS_STATE_TOP);
17830                    conni--) {
17831                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17832                for (int i = 0;
17833                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17834                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17835                                || procState > ActivityManager.PROCESS_STATE_TOP);
17836                        i++) {
17837                    // XXX should compute this based on the max of
17838                    // all connected clients.
17839                    ConnectionRecord cr = clist.get(i);
17840                    if (cr.binding.client == app) {
17841                        // Binding to ourself is not interesting.
17842                        continue;
17843                    }
17844                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17845                        ProcessRecord client = cr.binding.client;
17846                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
17847                                TOP_APP, doingAll, now);
17848                        int clientProcState = client.curProcState;
17849                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17850                            // If the other app is cached for any reason, for purposes here
17851                            // we are going to consider it empty.  The specific cached state
17852                            // doesn't propagate except under certain conditions.
17853                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17854                        }
17855                        String adjType = null;
17856                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17857                            // Not doing bind OOM management, so treat
17858                            // this guy more like a started service.
17859                            if (app.hasShownUi && app != mHomeProcess) {
17860                                // If this process has shown some UI, let it immediately
17861                                // go to the LRU list because it may be pretty heavy with
17862                                // UI stuff.  We'll tag it with a label just to help
17863                                // debug and understand what is going on.
17864                                if (adj > clientAdj) {
17865                                    adjType = "cch-bound-ui-services";
17866                                }
17867                                app.cached = false;
17868                                clientAdj = adj;
17869                                clientProcState = procState;
17870                            } else {
17871                                if (now >= (s.lastActivity
17872                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17873                                    // This service has not seen activity within
17874                                    // recent memory, so allow it to drop to the
17875                                    // LRU list if there is no other reason to keep
17876                                    // it around.  We'll also tag it with a label just
17877                                    // to help debug and undertand what is going on.
17878                                    if (adj > clientAdj) {
17879                                        adjType = "cch-bound-services";
17880                                    }
17881                                    clientAdj = adj;
17882                                }
17883                            }
17884                        }
17885                        if (adj > clientAdj) {
17886                            // If this process has recently shown UI, and
17887                            // the process that is binding to it is less
17888                            // important than being visible, then we don't
17889                            // care about the binding as much as we care
17890                            // about letting this process get into the LRU
17891                            // list to be killed and restarted if needed for
17892                            // memory.
17893                            if (app.hasShownUi && app != mHomeProcess
17894                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17895                                adjType = "cch-bound-ui-services";
17896                            } else {
17897                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17898                                        |Context.BIND_IMPORTANT)) != 0) {
17899                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17900                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17901                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17902                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17903                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17904                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17905                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17906                                    adj = clientAdj;
17907                                } else {
17908                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17909                                        adj = ProcessList.VISIBLE_APP_ADJ;
17910                                    }
17911                                }
17912                                if (!client.cached) {
17913                                    app.cached = false;
17914                                }
17915                                adjType = "service";
17916                            }
17917                        }
17918                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17919                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17920                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17921                            }
17922                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17923                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17924                                    // Special handling of clients who are in the top state.
17925                                    // We *may* want to consider this process to be in the
17926                                    // top state as well, but only if there is not another
17927                                    // reason for it to be running.  Being on the top is a
17928                                    // special state, meaning you are specifically running
17929                                    // for the current top app.  If the process is already
17930                                    // running in the background for some other reason, it
17931                                    // is more important to continue considering it to be
17932                                    // in the background state.
17933                                    mayBeTop = true;
17934                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17935                                } else {
17936                                    // Special handling for above-top states (persistent
17937                                    // processes).  These should not bring the current process
17938                                    // into the top state, since they are not on top.  Instead
17939                                    // give them the best state after that.
17940                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
17941                                        clientProcState =
17942                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
17943                                    } else if (mWakefulness
17944                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
17945                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
17946                                                    != 0) {
17947                                        clientProcState =
17948                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
17949                                    } else {
17950                                        clientProcState =
17951                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17952                                    }
17953                                }
17954                            }
17955                        } else {
17956                            if (clientProcState <
17957                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17958                                clientProcState =
17959                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17960                            }
17961                        }
17962                        if (procState > clientProcState) {
17963                            procState = clientProcState;
17964                        }
17965                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17966                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17967                            app.pendingUiClean = true;
17968                        }
17969                        if (adjType != null) {
17970                            app.adjType = adjType;
17971                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17972                                    .REASON_SERVICE_IN_USE;
17973                            app.adjSource = cr.binding.client;
17974                            app.adjSourceProcState = clientProcState;
17975                            app.adjTarget = s.name;
17976                        }
17977                    }
17978                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17979                        app.treatLikeActivity = true;
17980                    }
17981                    final ActivityRecord a = cr.activity;
17982                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17983                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17984                                (a.visible || a.state == ActivityState.RESUMED
17985                                 || a.state == ActivityState.PAUSING)) {
17986                            adj = ProcessList.FOREGROUND_APP_ADJ;
17987                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17988                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17989                            }
17990                            app.cached = false;
17991                            app.adjType = "service";
17992                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17993                                    .REASON_SERVICE_IN_USE;
17994                            app.adjSource = a;
17995                            app.adjSourceProcState = procState;
17996                            app.adjTarget = s.name;
17997                        }
17998                    }
17999                }
18000            }
18001        }
18002
18003        for (int provi = app.pubProviders.size()-1;
18004                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18005                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18006                        || procState > ActivityManager.PROCESS_STATE_TOP);
18007                provi--) {
18008            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18009            for (int i = cpr.connections.size()-1;
18010                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18011                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18012                            || procState > ActivityManager.PROCESS_STATE_TOP);
18013                    i--) {
18014                ContentProviderConnection conn = cpr.connections.get(i);
18015                ProcessRecord client = conn.client;
18016                if (client == app) {
18017                    // Being our own client is not interesting.
18018                    continue;
18019                }
18020                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18021                int clientProcState = client.curProcState;
18022                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18023                    // If the other app is cached for any reason, for purposes here
18024                    // we are going to consider it empty.
18025                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18026                }
18027                if (adj > clientAdj) {
18028                    if (app.hasShownUi && app != mHomeProcess
18029                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18030                        app.adjType = "cch-ui-provider";
18031                    } else {
18032                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18033                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18034                        app.adjType = "provider";
18035                    }
18036                    app.cached &= client.cached;
18037                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18038                            .REASON_PROVIDER_IN_USE;
18039                    app.adjSource = client;
18040                    app.adjSourceProcState = clientProcState;
18041                    app.adjTarget = cpr.name;
18042                }
18043                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18044                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18045                        // Special handling of clients who are in the top state.
18046                        // We *may* want to consider this process to be in the
18047                        // top state as well, but only if there is not another
18048                        // reason for it to be running.  Being on the top is a
18049                        // special state, meaning you are specifically running
18050                        // for the current top app.  If the process is already
18051                        // running in the background for some other reason, it
18052                        // is more important to continue considering it to be
18053                        // in the background state.
18054                        mayBeTop = true;
18055                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18056                    } else {
18057                        // Special handling for above-top states (persistent
18058                        // processes).  These should not bring the current process
18059                        // into the top state, since they are not on top.  Instead
18060                        // give them the best state after that.
18061                        clientProcState =
18062                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18063                    }
18064                }
18065                if (procState > clientProcState) {
18066                    procState = clientProcState;
18067                }
18068                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18069                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18070                }
18071            }
18072            // If the provider has external (non-framework) process
18073            // dependencies, ensure that its adjustment is at least
18074            // FOREGROUND_APP_ADJ.
18075            if (cpr.hasExternalProcessHandles()) {
18076                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
18077                    adj = ProcessList.FOREGROUND_APP_ADJ;
18078                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18079                    app.cached = false;
18080                    app.adjType = "provider";
18081                    app.adjTarget = cpr.name;
18082                }
18083                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18084                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18085                }
18086            }
18087        }
18088
18089        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
18090            // A client of one of our services or providers is in the top state.  We
18091            // *may* want to be in the top state, but not if we are already running in
18092            // the background for some other reason.  For the decision here, we are going
18093            // to pick out a few specific states that we want to remain in when a client
18094            // is top (states that tend to be longer-term) and otherwise allow it to go
18095            // to the top state.
18096            switch (procState) {
18097                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
18098                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
18099                case ActivityManager.PROCESS_STATE_SERVICE:
18100                    // These all are longer-term states, so pull them up to the top
18101                    // of the background states, but not all the way to the top state.
18102                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18103                    break;
18104                default:
18105                    // Otherwise, top is a better choice, so take it.
18106                    procState = ActivityManager.PROCESS_STATE_TOP;
18107                    break;
18108            }
18109        }
18110
18111        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
18112            if (app.hasClientActivities) {
18113                // This is a cached process, but with client activities.  Mark it so.
18114                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
18115                app.adjType = "cch-client-act";
18116            } else if (app.treatLikeActivity) {
18117                // This is a cached process, but somebody wants us to treat it like it has
18118                // an activity, okay!
18119                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18120                app.adjType = "cch-as-act";
18121            }
18122        }
18123
18124        if (adj == ProcessList.SERVICE_ADJ) {
18125            if (doingAll) {
18126                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
18127                mNewNumServiceProcs++;
18128                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
18129                if (!app.serviceb) {
18130                    // This service isn't far enough down on the LRU list to
18131                    // normally be a B service, but if we are low on RAM and it
18132                    // is large we want to force it down since we would prefer to
18133                    // keep launcher over it.
18134                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
18135                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
18136                        app.serviceHighRam = true;
18137                        app.serviceb = true;
18138                        //Slog.i(TAG, "ADJ " + app + " high ram!");
18139                    } else {
18140                        mNewNumAServiceProcs++;
18141                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
18142                    }
18143                } else {
18144                    app.serviceHighRam = false;
18145                }
18146            }
18147            if (app.serviceb) {
18148                adj = ProcessList.SERVICE_B_ADJ;
18149            }
18150        }
18151
18152        app.curRawAdj = adj;
18153
18154        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
18155        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
18156        if (adj > app.maxAdj) {
18157            adj = app.maxAdj;
18158            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
18159                schedGroup = Process.THREAD_GROUP_DEFAULT;
18160            }
18161        }
18162
18163        // Do final modification to adj.  Everything we do between here and applying
18164        // the final setAdj must be done in this function, because we will also use
18165        // it when computing the final cached adj later.  Note that we don't need to
18166        // worry about this for max adj above, since max adj will always be used to
18167        // keep it out of the cached vaues.
18168        app.curAdj = app.modifyRawOomAdj(adj);
18169        app.curSchedGroup = schedGroup;
18170        app.curProcState = procState;
18171        app.foregroundActivities = foregroundActivities;
18172
18173        return app.curRawAdj;
18174    }
18175
18176    /**
18177     * Record new PSS sample for a process.
18178     */
18179    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long now) {
18180        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024);
18181        proc.lastPssTime = now;
18182        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
18183        if (DEBUG_PSS) Slog.d(TAG_PSS,
18184                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
18185                + " state=" + ProcessList.makeProcStateString(procState));
18186        if (proc.initialIdlePss == 0) {
18187            proc.initialIdlePss = pss;
18188        }
18189        proc.lastPss = pss;
18190        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
18191            proc.lastCachedPss = pss;
18192        }
18193
18194        final SparseArray<Pair<Long, String>> watchUids
18195                = mMemWatchProcesses.getMap().get(proc.processName);
18196        Long check = null;
18197        if (watchUids != null) {
18198            Pair<Long, String> val = watchUids.get(proc.uid);
18199            if (val == null) {
18200                val = watchUids.get(0);
18201            }
18202            if (val != null) {
18203                check = val.first;
18204            }
18205        }
18206        if (check != null) {
18207            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
18208                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18209                if (!isDebuggable) {
18210                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
18211                        isDebuggable = true;
18212                    }
18213                }
18214                if (isDebuggable) {
18215                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
18216                    final ProcessRecord myProc = proc;
18217                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
18218                    mMemWatchDumpProcName = proc.processName;
18219                    mMemWatchDumpFile = heapdumpFile.toString();
18220                    mMemWatchDumpPid = proc.pid;
18221                    mMemWatchDumpUid = proc.uid;
18222                    BackgroundThread.getHandler().post(new Runnable() {
18223                        @Override
18224                        public void run() {
18225                            revokeUriPermission(ActivityThread.currentActivityThread()
18226                                            .getApplicationThread(),
18227                                    DumpHeapActivity.JAVA_URI,
18228                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
18229                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
18230                                    UserHandle.myUserId());
18231                            ParcelFileDescriptor fd = null;
18232                            try {
18233                                heapdumpFile.delete();
18234                                fd = ParcelFileDescriptor.open(heapdumpFile,
18235                                        ParcelFileDescriptor.MODE_CREATE |
18236                                                ParcelFileDescriptor.MODE_TRUNCATE |
18237                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
18238                                                ParcelFileDescriptor.MODE_APPEND);
18239                                IApplicationThread thread = myProc.thread;
18240                                if (thread != null) {
18241                                    try {
18242                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
18243                                                "Requesting dump heap from "
18244                                                + myProc + " to " + heapdumpFile);
18245                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
18246                                    } catch (RemoteException e) {
18247                                    }
18248                                }
18249                            } catch (FileNotFoundException e) {
18250                                e.printStackTrace();
18251                            } finally {
18252                                if (fd != null) {
18253                                    try {
18254                                        fd.close();
18255                                    } catch (IOException e) {
18256                                    }
18257                                }
18258                            }
18259                        }
18260                    });
18261                } else {
18262                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
18263                            + ", but debugging not enabled");
18264                }
18265            }
18266        }
18267    }
18268
18269    /**
18270     * Schedule PSS collection of a process.
18271     */
18272    void requestPssLocked(ProcessRecord proc, int procState) {
18273        if (mPendingPssProcesses.contains(proc)) {
18274            return;
18275        }
18276        if (mPendingPssProcesses.size() == 0) {
18277            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18278        }
18279        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
18280        proc.pssProcState = procState;
18281        mPendingPssProcesses.add(proc);
18282    }
18283
18284    /**
18285     * Schedule PSS collection of all processes.
18286     */
18287    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
18288        if (!always) {
18289            if (now < (mLastFullPssTime +
18290                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
18291                return;
18292            }
18293        }
18294        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
18295        mLastFullPssTime = now;
18296        mFullPssPending = true;
18297        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
18298        mPendingPssProcesses.clear();
18299        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18300            ProcessRecord app = mLruProcesses.get(i);
18301            if (app.thread == null
18302                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
18303                continue;
18304            }
18305            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
18306                app.pssProcState = app.setProcState;
18307                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18308                        mTestPssMode, isSleeping(), now);
18309                mPendingPssProcesses.add(app);
18310            }
18311        }
18312        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18313    }
18314
18315    public void setTestPssMode(boolean enabled) {
18316        synchronized (this) {
18317            mTestPssMode = enabled;
18318            if (enabled) {
18319                // Whenever we enable the mode, we want to take a snapshot all of current
18320                // process mem use.
18321                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
18322            }
18323        }
18324    }
18325
18326    /**
18327     * Ask a given process to GC right now.
18328     */
18329    final void performAppGcLocked(ProcessRecord app) {
18330        try {
18331            app.lastRequestedGc = SystemClock.uptimeMillis();
18332            if (app.thread != null) {
18333                if (app.reportLowMemory) {
18334                    app.reportLowMemory = false;
18335                    app.thread.scheduleLowMemory();
18336                } else {
18337                    app.thread.processInBackground();
18338                }
18339            }
18340        } catch (Exception e) {
18341            // whatever.
18342        }
18343    }
18344
18345    /**
18346     * Returns true if things are idle enough to perform GCs.
18347     */
18348    private final boolean canGcNowLocked() {
18349        boolean processingBroadcasts = false;
18350        for (BroadcastQueue q : mBroadcastQueues) {
18351            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
18352                processingBroadcasts = true;
18353            }
18354        }
18355        return !processingBroadcasts
18356                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
18357    }
18358
18359    /**
18360     * Perform GCs on all processes that are waiting for it, but only
18361     * if things are idle.
18362     */
18363    final void performAppGcsLocked() {
18364        final int N = mProcessesToGc.size();
18365        if (N <= 0) {
18366            return;
18367        }
18368        if (canGcNowLocked()) {
18369            while (mProcessesToGc.size() > 0) {
18370                ProcessRecord proc = mProcessesToGc.remove(0);
18371                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
18372                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
18373                            <= SystemClock.uptimeMillis()) {
18374                        // To avoid spamming the system, we will GC processes one
18375                        // at a time, waiting a few seconds between each.
18376                        performAppGcLocked(proc);
18377                        scheduleAppGcsLocked();
18378                        return;
18379                    } else {
18380                        // It hasn't been long enough since we last GCed this
18381                        // process...  put it in the list to wait for its time.
18382                        addProcessToGcListLocked(proc);
18383                        break;
18384                    }
18385                }
18386            }
18387
18388            scheduleAppGcsLocked();
18389        }
18390    }
18391
18392    /**
18393     * If all looks good, perform GCs on all processes waiting for them.
18394     */
18395    final void performAppGcsIfAppropriateLocked() {
18396        if (canGcNowLocked()) {
18397            performAppGcsLocked();
18398            return;
18399        }
18400        // Still not idle, wait some more.
18401        scheduleAppGcsLocked();
18402    }
18403
18404    /**
18405     * Schedule the execution of all pending app GCs.
18406     */
18407    final void scheduleAppGcsLocked() {
18408        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
18409
18410        if (mProcessesToGc.size() > 0) {
18411            // Schedule a GC for the time to the next process.
18412            ProcessRecord proc = mProcessesToGc.get(0);
18413            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
18414
18415            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
18416            long now = SystemClock.uptimeMillis();
18417            if (when < (now+GC_TIMEOUT)) {
18418                when = now + GC_TIMEOUT;
18419            }
18420            mHandler.sendMessageAtTime(msg, when);
18421        }
18422    }
18423
18424    /**
18425     * Add a process to the array of processes waiting to be GCed.  Keeps the
18426     * list in sorted order by the last GC time.  The process can't already be
18427     * on the list.
18428     */
18429    final void addProcessToGcListLocked(ProcessRecord proc) {
18430        boolean added = false;
18431        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
18432            if (mProcessesToGc.get(i).lastRequestedGc <
18433                    proc.lastRequestedGc) {
18434                added = true;
18435                mProcessesToGc.add(i+1, proc);
18436                break;
18437            }
18438        }
18439        if (!added) {
18440            mProcessesToGc.add(0, proc);
18441        }
18442    }
18443
18444    /**
18445     * Set up to ask a process to GC itself.  This will either do it
18446     * immediately, or put it on the list of processes to gc the next
18447     * time things are idle.
18448     */
18449    final void scheduleAppGcLocked(ProcessRecord app) {
18450        long now = SystemClock.uptimeMillis();
18451        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
18452            return;
18453        }
18454        if (!mProcessesToGc.contains(app)) {
18455            addProcessToGcListLocked(app);
18456            scheduleAppGcsLocked();
18457        }
18458    }
18459
18460    final void checkExcessivePowerUsageLocked(boolean doKills) {
18461        updateCpuStatsNow();
18462
18463        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18464        boolean doWakeKills = doKills;
18465        boolean doCpuKills = doKills;
18466        if (mLastPowerCheckRealtime == 0) {
18467            doWakeKills = false;
18468        }
18469        if (mLastPowerCheckUptime == 0) {
18470            doCpuKills = false;
18471        }
18472        if (stats.isScreenOn()) {
18473            doWakeKills = false;
18474        }
18475        final long curRealtime = SystemClock.elapsedRealtime();
18476        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
18477        final long curUptime = SystemClock.uptimeMillis();
18478        final long uptimeSince = curUptime - mLastPowerCheckUptime;
18479        mLastPowerCheckRealtime = curRealtime;
18480        mLastPowerCheckUptime = curUptime;
18481        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
18482            doWakeKills = false;
18483        }
18484        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
18485            doCpuKills = false;
18486        }
18487        int i = mLruProcesses.size();
18488        while (i > 0) {
18489            i--;
18490            ProcessRecord app = mLruProcesses.get(i);
18491            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18492                long wtime;
18493                synchronized (stats) {
18494                    wtime = stats.getProcessWakeTime(app.info.uid,
18495                            app.pid, curRealtime);
18496                }
18497                long wtimeUsed = wtime - app.lastWakeTime;
18498                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
18499                if (DEBUG_POWER) {
18500                    StringBuilder sb = new StringBuilder(128);
18501                    sb.append("Wake for ");
18502                    app.toShortString(sb);
18503                    sb.append(": over ");
18504                    TimeUtils.formatDuration(realtimeSince, sb);
18505                    sb.append(" used ");
18506                    TimeUtils.formatDuration(wtimeUsed, sb);
18507                    sb.append(" (");
18508                    sb.append((wtimeUsed*100)/realtimeSince);
18509                    sb.append("%)");
18510                    Slog.i(TAG_POWER, sb.toString());
18511                    sb.setLength(0);
18512                    sb.append("CPU for ");
18513                    app.toShortString(sb);
18514                    sb.append(": over ");
18515                    TimeUtils.formatDuration(uptimeSince, sb);
18516                    sb.append(" used ");
18517                    TimeUtils.formatDuration(cputimeUsed, sb);
18518                    sb.append(" (");
18519                    sb.append((cputimeUsed*100)/uptimeSince);
18520                    sb.append("%)");
18521                    Slog.i(TAG_POWER, sb.toString());
18522                }
18523                // If a process has held a wake lock for more
18524                // than 50% of the time during this period,
18525                // that sounds bad.  Kill!
18526                if (doWakeKills && realtimeSince > 0
18527                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
18528                    synchronized (stats) {
18529                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
18530                                realtimeSince, wtimeUsed);
18531                    }
18532                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
18533                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
18534                } else if (doCpuKills && uptimeSince > 0
18535                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
18536                    synchronized (stats) {
18537                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
18538                                uptimeSince, cputimeUsed);
18539                    }
18540                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
18541                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
18542                } else {
18543                    app.lastWakeTime = wtime;
18544                    app.lastCpuTime = app.curCpuTime;
18545                }
18546            }
18547        }
18548    }
18549
18550    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now) {
18551        boolean success = true;
18552
18553        if (app.curRawAdj != app.setRawAdj) {
18554            app.setRawAdj = app.curRawAdj;
18555        }
18556
18557        int changes = 0;
18558
18559        if (app.curAdj != app.setAdj) {
18560            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
18561            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18562                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
18563                    + app.adjType);
18564            app.setAdj = app.curAdj;
18565        }
18566
18567        if (app.setSchedGroup != app.curSchedGroup) {
18568            app.setSchedGroup = app.curSchedGroup;
18569            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18570                    "Setting process group of " + app.processName
18571                    + " to " + app.curSchedGroup);
18572            if (app.waitingToKill != null && app.curReceiver == null
18573                    && app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
18574                app.kill(app.waitingToKill, true);
18575                success = false;
18576            } else {
18577                if (true) {
18578                    long oldId = Binder.clearCallingIdentity();
18579                    try {
18580                        Process.setProcessGroup(app.pid, app.curSchedGroup);
18581                    } catch (Exception e) {
18582                        Slog.w(TAG, "Failed setting process group of " + app.pid
18583                                + " to " + app.curSchedGroup);
18584                        e.printStackTrace();
18585                    } finally {
18586                        Binder.restoreCallingIdentity(oldId);
18587                    }
18588                } else {
18589                    if (app.thread != null) {
18590                        try {
18591                            app.thread.setSchedulingGroup(app.curSchedGroup);
18592                        } catch (RemoteException e) {
18593                        }
18594                    }
18595                }
18596                Process.setSwappiness(app.pid,
18597                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
18598            }
18599        }
18600        if (app.repForegroundActivities != app.foregroundActivities) {
18601            app.repForegroundActivities = app.foregroundActivities;
18602            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
18603        }
18604        if (app.repProcState != app.curProcState) {
18605            app.repProcState = app.curProcState;
18606            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
18607            if (app.thread != null) {
18608                try {
18609                    if (false) {
18610                        //RuntimeException h = new RuntimeException("here");
18611                        Slog.i(TAG, "Sending new process state " + app.repProcState
18612                                + " to " + app /*, h*/);
18613                    }
18614                    app.thread.setProcessState(app.repProcState);
18615                } catch (RemoteException e) {
18616                }
18617            }
18618        }
18619        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
18620                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
18621            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
18622                // Experimental code to more aggressively collect pss while
18623                // running test...  the problem is that this tends to collect
18624                // the data right when a process is transitioning between process
18625                // states, which well tend to give noisy data.
18626                long start = SystemClock.uptimeMillis();
18627                long pss = Debug.getPss(app.pid, mTmpLong, null);
18628                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], now);
18629                mPendingPssProcesses.remove(app);
18630                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
18631                        + " to " + app.curProcState + ": "
18632                        + (SystemClock.uptimeMillis()-start) + "ms");
18633            }
18634            app.lastStateTime = now;
18635            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18636                    mTestPssMode, isSleeping(), now);
18637            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
18638                    + ProcessList.makeProcStateString(app.setProcState) + " to "
18639                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
18640                    + (app.nextPssTime-now) + ": " + app);
18641        } else {
18642            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
18643                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
18644                    mTestPssMode)))) {
18645                requestPssLocked(app, app.setProcState);
18646                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
18647                        mTestPssMode, isSleeping(), now);
18648            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
18649                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
18650        }
18651        if (app.setProcState != app.curProcState) {
18652            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18653                    "Proc state change of " + app.processName
18654                    + " to " + app.curProcState);
18655            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
18656            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
18657            if (setImportant && !curImportant) {
18658                // This app is no longer something we consider important enough to allow to
18659                // use arbitrary amounts of battery power.  Note
18660                // its current wake lock time to later know to kill it if
18661                // it is not behaving well.
18662                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18663                synchronized (stats) {
18664                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
18665                            app.pid, SystemClock.elapsedRealtime());
18666                }
18667                app.lastCpuTime = app.curCpuTime;
18668
18669            }
18670            // Inform UsageStats of important process state change
18671            // Must be called before updating setProcState
18672            maybeUpdateUsageStatsLocked(app);
18673
18674            app.setProcState = app.curProcState;
18675            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18676                app.notCachedSinceIdle = false;
18677            }
18678            if (!doingAll) {
18679                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
18680            } else {
18681                app.procStateChanged = true;
18682            }
18683        }
18684
18685        if (changes != 0) {
18686            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18687                    "Changes in " + app + ": " + changes);
18688            int i = mPendingProcessChanges.size()-1;
18689            ProcessChangeItem item = null;
18690            while (i >= 0) {
18691                item = mPendingProcessChanges.get(i);
18692                if (item.pid == app.pid) {
18693                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18694                            "Re-using existing item: " + item);
18695                    break;
18696                }
18697                i--;
18698            }
18699            if (i < 0) {
18700                // No existing item in pending changes; need a new one.
18701                final int NA = mAvailProcessChanges.size();
18702                if (NA > 0) {
18703                    item = mAvailProcessChanges.remove(NA-1);
18704                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18705                            "Retrieving available item: " + item);
18706                } else {
18707                    item = new ProcessChangeItem();
18708                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18709                            "Allocating new item: " + item);
18710                }
18711                item.changes = 0;
18712                item.pid = app.pid;
18713                item.uid = app.info.uid;
18714                if (mPendingProcessChanges.size() == 0) {
18715                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18716                            "*** Enqueueing dispatch processes changed!");
18717                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
18718                }
18719                mPendingProcessChanges.add(item);
18720            }
18721            item.changes |= changes;
18722            item.processState = app.repProcState;
18723            item.foregroundActivities = app.repForegroundActivities;
18724            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18725                    "Item " + Integer.toHexString(System.identityHashCode(item))
18726                    + " " + app.toShortString() + ": changes=" + item.changes
18727                    + " procState=" + item.processState
18728                    + " foreground=" + item.foregroundActivities
18729                    + " type=" + app.adjType + " source=" + app.adjSource
18730                    + " target=" + app.adjTarget);
18731        }
18732
18733        return success;
18734    }
18735
18736    private final void enqueueUidChangeLocked(UidRecord uidRec, boolean gone) {
18737        if (uidRec.pendingChange == null) {
18738            if (mPendingUidChanges.size() == 0) {
18739                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18740                        "*** Enqueueing dispatch uid changed!");
18741                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_MSG).sendToTarget();
18742            }
18743            final int NA = mAvailUidChanges.size();
18744            if (NA > 0) {
18745                uidRec.pendingChange = mAvailUidChanges.remove(NA-1);
18746                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18747                        "Retrieving available item: " + uidRec.pendingChange);
18748            } else {
18749                uidRec.pendingChange = new UidRecord.ChangeItem();
18750                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18751                        "Allocating new item: " + uidRec.pendingChange);
18752            }
18753            uidRec.pendingChange.uidRecord = uidRec;
18754            uidRec.pendingChange.uid = uidRec.uid;
18755            mPendingUidChanges.add(uidRec.pendingChange);
18756        }
18757        uidRec.pendingChange.gone = gone;
18758        uidRec.pendingChange.processState = uidRec.setProcState;
18759    }
18760
18761    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
18762            String authority) {
18763        if (app == null) return;
18764        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18765            UserState userState = mStartedUsers.get(app.userId);
18766            if (userState == null) return;
18767            final long now = SystemClock.elapsedRealtime();
18768            Long lastReported = userState.mProviderLastReportedFg.get(authority);
18769            if (lastReported == null || lastReported < now - 60 * 1000L) {
18770                mUsageStatsService.reportContentProviderUsage(
18771                        authority, providerPkgName, app.userId);
18772                userState.mProviderLastReportedFg.put(authority, now);
18773            }
18774        }
18775    }
18776
18777    private void maybeUpdateUsageStatsLocked(ProcessRecord app) {
18778        if (DEBUG_USAGE_STATS) {
18779            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
18780                    + "] state changes: old = " + app.setProcState + ", new = "
18781                    + app.curProcState);
18782        }
18783        if (mUsageStatsService == null) {
18784            return;
18785        }
18786        boolean isInteraction;
18787        // To avoid some abuse patterns, we are going to be careful about what we consider
18788        // to be an app interaction.  Being the top activity doesn't count while the display
18789        // is sleeping, nor do short foreground services.
18790        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
18791            isInteraction = true;
18792            app.fgInteractionTime = 0;
18793        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
18794            final long now = SystemClock.elapsedRealtime();
18795            if (app.fgInteractionTime == 0) {
18796                app.fgInteractionTime = now;
18797                isInteraction = false;
18798            } else {
18799                isInteraction = now > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
18800            }
18801        } else {
18802            isInteraction = app.curProcState
18803                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18804            app.fgInteractionTime = 0;
18805        }
18806        if (isInteraction && !app.reportedInteraction) {
18807            String[] packages = app.getPackageList();
18808            if (packages != null) {
18809                for (int i = 0; i < packages.length; i++) {
18810                    mUsageStatsService.reportEvent(packages[i], app.userId,
18811                            UsageEvents.Event.SYSTEM_INTERACTION);
18812                }
18813            }
18814        }
18815        app.reportedInteraction = isInteraction;
18816    }
18817
18818    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
18819        if (proc.thread != null) {
18820            if (proc.baseProcessTracker != null) {
18821                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
18822            }
18823            if (proc.repProcState >= 0) {
18824                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
18825                        proc.repProcState);
18826            }
18827        }
18828    }
18829
18830    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
18831            ProcessRecord TOP_APP, boolean doingAll, long now) {
18832        if (app.thread == null) {
18833            return false;
18834        }
18835
18836        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
18837
18838        return applyOomAdjLocked(app, doingAll, now);
18839    }
18840
18841    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
18842            boolean oomAdj) {
18843        if (isForeground != proc.foregroundServices) {
18844            proc.foregroundServices = isForeground;
18845            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
18846                    proc.info.uid);
18847            if (isForeground) {
18848                if (curProcs == null) {
18849                    curProcs = new ArrayList<ProcessRecord>();
18850                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
18851                }
18852                if (!curProcs.contains(proc)) {
18853                    curProcs.add(proc);
18854                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
18855                            proc.info.packageName, proc.info.uid);
18856                }
18857            } else {
18858                if (curProcs != null) {
18859                    if (curProcs.remove(proc)) {
18860                        mBatteryStatsService.noteEvent(
18861                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
18862                                proc.info.packageName, proc.info.uid);
18863                        if (curProcs.size() <= 0) {
18864                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
18865                        }
18866                    }
18867                }
18868            }
18869            if (oomAdj) {
18870                updateOomAdjLocked();
18871            }
18872        }
18873    }
18874
18875    private final ActivityRecord resumedAppLocked() {
18876        ActivityRecord act = mStackSupervisor.resumedAppLocked();
18877        String pkg;
18878        int uid;
18879        if (act != null) {
18880            pkg = act.packageName;
18881            uid = act.info.applicationInfo.uid;
18882        } else {
18883            pkg = null;
18884            uid = -1;
18885        }
18886        // Has the UID or resumed package name changed?
18887        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
18888                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
18889            if (mCurResumedPackage != null) {
18890                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
18891                        mCurResumedPackage, mCurResumedUid);
18892            }
18893            mCurResumedPackage = pkg;
18894            mCurResumedUid = uid;
18895            if (mCurResumedPackage != null) {
18896                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
18897                        mCurResumedPackage, mCurResumedUid);
18898            }
18899        }
18900        return act;
18901    }
18902
18903    final boolean updateOomAdjLocked(ProcessRecord app) {
18904        final ActivityRecord TOP_ACT = resumedAppLocked();
18905        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18906        final boolean wasCached = app.cached;
18907
18908        mAdjSeq++;
18909
18910        // This is the desired cached adjusment we want to tell it to use.
18911        // If our app is currently cached, we know it, and that is it.  Otherwise,
18912        // we don't know it yet, and it needs to now be cached we will then
18913        // need to do a complete oom adj.
18914        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
18915                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
18916        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
18917                SystemClock.uptimeMillis());
18918        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
18919            // Changed to/from cached state, so apps after it in the LRU
18920            // list may also be changed.
18921            updateOomAdjLocked();
18922        }
18923        return success;
18924    }
18925
18926    final void updateOomAdjLocked() {
18927        final ActivityRecord TOP_ACT = resumedAppLocked();
18928        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18929        final long now = SystemClock.uptimeMillis();
18930        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
18931        final int N = mLruProcesses.size();
18932
18933        if (false) {
18934            RuntimeException e = new RuntimeException();
18935            e.fillInStackTrace();
18936            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
18937        }
18938
18939        // Reset state in all uid records.
18940        for (int i=mActiveUids.size()-1; i>=0; i--) {
18941            final UidRecord uidRec = mActiveUids.valueAt(i);
18942            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18943                    "Starting update of " + uidRec);
18944            uidRec.reset();
18945        }
18946
18947        mAdjSeq++;
18948        mNewNumServiceProcs = 0;
18949        mNewNumAServiceProcs = 0;
18950
18951        final int emptyProcessLimit;
18952        final int cachedProcessLimit;
18953        if (mProcessLimit <= 0) {
18954            emptyProcessLimit = cachedProcessLimit = 0;
18955        } else if (mProcessLimit == 1) {
18956            emptyProcessLimit = 1;
18957            cachedProcessLimit = 0;
18958        } else {
18959            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
18960            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
18961        }
18962
18963        // Let's determine how many processes we have running vs.
18964        // how many slots we have for background processes; we may want
18965        // to put multiple processes in a slot of there are enough of
18966        // them.
18967        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
18968                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
18969        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
18970        if (numEmptyProcs > cachedProcessLimit) {
18971            // If there are more empty processes than our limit on cached
18972            // processes, then use the cached process limit for the factor.
18973            // This ensures that the really old empty processes get pushed
18974            // down to the bottom, so if we are running low on memory we will
18975            // have a better chance at keeping around more cached processes
18976            // instead of a gazillion empty processes.
18977            numEmptyProcs = cachedProcessLimit;
18978        }
18979        int emptyFactor = numEmptyProcs/numSlots;
18980        if (emptyFactor < 1) emptyFactor = 1;
18981        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
18982        if (cachedFactor < 1) cachedFactor = 1;
18983        int stepCached = 0;
18984        int stepEmpty = 0;
18985        int numCached = 0;
18986        int numEmpty = 0;
18987        int numTrimming = 0;
18988
18989        mNumNonCachedProcs = 0;
18990        mNumCachedHiddenProcs = 0;
18991
18992        // First update the OOM adjustment for each of the
18993        // application processes based on their current state.
18994        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
18995        int nextCachedAdj = curCachedAdj+1;
18996        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
18997        int nextEmptyAdj = curEmptyAdj+2;
18998        for (int i=N-1; i>=0; i--) {
18999            ProcessRecord app = mLruProcesses.get(i);
19000            if (!app.killedByAm && app.thread != null) {
19001                app.procStateChanged = false;
19002                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19003
19004                // If we haven't yet assigned the final cached adj
19005                // to the process, do that now.
19006                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
19007                    switch (app.curProcState) {
19008                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19009                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19010                            // This process is a cached process holding activities...
19011                            // assign it the next cached value for that type, and then
19012                            // step that cached level.
19013                            app.curRawAdj = curCachedAdj;
19014                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
19015                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
19016                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
19017                                    + ")");
19018                            if (curCachedAdj != nextCachedAdj) {
19019                                stepCached++;
19020                                if (stepCached >= cachedFactor) {
19021                                    stepCached = 0;
19022                                    curCachedAdj = nextCachedAdj;
19023                                    nextCachedAdj += 2;
19024                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19025                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
19026                                    }
19027                                }
19028                            }
19029                            break;
19030                        default:
19031                            // For everything else, assign next empty cached process
19032                            // level and bump that up.  Note that this means that
19033                            // long-running services that have dropped down to the
19034                            // cached level will be treated as empty (since their process
19035                            // state is still as a service), which is what we want.
19036                            app.curRawAdj = curEmptyAdj;
19037                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
19038                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
19039                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
19040                                    + ")");
19041                            if (curEmptyAdj != nextEmptyAdj) {
19042                                stepEmpty++;
19043                                if (stepEmpty >= emptyFactor) {
19044                                    stepEmpty = 0;
19045                                    curEmptyAdj = nextEmptyAdj;
19046                                    nextEmptyAdj += 2;
19047                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19048                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
19049                                    }
19050                                }
19051                            }
19052                            break;
19053                    }
19054                }
19055
19056                applyOomAdjLocked(app, true, now);
19057
19058                // Count the number of process types.
19059                switch (app.curProcState) {
19060                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19061                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19062                        mNumCachedHiddenProcs++;
19063                        numCached++;
19064                        if (numCached > cachedProcessLimit) {
19065                            app.kill("cached #" + numCached, true);
19066                        }
19067                        break;
19068                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
19069                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
19070                                && app.lastActivityTime < oldTime) {
19071                            app.kill("empty for "
19072                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
19073                                    / 1000) + "s", true);
19074                        } else {
19075                            numEmpty++;
19076                            if (numEmpty > emptyProcessLimit) {
19077                                app.kill("empty #" + numEmpty, true);
19078                            }
19079                        }
19080                        break;
19081                    default:
19082                        mNumNonCachedProcs++;
19083                        break;
19084                }
19085
19086                if (app.isolated && app.services.size() <= 0) {
19087                    // If this is an isolated process, and there are no
19088                    // services running in it, then the process is no longer
19089                    // needed.  We agressively kill these because we can by
19090                    // definition not re-use the same process again, and it is
19091                    // good to avoid having whatever code was running in them
19092                    // left sitting around after no longer needed.
19093                    app.kill("isolated not needed", true);
19094                } else {
19095                    // Keeping this process, update its uid.
19096                    final UidRecord uidRec = app.uidRecord;
19097                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
19098                        uidRec.curProcState = app.curProcState;
19099                    }
19100                }
19101
19102                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19103                        && !app.killedByAm) {
19104                    numTrimming++;
19105                }
19106            }
19107        }
19108
19109        mNumServiceProcs = mNewNumServiceProcs;
19110
19111        // Now determine the memory trimming level of background processes.
19112        // Unfortunately we need to start at the back of the list to do this
19113        // properly.  We only do this if the number of background apps we
19114        // are managing to keep around is less than half the maximum we desire;
19115        // if we are keeping a good number around, we'll let them use whatever
19116        // memory they want.
19117        final int numCachedAndEmpty = numCached + numEmpty;
19118        int memFactor;
19119        if (numCached <= ProcessList.TRIM_CACHED_APPS
19120                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
19121            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
19122                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
19123            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
19124                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
19125            } else {
19126                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
19127            }
19128        } else {
19129            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
19130        }
19131        // We always allow the memory level to go up (better).  We only allow it to go
19132        // down if we are in a state where that is allowed, *and* the total number of processes
19133        // has gone down since last time.
19134        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
19135                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
19136                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
19137        if (memFactor > mLastMemoryLevel) {
19138            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
19139                memFactor = mLastMemoryLevel;
19140                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
19141            }
19142        }
19143        mLastMemoryLevel = memFactor;
19144        mLastNumProcesses = mLruProcesses.size();
19145        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
19146        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
19147        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
19148            if (mLowRamStartTime == 0) {
19149                mLowRamStartTime = now;
19150            }
19151            int step = 0;
19152            int fgTrimLevel;
19153            switch (memFactor) {
19154                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
19155                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
19156                    break;
19157                case ProcessStats.ADJ_MEM_FACTOR_LOW:
19158                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
19159                    break;
19160                default:
19161                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
19162                    break;
19163            }
19164            int factor = numTrimming/3;
19165            int minFactor = 2;
19166            if (mHomeProcess != null) minFactor++;
19167            if (mPreviousProcess != null) minFactor++;
19168            if (factor < minFactor) factor = minFactor;
19169            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
19170            for (int i=N-1; i>=0; i--) {
19171                ProcessRecord app = mLruProcesses.get(i);
19172                if (allChanged || app.procStateChanged) {
19173                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
19174                    app.procStateChanged = false;
19175                }
19176                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19177                        && !app.killedByAm) {
19178                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
19179                        try {
19180                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19181                                    "Trimming memory of " + app.processName + " to " + curLevel);
19182                            app.thread.scheduleTrimMemory(curLevel);
19183                        } catch (RemoteException e) {
19184                        }
19185                        if (false) {
19186                            // For now we won't do this; our memory trimming seems
19187                            // to be good enough at this point that destroying
19188                            // activities causes more harm than good.
19189                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
19190                                    && app != mHomeProcess && app != mPreviousProcess) {
19191                                // Need to do this on its own message because the stack may not
19192                                // be in a consistent state at this point.
19193                                // For these apps we will also finish their activities
19194                                // to help them free memory.
19195                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
19196                            }
19197                        }
19198                    }
19199                    app.trimMemoryLevel = curLevel;
19200                    step++;
19201                    if (step >= factor) {
19202                        step = 0;
19203                        switch (curLevel) {
19204                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
19205                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
19206                                break;
19207                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
19208                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19209                                break;
19210                        }
19211                    }
19212                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19213                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
19214                            && app.thread != null) {
19215                        try {
19216                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19217                                    "Trimming memory of heavy-weight " + app.processName
19218                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19219                            app.thread.scheduleTrimMemory(
19220                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19221                        } catch (RemoteException e) {
19222                        }
19223                    }
19224                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19225                } else {
19226                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19227                            || app.systemNoUi) && app.pendingUiClean) {
19228                        // If this application is now in the background and it
19229                        // had done UI, then give it the special trim level to
19230                        // have it free UI resources.
19231                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
19232                        if (app.trimMemoryLevel < level && app.thread != null) {
19233                            try {
19234                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19235                                        "Trimming memory of bg-ui " + app.processName
19236                                        + " to " + level);
19237                                app.thread.scheduleTrimMemory(level);
19238                            } catch (RemoteException e) {
19239                            }
19240                        }
19241                        app.pendingUiClean = false;
19242                    }
19243                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
19244                        try {
19245                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19246                                    "Trimming memory of fg " + app.processName
19247                                    + " to " + fgTrimLevel);
19248                            app.thread.scheduleTrimMemory(fgTrimLevel);
19249                        } catch (RemoteException e) {
19250                        }
19251                    }
19252                    app.trimMemoryLevel = fgTrimLevel;
19253                }
19254            }
19255        } else {
19256            if (mLowRamStartTime != 0) {
19257                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
19258                mLowRamStartTime = 0;
19259            }
19260            for (int i=N-1; i>=0; i--) {
19261                ProcessRecord app = mLruProcesses.get(i);
19262                if (allChanged || app.procStateChanged) {
19263                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
19264                    app.procStateChanged = false;
19265                }
19266                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19267                        || app.systemNoUi) && app.pendingUiClean) {
19268                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
19269                            && app.thread != null) {
19270                        try {
19271                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19272                                    "Trimming memory of ui hidden " + app.processName
19273                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19274                            app.thread.scheduleTrimMemory(
19275                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19276                        } catch (RemoteException e) {
19277                        }
19278                    }
19279                    app.pendingUiClean = false;
19280                }
19281                app.trimMemoryLevel = 0;
19282            }
19283        }
19284
19285        if (mAlwaysFinishActivities) {
19286            // Need to do this on its own message because the stack may not
19287            // be in a consistent state at this point.
19288            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
19289        }
19290
19291        if (allChanged) {
19292            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
19293        }
19294
19295        // Update from any uid changes.
19296        for (int i=mActiveUids.size()-1; i>=0; i--) {
19297            final UidRecord uidRec = mActiveUids.valueAt(i);
19298            if (uidRec.setProcState != uidRec.curProcState) {
19299                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19300                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
19301                        + " to " + uidRec.curProcState);
19302                uidRec.setProcState = uidRec.curProcState;
19303                enqueueUidChangeLocked(uidRec, false);
19304            }
19305        }
19306
19307        if (mProcessStats.shouldWriteNowLocked(now)) {
19308            mHandler.post(new Runnable() {
19309                @Override public void run() {
19310                    synchronized (ActivityManagerService.this) {
19311                        mProcessStats.writeStateAsyncLocked();
19312                    }
19313                }
19314            });
19315        }
19316
19317        if (DEBUG_OOM_ADJ) {
19318            final long duration = SystemClock.uptimeMillis() - now;
19319            if (false) {
19320                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
19321                        new RuntimeException("here").fillInStackTrace());
19322            } else {
19323                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
19324            }
19325        }
19326    }
19327
19328    final void trimApplications() {
19329        synchronized (this) {
19330            int i;
19331
19332            // First remove any unused application processes whose package
19333            // has been removed.
19334            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
19335                final ProcessRecord app = mRemovedProcesses.get(i);
19336                if (app.activities.size() == 0
19337                        && app.curReceiver == null && app.services.size() == 0) {
19338                    Slog.i(
19339                        TAG, "Exiting empty application process "
19340                        + app.processName + " ("
19341                        + (app.thread != null ? app.thread.asBinder() : null)
19342                        + ")\n");
19343                    if (app.pid > 0 && app.pid != MY_PID) {
19344                        app.kill("empty", false);
19345                    } else {
19346                        try {
19347                            app.thread.scheduleExit();
19348                        } catch (Exception e) {
19349                            // Ignore exceptions.
19350                        }
19351                    }
19352                    cleanUpApplicationRecordLocked(app, false, true, -1);
19353                    mRemovedProcesses.remove(i);
19354
19355                    if (app.persistent) {
19356                        addAppLocked(app.info, false, null /* ABI override */);
19357                    }
19358                }
19359            }
19360
19361            // Now update the oom adj for all processes.
19362            updateOomAdjLocked();
19363        }
19364    }
19365
19366    /** This method sends the specified signal to each of the persistent apps */
19367    public void signalPersistentProcesses(int sig) throws RemoteException {
19368        if (sig != Process.SIGNAL_USR1) {
19369            throw new SecurityException("Only SIGNAL_USR1 is allowed");
19370        }
19371
19372        synchronized (this) {
19373            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
19374                    != PackageManager.PERMISSION_GRANTED) {
19375                throw new SecurityException("Requires permission "
19376                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
19377            }
19378
19379            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
19380                ProcessRecord r = mLruProcesses.get(i);
19381                if (r.thread != null && r.persistent) {
19382                    Process.sendSignal(r.pid, sig);
19383                }
19384            }
19385        }
19386    }
19387
19388    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
19389        if (proc == null || proc == mProfileProc) {
19390            proc = mProfileProc;
19391            profileType = mProfileType;
19392            clearProfilerLocked();
19393        }
19394        if (proc == null) {
19395            return;
19396        }
19397        try {
19398            proc.thread.profilerControl(false, null, profileType);
19399        } catch (RemoteException e) {
19400            throw new IllegalStateException("Process disappeared");
19401        }
19402    }
19403
19404    private void clearProfilerLocked() {
19405        if (mProfileFd != null) {
19406            try {
19407                mProfileFd.close();
19408            } catch (IOException e) {
19409            }
19410        }
19411        mProfileApp = null;
19412        mProfileProc = null;
19413        mProfileFile = null;
19414        mProfileType = 0;
19415        mAutoStopProfiler = false;
19416        mSamplingInterval = 0;
19417    }
19418
19419    public boolean profileControl(String process, int userId, boolean start,
19420            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
19421
19422        try {
19423            synchronized (this) {
19424                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19425                // its own permission.
19426                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19427                        != PackageManager.PERMISSION_GRANTED) {
19428                    throw new SecurityException("Requires permission "
19429                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19430                }
19431
19432                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
19433                    throw new IllegalArgumentException("null profile info or fd");
19434                }
19435
19436                ProcessRecord proc = null;
19437                if (process != null) {
19438                    proc = findProcessLocked(process, userId, "profileControl");
19439                }
19440
19441                if (start && (proc == null || proc.thread == null)) {
19442                    throw new IllegalArgumentException("Unknown process: " + process);
19443                }
19444
19445                if (start) {
19446                    stopProfilerLocked(null, 0);
19447                    setProfileApp(proc.info, proc.processName, profilerInfo);
19448                    mProfileProc = proc;
19449                    mProfileType = profileType;
19450                    ParcelFileDescriptor fd = profilerInfo.profileFd;
19451                    try {
19452                        fd = fd.dup();
19453                    } catch (IOException e) {
19454                        fd = null;
19455                    }
19456                    profilerInfo.profileFd = fd;
19457                    proc.thread.profilerControl(start, profilerInfo, profileType);
19458                    fd = null;
19459                    mProfileFd = null;
19460                } else {
19461                    stopProfilerLocked(proc, profileType);
19462                    if (profilerInfo != null && profilerInfo.profileFd != null) {
19463                        try {
19464                            profilerInfo.profileFd.close();
19465                        } catch (IOException e) {
19466                        }
19467                    }
19468                }
19469
19470                return true;
19471            }
19472        } catch (RemoteException e) {
19473            throw new IllegalStateException("Process disappeared");
19474        } finally {
19475            if (profilerInfo != null && profilerInfo.profileFd != null) {
19476                try {
19477                    profilerInfo.profileFd.close();
19478                } catch (IOException e) {
19479                }
19480            }
19481        }
19482    }
19483
19484    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
19485        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19486                userId, true, ALLOW_FULL_ONLY, callName, null);
19487        ProcessRecord proc = null;
19488        try {
19489            int pid = Integer.parseInt(process);
19490            synchronized (mPidsSelfLocked) {
19491                proc = mPidsSelfLocked.get(pid);
19492            }
19493        } catch (NumberFormatException e) {
19494        }
19495
19496        if (proc == null) {
19497            ArrayMap<String, SparseArray<ProcessRecord>> all
19498                    = mProcessNames.getMap();
19499            SparseArray<ProcessRecord> procs = all.get(process);
19500            if (procs != null && procs.size() > 0) {
19501                proc = procs.valueAt(0);
19502                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
19503                    for (int i=1; i<procs.size(); i++) {
19504                        ProcessRecord thisProc = procs.valueAt(i);
19505                        if (thisProc.userId == userId) {
19506                            proc = thisProc;
19507                            break;
19508                        }
19509                    }
19510                }
19511            }
19512        }
19513
19514        return proc;
19515    }
19516
19517    public boolean dumpHeap(String process, int userId, boolean managed,
19518            String path, ParcelFileDescriptor fd) throws RemoteException {
19519
19520        try {
19521            synchronized (this) {
19522                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19523                // its own permission (same as profileControl).
19524                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19525                        != PackageManager.PERMISSION_GRANTED) {
19526                    throw new SecurityException("Requires permission "
19527                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19528                }
19529
19530                if (fd == null) {
19531                    throw new IllegalArgumentException("null fd");
19532                }
19533
19534                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
19535                if (proc == null || proc.thread == null) {
19536                    throw new IllegalArgumentException("Unknown process: " + process);
19537                }
19538
19539                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19540                if (!isDebuggable) {
19541                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19542                        throw new SecurityException("Process not debuggable: " + proc);
19543                    }
19544                }
19545
19546                proc.thread.dumpHeap(managed, path, fd);
19547                fd = null;
19548                return true;
19549            }
19550        } catch (RemoteException e) {
19551            throw new IllegalStateException("Process disappeared");
19552        } finally {
19553            if (fd != null) {
19554                try {
19555                    fd.close();
19556                } catch (IOException e) {
19557                }
19558            }
19559        }
19560    }
19561
19562    @Override
19563    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
19564            String reportPackage) {
19565        if (processName != null) {
19566            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
19567                    "setDumpHeapDebugLimit()");
19568        } else {
19569            synchronized (mPidsSelfLocked) {
19570                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
19571                if (proc == null) {
19572                    throw new SecurityException("No process found for calling pid "
19573                            + Binder.getCallingPid());
19574                }
19575                if (!Build.IS_DEBUGGABLE
19576                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19577                    throw new SecurityException("Not running a debuggable build");
19578                }
19579                processName = proc.processName;
19580                uid = proc.uid;
19581                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
19582                    throw new SecurityException("Package " + reportPackage + " is not running in "
19583                            + proc);
19584                }
19585            }
19586        }
19587        synchronized (this) {
19588            if (maxMemSize > 0) {
19589                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
19590            } else {
19591                if (uid != 0) {
19592                    mMemWatchProcesses.remove(processName, uid);
19593                } else {
19594                    mMemWatchProcesses.getMap().remove(processName);
19595                }
19596            }
19597        }
19598    }
19599
19600    @Override
19601    public void dumpHeapFinished(String path) {
19602        synchronized (this) {
19603            if (Binder.getCallingPid() != mMemWatchDumpPid) {
19604                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
19605                        + " does not match last pid " + mMemWatchDumpPid);
19606                return;
19607            }
19608            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
19609                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
19610                        + " does not match last path " + mMemWatchDumpFile);
19611                return;
19612            }
19613            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
19614            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
19615        }
19616    }
19617
19618    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
19619    public void monitor() {
19620        synchronized (this) { }
19621    }
19622
19623    void onCoreSettingsChange(Bundle settings) {
19624        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19625            ProcessRecord processRecord = mLruProcesses.get(i);
19626            try {
19627                if (processRecord.thread != null) {
19628                    processRecord.thread.setCoreSettings(settings);
19629                }
19630            } catch (RemoteException re) {
19631                /* ignore */
19632            }
19633        }
19634    }
19635
19636    // Multi-user methods
19637
19638    /**
19639     * Start user, if its not already running, but don't bring it to foreground.
19640     */
19641    @Override
19642    public boolean startUserInBackground(final int userId) {
19643        return startUser(userId, /* foreground */ false);
19644    }
19645
19646    /**
19647     * Start user, if its not already running, and bring it to foreground.
19648     */
19649    boolean startUserInForeground(final int userId, Dialog dlg) {
19650        boolean result = startUser(userId, /* foreground */ true);
19651        dlg.dismiss();
19652        return result;
19653    }
19654
19655    /**
19656     * Refreshes the list of users related to the current user when either a
19657     * user switch happens or when a new related user is started in the
19658     * background.
19659     */
19660    private void updateCurrentProfileIdsLocked() {
19661        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19662                mCurrentUserId, false /* enabledOnly */);
19663        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
19664        for (int i = 0; i < currentProfileIds.length; i++) {
19665            currentProfileIds[i] = profiles.get(i).id;
19666        }
19667        mCurrentProfileIds = currentProfileIds;
19668
19669        synchronized (mUserProfileGroupIdsSelfLocked) {
19670            mUserProfileGroupIdsSelfLocked.clear();
19671            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
19672            for (int i = 0; i < users.size(); i++) {
19673                UserInfo user = users.get(i);
19674                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
19675                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
19676                }
19677            }
19678        }
19679    }
19680
19681    private Set<Integer> getProfileIdsLocked(int userId) {
19682        Set<Integer> userIds = new HashSet<Integer>();
19683        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19684                userId, false /* enabledOnly */);
19685        for (UserInfo user : profiles) {
19686            userIds.add(Integer.valueOf(user.id));
19687        }
19688        return userIds;
19689    }
19690
19691    @Override
19692    public boolean switchUser(final int userId) {
19693        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19694        String userName;
19695        synchronized (this) {
19696            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19697            if (userInfo == null) {
19698                Slog.w(TAG, "No user info for user #" + userId);
19699                return false;
19700            }
19701            if (userInfo.isManagedProfile()) {
19702                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19703                return false;
19704            }
19705            userName = userInfo.name;
19706            mTargetUserId = userId;
19707        }
19708        mUiHandler.removeMessages(START_USER_SWITCH_MSG);
19709        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
19710        return true;
19711    }
19712
19713    private void showUserSwitchDialog(int userId, String userName) {
19714        // The dialog will show and then initiate the user switch by calling startUserInForeground
19715        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
19716                true /* above system */);
19717        d.show();
19718    }
19719
19720    private boolean startUser(final int userId, final boolean foreground) {
19721        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19722                != PackageManager.PERMISSION_GRANTED) {
19723            String msg = "Permission Denial: switchUser() from pid="
19724                    + Binder.getCallingPid()
19725                    + ", uid=" + Binder.getCallingUid()
19726                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19727            Slog.w(TAG, msg);
19728            throw new SecurityException(msg);
19729        }
19730
19731        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
19732
19733        final long ident = Binder.clearCallingIdentity();
19734        try {
19735            synchronized (this) {
19736                final int oldUserId = mCurrentUserId;
19737                if (oldUserId == userId) {
19738                    return true;
19739                }
19740
19741                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
19742                        "startUser", false);
19743
19744                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19745                if (userInfo == null) {
19746                    Slog.w(TAG, "No user info for user #" + userId);
19747                    return false;
19748                }
19749                if (foreground && userInfo.isManagedProfile()) {
19750                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19751                    return false;
19752                }
19753
19754                if (foreground) {
19755                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
19756                            R.anim.screen_user_enter);
19757                }
19758
19759                boolean needStart = false;
19760
19761                // If the user we are switching to is not currently started, then
19762                // we need to start it now.
19763                if (mStartedUsers.get(userId) == null) {
19764                    mStartedUsers.put(userId, new UserState(new UserHandle(userId), false));
19765                    updateStartedUserArrayLocked();
19766                    needStart = true;
19767                }
19768
19769                final Integer userIdInt = Integer.valueOf(userId);
19770                mUserLru.remove(userIdInt);
19771                mUserLru.add(userIdInt);
19772
19773                if (foreground) {
19774                    mCurrentUserId = userId;
19775                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
19776                    updateCurrentProfileIdsLocked();
19777                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
19778                    // Once the internal notion of the active user has switched, we lock the device
19779                    // with the option to show the user switcher on the keyguard.
19780                    mWindowManager.lockNow(null);
19781                } else {
19782                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
19783                    updateCurrentProfileIdsLocked();
19784                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
19785                    mUserLru.remove(currentUserIdInt);
19786                    mUserLru.add(currentUserIdInt);
19787                }
19788
19789                final UserState uss = mStartedUsers.get(userId);
19790
19791                // Make sure user is in the started state.  If it is currently
19792                // stopping, we need to knock that off.
19793                if (uss.mState == UserState.STATE_STOPPING) {
19794                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
19795                    // so we can just fairly silently bring the user back from
19796                    // the almost-dead.
19797                    uss.mState = UserState.STATE_RUNNING;
19798                    updateStartedUserArrayLocked();
19799                    needStart = true;
19800                } else if (uss.mState == UserState.STATE_SHUTDOWN) {
19801                    // This means ACTION_SHUTDOWN has been sent, so we will
19802                    // need to treat this as a new boot of the user.
19803                    uss.mState = UserState.STATE_BOOTING;
19804                    updateStartedUserArrayLocked();
19805                    needStart = true;
19806                }
19807
19808                if (uss.mState == UserState.STATE_BOOTING) {
19809                    // Booting up a new user, need to tell system services about it.
19810                    // Note that this is on the same handler as scheduling of broadcasts,
19811                    // which is important because it needs to go first.
19812                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
19813                }
19814
19815                if (foreground) {
19816                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
19817                            oldUserId));
19818                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
19819                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19820                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
19821                            oldUserId, userId, uss));
19822                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
19823                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
19824                }
19825
19826                if (needStart) {
19827                    // Send USER_STARTED broadcast
19828                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
19829                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19830                            | Intent.FLAG_RECEIVER_FOREGROUND);
19831                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19832                    broadcastIntentLocked(null, null, intent,
19833                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19834                            null, false, false, MY_PID, Process.SYSTEM_UID, userId);
19835                }
19836
19837                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
19838                    if (userId != UserHandle.USER_OWNER) {
19839                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
19840                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19841                        broadcastIntentLocked(null, null, intent, null,
19842                                new IIntentReceiver.Stub() {
19843                                    public void performReceive(Intent intent, int resultCode,
19844                                            String data, Bundle extras, boolean ordered,
19845                                            boolean sticky, int sendingUser) {
19846                                        onUserInitialized(uss, foreground, oldUserId, userId);
19847                                    }
19848                                }, 0, null, null, null, AppOpsManager.OP_NONE,
19849                                null, true, false, MY_PID, Process.SYSTEM_UID, userId);
19850                        uss.initializing = true;
19851                    } else {
19852                        getUserManagerLocked().makeInitialized(userInfo.id);
19853                    }
19854                }
19855
19856                if (foreground) {
19857                    if (!uss.initializing) {
19858                        moveUserToForeground(uss, oldUserId, userId);
19859                    }
19860                } else {
19861                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
19862                }
19863
19864                if (needStart) {
19865                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
19866                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19867                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19868                    broadcastIntentLocked(null, null, intent,
19869                            null, new IIntentReceiver.Stub() {
19870                                @Override
19871                                public void performReceive(Intent intent, int resultCode,
19872                                        String data, Bundle extras, boolean ordered, boolean sticky,
19873                                        int sendingUser) throws RemoteException {
19874                                }
19875                            }, 0, null, null,
19876                            new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
19877                            null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19878                }
19879            }
19880        } finally {
19881            Binder.restoreCallingIdentity(ident);
19882        }
19883
19884        return true;
19885    }
19886
19887    void dispatchForegroundProfileChanged(int userId) {
19888        final int N = mUserSwitchObservers.beginBroadcast();
19889        for (int i = 0; i < N; i++) {
19890            try {
19891                mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
19892            } catch (RemoteException e) {
19893                // Ignore
19894            }
19895        }
19896        mUserSwitchObservers.finishBroadcast();
19897    }
19898
19899    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
19900        long ident = Binder.clearCallingIdentity();
19901        try {
19902            Intent intent;
19903            if (oldUserId >= 0) {
19904                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
19905                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
19906                int count = profiles.size();
19907                for (int i = 0; i < count; i++) {
19908                    int profileUserId = profiles.get(i).id;
19909                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
19910                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19911                            | Intent.FLAG_RECEIVER_FOREGROUND);
19912                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19913                    broadcastIntentLocked(null, null, intent,
19914                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19915                            null, false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19916                }
19917            }
19918            if (newUserId >= 0) {
19919                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
19920                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
19921                int count = profiles.size();
19922                for (int i = 0; i < count; i++) {
19923                    int profileUserId = profiles.get(i).id;
19924                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
19925                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19926                            | Intent.FLAG_RECEIVER_FOREGROUND);
19927                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19928                    broadcastIntentLocked(null, null, intent,
19929                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19930                            null, false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19931                }
19932                intent = new Intent(Intent.ACTION_USER_SWITCHED);
19933                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19934                        | Intent.FLAG_RECEIVER_FOREGROUND);
19935                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
19936                broadcastIntentLocked(null, null, intent,
19937                        null, null, 0, null, null,
19938                        new String[] {android.Manifest.permission.MANAGE_USERS},
19939                        AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
19940                        UserHandle.USER_ALL);
19941            }
19942        } finally {
19943            Binder.restoreCallingIdentity(ident);
19944        }
19945    }
19946
19947    void dispatchUserSwitch(final UserState uss, final int oldUserId,
19948            final int newUserId) {
19949        final int N = mUserSwitchObservers.beginBroadcast();
19950        if (N > 0) {
19951            final IRemoteCallback callback = new IRemoteCallback.Stub() {
19952                int mCount = 0;
19953                @Override
19954                public void sendResult(Bundle data) throws RemoteException {
19955                    synchronized (ActivityManagerService.this) {
19956                        if (mCurUserSwitchCallback == this) {
19957                            mCount++;
19958                            if (mCount == N) {
19959                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19960                            }
19961                        }
19962                    }
19963                }
19964            };
19965            synchronized (this) {
19966                uss.switching = true;
19967                mCurUserSwitchCallback = callback;
19968            }
19969            for (int i=0; i<N; i++) {
19970                try {
19971                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
19972                            newUserId, callback);
19973                } catch (RemoteException e) {
19974                }
19975            }
19976        } else {
19977            synchronized (this) {
19978                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19979            }
19980        }
19981        mUserSwitchObservers.finishBroadcast();
19982    }
19983
19984    void timeoutUserSwitch(UserState uss, int oldUserId, int newUserId) {
19985        synchronized (this) {
19986            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
19987            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19988        }
19989    }
19990
19991    void sendContinueUserSwitchLocked(UserState uss, int oldUserId, int newUserId) {
19992        mCurUserSwitchCallback = null;
19993        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19994        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
19995                oldUserId, newUserId, uss));
19996    }
19997
19998    void onUserInitialized(UserState uss, boolean foreground, int oldUserId, int newUserId) {
19999        synchronized (this) {
20000            if (foreground) {
20001                moveUserToForeground(uss, oldUserId, newUserId);
20002            }
20003        }
20004
20005        completeSwitchAndInitialize(uss, newUserId, true, false);
20006    }
20007
20008    void moveUserToForeground(UserState uss, int oldUserId, int newUserId) {
20009        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
20010        if (homeInFront) {
20011            startHomeActivityLocked(newUserId, "moveUserToFroreground");
20012        } else {
20013            mStackSupervisor.resumeTopActivitiesLocked();
20014        }
20015        EventLogTags.writeAmSwitchUser(newUserId);
20016        getUserManagerLocked().onUserForeground(newUserId);
20017        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
20018    }
20019
20020    void continueUserSwitch(UserState uss, int oldUserId, int newUserId) {
20021        completeSwitchAndInitialize(uss, newUserId, false, true);
20022    }
20023
20024    void completeSwitchAndInitialize(UserState uss, int newUserId,
20025            boolean clearInitializing, boolean clearSwitching) {
20026        boolean unfrozen = false;
20027        synchronized (this) {
20028            if (clearInitializing) {
20029                uss.initializing = false;
20030                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
20031            }
20032            if (clearSwitching) {
20033                uss.switching = false;
20034            }
20035            if (!uss.switching && !uss.initializing) {
20036                mWindowManager.stopFreezingScreen();
20037                unfrozen = true;
20038            }
20039        }
20040        if (unfrozen) {
20041            mHandler.removeMessages(REPORT_USER_SWITCH_COMPLETE_MSG);
20042            mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_COMPLETE_MSG,
20043                    newUserId, 0));
20044        }
20045        stopGuestUserIfBackground();
20046    }
20047
20048    /** Called on handler thread */
20049    void dispatchUserSwitchComplete(int userId) {
20050        final int observerCount = mUserSwitchObservers.beginBroadcast();
20051        for (int i = 0; i < observerCount; i++) {
20052            try {
20053                mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(userId);
20054            } catch (RemoteException e) {
20055            }
20056        }
20057        mUserSwitchObservers.finishBroadcast();
20058    }
20059
20060    /**
20061     * Stops the guest user if it has gone to the background.
20062     */
20063    private void stopGuestUserIfBackground() {
20064        synchronized (this) {
20065            final int num = mUserLru.size();
20066            for (int i = 0; i < num; i++) {
20067                Integer oldUserId = mUserLru.get(i);
20068                UserState oldUss = mStartedUsers.get(oldUserId);
20069                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
20070                        || oldUss.mState == UserState.STATE_STOPPING
20071                        || oldUss.mState == UserState.STATE_SHUTDOWN) {
20072                    continue;
20073                }
20074                UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
20075                if (userInfo.isGuest()) {
20076                    // This is a user to be stopped.
20077                    stopUserLocked(oldUserId, null);
20078                    break;
20079                }
20080            }
20081        }
20082    }
20083
20084    void scheduleStartProfilesLocked() {
20085        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20086            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20087                    DateUtils.SECOND_IN_MILLIS);
20088        }
20089    }
20090
20091    void startProfilesLocked() {
20092        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
20093        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
20094                mCurrentUserId, false /* enabledOnly */);
20095        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
20096        for (UserInfo user : profiles) {
20097            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
20098                    && user.id != mCurrentUserId) {
20099                toStart.add(user);
20100            }
20101        }
20102        final int n = toStart.size();
20103        int i = 0;
20104        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
20105            startUserInBackground(toStart.get(i).id);
20106        }
20107        if (i < n) {
20108            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
20109        }
20110    }
20111
20112    void finishUserBoot(UserState uss) {
20113        synchronized (this) {
20114            if (uss.mState == UserState.STATE_BOOTING
20115                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
20116                uss.mState = UserState.STATE_RUNNING;
20117                final int userId = uss.mHandle.getIdentifier();
20118                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
20119                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20120                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
20121                broadcastIntentLocked(null, null, intent,
20122                        null, null, 0, null, null,
20123                        new String[] {android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
20124                        AppOpsManager.OP_NONE, null, true, false, MY_PID, Process.SYSTEM_UID,
20125                        userId);
20126            }
20127        }
20128    }
20129
20130    void finishUserSwitch(UserState uss) {
20131        synchronized (this) {
20132            finishUserBoot(uss);
20133
20134            startProfilesLocked();
20135
20136            int num = mUserLru.size();
20137            int i = 0;
20138            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
20139                Integer oldUserId = mUserLru.get(i);
20140                UserState oldUss = mStartedUsers.get(oldUserId);
20141                if (oldUss == null) {
20142                    // Shouldn't happen, but be sane if it does.
20143                    mUserLru.remove(i);
20144                    num--;
20145                    continue;
20146                }
20147                if (oldUss.mState == UserState.STATE_STOPPING
20148                        || oldUss.mState == UserState.STATE_SHUTDOWN) {
20149                    // This user is already stopping, doesn't count.
20150                    num--;
20151                    i++;
20152                    continue;
20153                }
20154                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
20155                    // Owner and current can't be stopped, but count as running.
20156                    i++;
20157                    continue;
20158                }
20159                // This is a user to be stopped.
20160                stopUserLocked(oldUserId, null);
20161                num--;
20162                i++;
20163            }
20164        }
20165    }
20166
20167    @Override
20168    public int stopUser(final int userId, final IStopUserCallback callback) {
20169        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20170                != PackageManager.PERMISSION_GRANTED) {
20171            String msg = "Permission Denial: switchUser() from pid="
20172                    + Binder.getCallingPid()
20173                    + ", uid=" + Binder.getCallingUid()
20174                    + " requires " + INTERACT_ACROSS_USERS_FULL;
20175            Slog.w(TAG, msg);
20176            throw new SecurityException(msg);
20177        }
20178        if (userId < 0 || userId == UserHandle.USER_OWNER) {
20179            throw new IllegalArgumentException("Can't stop primary user " + userId);
20180        }
20181        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
20182        synchronized (this) {
20183            return stopUserLocked(userId, callback);
20184        }
20185    }
20186
20187    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
20188        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
20189        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
20190            return ActivityManager.USER_OP_IS_CURRENT;
20191        }
20192
20193        final UserState uss = mStartedUsers.get(userId);
20194        if (uss == null) {
20195            // User is not started, nothing to do...  but we do need to
20196            // callback if requested.
20197            if (callback != null) {
20198                mHandler.post(new Runnable() {
20199                    @Override
20200                    public void run() {
20201                        try {
20202                            callback.userStopped(userId);
20203                        } catch (RemoteException e) {
20204                        }
20205                    }
20206                });
20207            }
20208            return ActivityManager.USER_OP_SUCCESS;
20209        }
20210
20211        if (callback != null) {
20212            uss.mStopCallbacks.add(callback);
20213        }
20214
20215        if (uss.mState != UserState.STATE_STOPPING
20216                && uss.mState != UserState.STATE_SHUTDOWN) {
20217            uss.mState = UserState.STATE_STOPPING;
20218            updateStartedUserArrayLocked();
20219
20220            long ident = Binder.clearCallingIdentity();
20221            try {
20222                // We are going to broadcast ACTION_USER_STOPPING and then
20223                // once that is done send a final ACTION_SHUTDOWN and then
20224                // stop the user.
20225                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
20226                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20227                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20228                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
20229                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
20230                // This is the result receiver for the final shutdown broadcast.
20231                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
20232                    @Override
20233                    public void performReceive(Intent intent, int resultCode, String data,
20234                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
20235                        finishUserStop(uss);
20236                    }
20237                };
20238                // This is the result receiver for the initial stopping broadcast.
20239                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
20240                    @Override
20241                    public void performReceive(Intent intent, int resultCode, String data,
20242                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
20243                        // On to the next.
20244                        synchronized (ActivityManagerService.this) {
20245                            if (uss.mState != UserState.STATE_STOPPING) {
20246                                // Whoops, we are being started back up.  Abort, abort!
20247                                return;
20248                            }
20249                            uss.mState = UserState.STATE_SHUTDOWN;
20250                        }
20251                        mBatteryStatsService.noteEvent(
20252                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
20253                                Integer.toString(userId), userId);
20254                        mSystemServiceManager.stopUser(userId);
20255                        broadcastIntentLocked(null, null, shutdownIntent,
20256                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
20257                                null, true, false, MY_PID, Process.SYSTEM_UID, userId);
20258                    }
20259                };
20260                // Kick things off.
20261                broadcastIntentLocked(null, null, stoppingIntent,
20262                        null, stoppingReceiver, 0, null, null,
20263                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
20264                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
20265            } finally {
20266                Binder.restoreCallingIdentity(ident);
20267            }
20268        }
20269
20270        return ActivityManager.USER_OP_SUCCESS;
20271    }
20272
20273    void finishUserStop(UserState uss) {
20274        final int userId = uss.mHandle.getIdentifier();
20275        boolean stopped;
20276        ArrayList<IStopUserCallback> callbacks;
20277        synchronized (this) {
20278            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
20279            if (mStartedUsers.get(userId) != uss) {
20280                stopped = false;
20281            } else if (uss.mState != UserState.STATE_SHUTDOWN) {
20282                stopped = false;
20283            } else {
20284                stopped = true;
20285                // User can no longer run.
20286                mStartedUsers.remove(userId);
20287                mUserLru.remove(Integer.valueOf(userId));
20288                updateStartedUserArrayLocked();
20289
20290                // Clean up all state and processes associated with the user.
20291                // Kill all the processes for the user.
20292                forceStopUserLocked(userId, "finish user");
20293            }
20294
20295            // Explicitly remove the old information in mRecentTasks.
20296            mRecentTasks.removeTasksForUserLocked(userId);
20297        }
20298
20299        for (int i=0; i<callbacks.size(); i++) {
20300            try {
20301                if (stopped) callbacks.get(i).userStopped(userId);
20302                else callbacks.get(i).userStopAborted(userId);
20303            } catch (RemoteException e) {
20304            }
20305        }
20306
20307        if (stopped) {
20308            mSystemServiceManager.cleanupUser(userId);
20309            synchronized (this) {
20310                mStackSupervisor.removeUserLocked(userId);
20311            }
20312        }
20313    }
20314
20315    @Override
20316    public UserInfo getCurrentUser() {
20317        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
20318                != PackageManager.PERMISSION_GRANTED) && (
20319                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20320                != PackageManager.PERMISSION_GRANTED)) {
20321            String msg = "Permission Denial: getCurrentUser() from pid="
20322                    + Binder.getCallingPid()
20323                    + ", uid=" + Binder.getCallingUid()
20324                    + " requires " + INTERACT_ACROSS_USERS;
20325            Slog.w(TAG, msg);
20326            throw new SecurityException(msg);
20327        }
20328        synchronized (this) {
20329            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20330            return getUserManagerLocked().getUserInfo(userId);
20331        }
20332    }
20333
20334    int getCurrentUserIdLocked() {
20335        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20336    }
20337
20338    @Override
20339    public boolean isUserRunning(int userId, boolean orStopped) {
20340        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20341                != PackageManager.PERMISSION_GRANTED) {
20342            String msg = "Permission Denial: isUserRunning() from pid="
20343                    + Binder.getCallingPid()
20344                    + ", uid=" + Binder.getCallingUid()
20345                    + " requires " + INTERACT_ACROSS_USERS;
20346            Slog.w(TAG, msg);
20347            throw new SecurityException(msg);
20348        }
20349        synchronized (this) {
20350            return isUserRunningLocked(userId, orStopped);
20351        }
20352    }
20353
20354    boolean isUserRunningLocked(int userId, boolean orStopped) {
20355        UserState state = mStartedUsers.get(userId);
20356        if (state == null) {
20357            return false;
20358        }
20359        if (orStopped) {
20360            return true;
20361        }
20362        return state.mState != UserState.STATE_STOPPING
20363                && state.mState != UserState.STATE_SHUTDOWN;
20364    }
20365
20366    @Override
20367    public int[] getRunningUserIds() {
20368        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20369                != PackageManager.PERMISSION_GRANTED) {
20370            String msg = "Permission Denial: isUserRunning() from pid="
20371                    + Binder.getCallingPid()
20372                    + ", uid=" + Binder.getCallingUid()
20373                    + " requires " + INTERACT_ACROSS_USERS;
20374            Slog.w(TAG, msg);
20375            throw new SecurityException(msg);
20376        }
20377        synchronized (this) {
20378            return mStartedUserArray;
20379        }
20380    }
20381
20382    private void updateStartedUserArrayLocked() {
20383        int num = 0;
20384        for (int i=0; i<mStartedUsers.size();  i++) {
20385            UserState uss = mStartedUsers.valueAt(i);
20386            // This list does not include stopping users.
20387            if (uss.mState != UserState.STATE_STOPPING
20388                    && uss.mState != UserState.STATE_SHUTDOWN) {
20389                num++;
20390            }
20391        }
20392        mStartedUserArray = new int[num];
20393        num = 0;
20394        for (int i=0; i<mStartedUsers.size();  i++) {
20395            UserState uss = mStartedUsers.valueAt(i);
20396            if (uss.mState != UserState.STATE_STOPPING
20397                    && uss.mState != UserState.STATE_SHUTDOWN) {
20398                mStartedUserArray[num] = mStartedUsers.keyAt(i);
20399                num++;
20400            }
20401        }
20402    }
20403
20404    @Override
20405    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20406        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20407                != PackageManager.PERMISSION_GRANTED) {
20408            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
20409                    + Binder.getCallingPid()
20410                    + ", uid=" + Binder.getCallingUid()
20411                    + " requires " + INTERACT_ACROSS_USERS_FULL;
20412            Slog.w(TAG, msg);
20413            throw new SecurityException(msg);
20414        }
20415
20416        mUserSwitchObservers.register(observer);
20417    }
20418
20419    @Override
20420    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20421        mUserSwitchObservers.unregister(observer);
20422    }
20423
20424    int[] getUsersLocked() {
20425        UserManagerService ums = getUserManagerLocked();
20426        return ums != null ? ums.getUserIds() : new int[] { 0 };
20427    }
20428
20429    UserManagerService getUserManagerLocked() {
20430        if (mUserManager == null) {
20431            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
20432            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
20433        }
20434        return mUserManager;
20435    }
20436
20437    private int applyUserId(int uid, int userId) {
20438        return UserHandle.getUid(userId, uid);
20439    }
20440
20441    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20442        if (info == null) return null;
20443        ApplicationInfo newInfo = new ApplicationInfo(info);
20444        newInfo.uid = applyUserId(info.uid, userId);
20445        newInfo.dataDir = Environment
20446                .getDataUserPackageDirectory(info.volumeUuid, userId, info.packageName)
20447                .getAbsolutePath();
20448        return newInfo;
20449    }
20450
20451    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20452        if (aInfo == null
20453                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20454            return aInfo;
20455        }
20456
20457        ActivityInfo info = new ActivityInfo(aInfo);
20458        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20459        return info;
20460    }
20461
20462    private final class LocalService extends ActivityManagerInternal {
20463        @Override
20464        public void onWakefulnessChanged(int wakefulness) {
20465            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20466        }
20467
20468        @Override
20469        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20470                String processName, String abiOverride, int uid, Runnable crashHandler) {
20471            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20472                    processName, abiOverride, uid, crashHandler);
20473        }
20474
20475        @Override
20476        public SleepToken acquireSleepToken(String tag) {
20477            Preconditions.checkNotNull(tag);
20478
20479            synchronized (ActivityManagerService.this) {
20480                SleepTokenImpl token = new SleepTokenImpl(tag);
20481                mSleepTokens.add(token);
20482                updateSleepIfNeededLocked();
20483                return token;
20484            }
20485        }
20486
20487        @Override
20488        public ComponentName getHomeActivityForUser(int userId) {
20489            synchronized (ActivityManagerService.this) {
20490                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20491                return homeActivity == null ? null : homeActivity.realActivity;
20492            }
20493        }
20494    }
20495
20496    private final class SleepTokenImpl extends SleepToken {
20497        private final String mTag;
20498        private final long mAcquireTime;
20499
20500        public SleepTokenImpl(String tag) {
20501            mTag = tag;
20502            mAcquireTime = SystemClock.uptimeMillis();
20503        }
20504
20505        @Override
20506        public void release() {
20507            synchronized (ActivityManagerService.this) {
20508                if (mSleepTokens.remove(this)) {
20509                    updateSleepIfNeededLocked();
20510                }
20511            }
20512        }
20513
20514        @Override
20515        public String toString() {
20516            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20517        }
20518    }
20519
20520    /**
20521     * An implementation of IAppTask, that allows an app to manage its own tasks via
20522     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
20523     * only the process that calls getAppTasks() can call the AppTask methods.
20524     */
20525    class AppTaskImpl extends IAppTask.Stub {
20526        private int mTaskId;
20527        private int mCallingUid;
20528
20529        public AppTaskImpl(int taskId, int callingUid) {
20530            mTaskId = taskId;
20531            mCallingUid = callingUid;
20532        }
20533
20534        private void checkCaller() {
20535            if (mCallingUid != Binder.getCallingUid()) {
20536                throw new SecurityException("Caller " + mCallingUid
20537                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
20538            }
20539        }
20540
20541        @Override
20542        public void finishAndRemoveTask() {
20543            checkCaller();
20544
20545            synchronized (ActivityManagerService.this) {
20546                long origId = Binder.clearCallingIdentity();
20547                try {
20548                    if (!removeTaskByIdLocked(mTaskId, false)) {
20549                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20550                    }
20551                } finally {
20552                    Binder.restoreCallingIdentity(origId);
20553                }
20554            }
20555        }
20556
20557        @Override
20558        public ActivityManager.RecentTaskInfo getTaskInfo() {
20559            checkCaller();
20560
20561            synchronized (ActivityManagerService.this) {
20562                long origId = Binder.clearCallingIdentity();
20563                try {
20564                    TaskRecord tr = mRecentTasks.taskForIdLocked(mTaskId);
20565                    if (tr == null) {
20566                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20567                    }
20568                    return createRecentTaskInfoFromTaskRecord(tr);
20569                } finally {
20570                    Binder.restoreCallingIdentity(origId);
20571                }
20572            }
20573        }
20574
20575        @Override
20576        public void moveToFront() {
20577            checkCaller();
20578            // Will bring task to front if it already has a root activity.
20579            startActivityFromRecentsInner(mTaskId, null);
20580        }
20581
20582        @Override
20583        public int startActivity(IBinder whoThread, String callingPackage,
20584                Intent intent, String resolvedType, Bundle options) {
20585            checkCaller();
20586
20587            int callingUser = UserHandle.getCallingUserId();
20588            TaskRecord tr;
20589            IApplicationThread appThread;
20590            synchronized (ActivityManagerService.this) {
20591                tr = mRecentTasks.taskForIdLocked(mTaskId);
20592                if (tr == null) {
20593                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20594                }
20595                appThread = ApplicationThreadNative.asInterface(whoThread);
20596                if (appThread == null) {
20597                    throw new IllegalArgumentException("Bad app thread " + appThread);
20598                }
20599            }
20600            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
20601                    resolvedType, null, null, null, null, 0, 0, null, null,
20602                    null, options, false, callingUser, null, tr);
20603        }
20604
20605        @Override
20606        public void setExcludeFromRecents(boolean exclude) {
20607            checkCaller();
20608
20609            synchronized (ActivityManagerService.this) {
20610                long origId = Binder.clearCallingIdentity();
20611                try {
20612                    TaskRecord tr = mRecentTasks.taskForIdLocked(mTaskId);
20613                    if (tr == null) {
20614                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20615                    }
20616                    Intent intent = tr.getBaseIntent();
20617                    if (exclude) {
20618                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20619                    } else {
20620                        intent.setFlags(intent.getFlags()
20621                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20622                    }
20623                } finally {
20624                    Binder.restoreCallingIdentity(origId);
20625                }
20626            }
20627        }
20628    }
20629}
20630