ActivityManagerService.java revision 73795315885adba0732af5cf19f4eeecd559bf30
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;
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.IActivityContainer;
43import android.app.IActivityContainerCallback;
44import android.app.IAppTask;
45import android.app.ITaskStackListener;
46import android.app.ProfilerInfo;
47import android.app.usage.UsageEvents;
48import android.app.usage.UsageStatsManagerInternal;
49import android.appwidget.AppWidgetManager;
50import android.content.pm.PermissionInfo;
51import android.content.res.Resources;
52import android.graphics.Bitmap;
53import android.graphics.Point;
54import android.graphics.Rect;
55import android.os.BatteryStats;
56import android.os.PersistableBundle;
57import android.os.PowerManager;
58import android.os.TransactionTooLargeException;
59import android.os.WorkSource;
60import android.os.storage.IMountService;
61import android.os.storage.StorageManager;
62import android.service.voice.IVoiceInteractionSession;
63import android.util.ArrayMap;
64import android.util.ArraySet;
65import android.util.DebugUtils;
66import android.util.SparseIntArray;
67import android.view.Display;
68
69import com.android.internal.R;
70import com.android.internal.annotations.GuardedBy;
71import com.android.internal.app.DumpHeapActivity;
72import com.android.internal.app.IAppOpsService;
73import com.android.internal.app.IVoiceInteractor;
74import com.android.internal.app.ProcessMap;
75import com.android.internal.app.ProcessStats;
76import com.android.internal.os.BackgroundThread;
77import com.android.internal.os.BatteryStatsImpl;
78import com.android.internal.os.IResultReceiver;
79import com.android.internal.os.ProcessCpuTracker;
80import com.android.internal.os.TransferPipe;
81import com.android.internal.os.Zygote;
82import com.android.internal.util.ArrayUtils;
83import com.android.internal.util.FastPrintWriter;
84import com.android.internal.util.FastXmlSerializer;
85import com.android.internal.util.MemInfoReader;
86import com.android.internal.util.Preconditions;
87import com.android.server.AppOpsService;
88import com.android.server.AttributeCache;
89import com.android.server.IntentResolver;
90import com.android.server.LocalServices;
91import com.android.server.ServiceThread;
92import com.android.server.SystemService;
93import com.android.server.SystemServiceManager;
94import com.android.server.Watchdog;
95import com.android.server.am.ActivityStack.ActivityState;
96import com.android.server.firewall.IntentFirewall;
97import com.android.server.pm.Installer;
98import com.android.server.pm.UserManagerService;
99import com.android.server.statusbar.StatusBarManagerInternal;
100import com.android.server.wm.AppTransition;
101import com.android.server.wm.WindowManagerService;
102import com.google.android.collect.Lists;
103import com.google.android.collect.Maps;
104
105import libcore.io.IoUtils;
106import libcore.util.EmptyArray;
107
108import org.xmlpull.v1.XmlPullParser;
109import org.xmlpull.v1.XmlPullParserException;
110import org.xmlpull.v1.XmlSerializer;
111
112import android.app.Activity;
113import android.app.ActivityManager;
114import android.app.ActivityManager.RunningTaskInfo;
115import android.app.ActivityManager.StackInfo;
116import android.app.ActivityManagerInternal;
117import android.app.ActivityManagerInternal.SleepToken;
118import android.app.ActivityManagerNative;
119import android.app.ActivityOptions;
120import android.app.ActivityThread;
121import android.app.AlertDialog;
122import android.app.AppGlobals;
123import android.app.ApplicationErrorReport;
124import android.app.Dialog;
125import android.app.IActivityController;
126import android.app.IApplicationThread;
127import android.app.IInstrumentationWatcher;
128import android.app.INotificationManager;
129import android.app.IProcessObserver;
130import android.app.IServiceConnection;
131import android.app.IStopUserCallback;
132import android.app.IUidObserver;
133import android.app.IUiAutomationConnection;
134import android.app.IUserSwitchObserver;
135import android.app.Instrumentation;
136import android.app.Notification;
137import android.app.NotificationManager;
138import android.app.PendingIntent;
139import android.app.backup.IBackupManager;
140import android.content.ActivityNotFoundException;
141import android.content.BroadcastReceiver;
142import android.content.ClipData;
143import android.content.ComponentCallbacks2;
144import android.content.ComponentName;
145import android.content.ContentProvider;
146import android.content.ContentResolver;
147import android.content.Context;
148import android.content.DialogInterface;
149import android.content.IContentProvider;
150import android.content.IIntentReceiver;
151import android.content.IIntentSender;
152import android.content.Intent;
153import android.content.IntentFilter;
154import android.content.IntentSender;
155import android.content.pm.ActivityInfo;
156import android.content.pm.ApplicationInfo;
157import android.content.pm.ConfigurationInfo;
158import android.content.pm.IPackageDataObserver;
159import android.content.pm.IPackageManager;
160import android.content.pm.InstrumentationInfo;
161import android.content.pm.PackageInfo;
162import android.content.pm.PackageManager;
163import android.content.pm.ParceledListSlice;
164import android.content.pm.UserInfo;
165import android.content.pm.PackageManager.NameNotFoundException;
166import android.content.pm.PathPermission;
167import android.content.pm.ProviderInfo;
168import android.content.pm.ResolveInfo;
169import android.content.pm.ServiceInfo;
170import android.content.res.CompatibilityInfo;
171import android.content.res.Configuration;
172import android.net.Proxy;
173import android.net.ProxyInfo;
174import android.net.Uri;
175import android.os.Binder;
176import android.os.Build;
177import android.os.Bundle;
178import android.os.Debug;
179import android.os.DropBoxManager;
180import android.os.Environment;
181import android.os.FactoryTest;
182import android.os.FileObserver;
183import android.os.FileUtils;
184import android.os.Handler;
185import android.os.IBinder;
186import android.os.IPermissionController;
187import android.os.IProcessInfoService;
188import android.os.IRemoteCallback;
189import android.os.IUserManager;
190import android.os.Looper;
191import android.os.Message;
192import android.os.Parcel;
193import android.os.ParcelFileDescriptor;
194import android.os.PowerManagerInternal;
195import android.os.Process;
196import android.os.RemoteCallbackList;
197import android.os.RemoteException;
198import android.os.SELinux;
199import android.os.ServiceManager;
200import android.os.StrictMode;
201import android.os.SystemClock;
202import android.os.SystemProperties;
203import android.os.UpdateLock;
204import android.os.UserHandle;
205import android.os.UserManager;
206import android.provider.Settings;
207import android.text.format.DateUtils;
208import android.text.format.Time;
209import android.util.AtomicFile;
210import android.util.EventLog;
211import android.util.Log;
212import android.util.Pair;
213import android.util.PrintWriterPrinter;
214import android.util.Slog;
215import android.util.SparseArray;
216import android.util.TimeUtils;
217import android.util.Xml;
218import android.view.Gravity;
219import android.view.LayoutInflater;
220import android.view.View;
221import android.view.WindowManager;
222
223import dalvik.system.VMRuntime;
224
225import java.io.BufferedInputStream;
226import java.io.BufferedOutputStream;
227import java.io.DataInputStream;
228import java.io.DataOutputStream;
229import java.io.File;
230import java.io.FileDescriptor;
231import java.io.FileInputStream;
232import java.io.FileNotFoundException;
233import java.io.FileOutputStream;
234import java.io.IOException;
235import java.io.InputStreamReader;
236import java.io.PrintWriter;
237import java.io.StringWriter;
238import java.lang.ref.WeakReference;
239import java.nio.charset.StandardCharsets;
240import java.util.ArrayList;
241import java.util.Arrays;
242import java.util.Collections;
243import java.util.Comparator;
244import java.util.HashMap;
245import java.util.HashSet;
246import java.util.Iterator;
247import java.util.List;
248import java.util.Locale;
249import java.util.Map;
250import java.util.Set;
251import java.util.concurrent.atomic.AtomicBoolean;
252import java.util.concurrent.atomic.AtomicLong;
253
254public final class ActivityManagerService extends ActivityManagerNative
255        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
256
257    // File that stores last updated system version and called preboot receivers
258    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
259
260    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
261    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
262    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
263    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
264    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
265    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
266    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
267    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
268    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
269    private static final String TAG_LRU = TAG + POSTFIX_LRU;
270    private static final String TAG_MU = TAG + POSTFIX_MU;
271    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
272    private static final String TAG_POWER = TAG + POSTFIX_POWER;
273    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
274    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
275    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
276    private static final String TAG_PSS = TAG + POSTFIX_PSS;
277    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
278    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
279    private static final String TAG_STACK = TAG + POSTFIX_STACK;
280    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
281    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
282    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
283    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
284
285    /** Control over CPU and battery monitoring */
286    // write battery stats every 30 minutes.
287    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
288    static final boolean MONITOR_CPU_USAGE = true;
289    // don't sample cpu less than every 5 seconds.
290    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
291    // wait possibly forever for next cpu sample.
292    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
293    static final boolean MONITOR_THREAD_CPU_USAGE = false;
294
295    // The flags that are set for all calls we make to the package manager.
296    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
297
298    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
299
300    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
301
302    // Amount of time after a call to stopAppSwitches() during which we will
303    // prevent further untrusted switches from happening.
304    static final long APP_SWITCH_DELAY_TIME = 5*1000;
305
306    // How long we wait for a launched process to attach to the activity manager
307    // before we decide it's never going to come up for real.
308    static final int PROC_START_TIMEOUT = 10*1000;
309
310    // How long we wait for a launched process to attach to the activity manager
311    // before we decide it's never going to come up for real, when the process was
312    // started with a wrapper for instrumentation (such as Valgrind) because it
313    // could take much longer than usual.
314    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
315
316    // How long to wait after going idle before forcing apps to GC.
317    static final int GC_TIMEOUT = 5*1000;
318
319    // The minimum amount of time between successive GC requests for a process.
320    static final int GC_MIN_INTERVAL = 60*1000;
321
322    // The minimum amount of time between successive PSS requests for a process.
323    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
324
325    // The minimum amount of time between successive PSS requests for a process
326    // when the request is due to the memory state being lowered.
327    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
328
329    // The rate at which we check for apps using excessive power -- 15 mins.
330    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
331
332    // The minimum sample duration we will allow before deciding we have
333    // enough data on wake locks to start killing things.
334    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
335
336    // The minimum sample duration we will allow before deciding we have
337    // enough data on CPU usage to start killing things.
338    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
339
340    // How long we allow a receiver to run before giving up on it.
341    static final int BROADCAST_FG_TIMEOUT = 10*1000;
342    static final int BROADCAST_BG_TIMEOUT = 60*1000;
343
344    // How long we wait until we timeout on key dispatching.
345    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
346
347    // How long we wait until we timeout on key dispatching during instrumentation.
348    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
349
350    // Amount of time we wait for observers to handle a user switch before
351    // giving up on them and unfreezing the screen.
352    static final int USER_SWITCH_TIMEOUT = 2*1000;
353
354    // Maximum number of users we allow to be running at a time.
355    static final int MAX_RUNNING_USERS = 3;
356
357    // How long to wait in getAssistContextExtras for the activity and foreground services
358    // to respond with the result.
359    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
360
361    // Maximum number of persisted Uri grants a package is allowed
362    static final int MAX_PERSISTED_URI_GRANTS = 128;
363
364    static final int MY_PID = Process.myPid();
365
366    static final String[] EMPTY_STRING_ARRAY = new String[0];
367
368    // How many bytes to write into the dropbox log before truncating
369    static final int DROPBOX_MAX_SIZE = 256 * 1024;
370
371    // Access modes for handleIncomingUser.
372    static final int ALLOW_NON_FULL = 0;
373    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
374    static final int ALLOW_FULL_ONLY = 2;
375
376    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
377
378    // Delay in notifying task stack change listeners (in millis)
379    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
380
381    // Necessary ApplicationInfo flags to mark an app as persistent
382    private static final int PERSISTENT_MASK =
383            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
384
385    /** All system services */
386    SystemServiceManager mSystemServiceManager;
387
388    private Installer mInstaller;
389
390    /** Run all ActivityStacks through this */
391    ActivityStackSupervisor mStackSupervisor;
392
393    /** Task stack change listeners. */
394    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
395            new RemoteCallbackList<ITaskStackListener>();
396
397    public IntentFirewall mIntentFirewall;
398
399    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
400    // default actuion automatically.  Important for devices without direct input
401    // devices.
402    private boolean mShowDialogs = true;
403
404    BroadcastQueue mFgBroadcastQueue;
405    BroadcastQueue mBgBroadcastQueue;
406    // Convenient for easy iteration over the queues. Foreground is first
407    // so that dispatch of foreground broadcasts gets precedence.
408    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
409
410    BroadcastQueue broadcastQueueForIntent(Intent intent) {
411        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
412        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
413                "Broadcast intent " + intent + " on "
414                + (isFg ? "foreground" : "background") + " queue");
415        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
416    }
417
418    /**
419     * Activity we have told the window manager to have key focus.
420     */
421    ActivityRecord mFocusedActivity = null;
422
423    /**
424     * User id of the last activity mFocusedActivity was set to.
425     */
426    private int mLastFocusedUserId;
427
428    /**
429     * If non-null, we are tracking the time the user spends in the currently focused app.
430     */
431    private AppTimeTracker mCurAppTimeTracker;
432
433    /**
434     * List of intents that were used to start the most recent tasks.
435     */
436    private final RecentTasks mRecentTasks;
437
438    /**
439     * For addAppTask: cached of the last activity component that was added.
440     */
441    ComponentName mLastAddedTaskComponent;
442
443    /**
444     * For addAppTask: cached of the last activity uid that was added.
445     */
446    int mLastAddedTaskUid;
447
448    /**
449     * For addAppTask: cached of the last ActivityInfo that was added.
450     */
451    ActivityInfo mLastAddedTaskActivity;
452
453    /**
454     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
455     */
456    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
457
458    /**
459     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
460     */
461    String mDeviceOwnerName;
462
463    /**
464     * Preferred activities to start on boot/user switch, as set by DevicePolicyManager. Indexed
465     * by userId.
466     */
467    SparseArray<ComponentName> mPreferredSetupActivities = new SparseArray<>();
468
469    public class PendingAssistExtras extends Binder implements Runnable {
470        public final ActivityRecord activity;
471        public final Bundle extras;
472        public final Intent intent;
473        public final String hint;
474        public final IResultReceiver receiver;
475        public final int userHandle;
476        public boolean haveResult = false;
477        public Bundle result = null;
478        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
479                String _hint, IResultReceiver _receiver, int _userHandle) {
480            activity = _activity;
481            extras = _extras;
482            intent = _intent;
483            hint = _hint;
484            receiver = _receiver;
485            userHandle = _userHandle;
486        }
487        @Override
488        public void run() {
489            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
490            synchronized (ActivityManagerService.this) {
491                synchronized (this) {
492                    haveResult = true;
493                    notifyAll();
494                }
495                pendingAssistExtrasTimedOutLocked(this);
496            }
497        }
498    }
499
500    final ArrayList<PendingAssistExtras> mPendingAssistExtras
501            = new ArrayList<PendingAssistExtras>();
502
503    /**
504     * Process management.
505     */
506    final ProcessList mProcessList = new ProcessList();
507
508    /**
509     * All of the applications we currently have running organized by name.
510     * The keys are strings of the application package name (as
511     * returned by the package manager), and the keys are ApplicationRecord
512     * objects.
513     */
514    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
515
516    /**
517     * Tracking long-term execution of processes to look for abuse and other
518     * bad app behavior.
519     */
520    final ProcessStatsService mProcessStats;
521
522    /**
523     * The currently running isolated processes.
524     */
525    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
526
527    /**
528     * Counter for assigning isolated process uids, to avoid frequently reusing the
529     * same ones.
530     */
531    int mNextIsolatedProcessUid = 0;
532
533    /**
534     * The currently running heavy-weight process, if any.
535     */
536    ProcessRecord mHeavyWeightProcess = null;
537
538    /**
539     * The last time that various processes have crashed.
540     */
541    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
542
543    /**
544     * Information about a process that is currently marked as bad.
545     */
546    static final class BadProcessInfo {
547        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
548            this.time = time;
549            this.shortMsg = shortMsg;
550            this.longMsg = longMsg;
551            this.stack = stack;
552        }
553
554        final long time;
555        final String shortMsg;
556        final String longMsg;
557        final String stack;
558    }
559
560    /**
561     * Set of applications that we consider to be bad, and will reject
562     * incoming broadcasts from (which the user has no control over).
563     * Processes are added to this set when they have crashed twice within
564     * a minimum amount of time; they are removed from it when they are
565     * later restarted (hopefully due to some user action).  The value is the
566     * time it was added to the list.
567     */
568    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
569
570    /**
571     * All of the processes we currently have running organized by pid.
572     * The keys are the pid running the application.
573     *
574     * <p>NOTE: This object is protected by its own lock, NOT the global
575     * activity manager lock!
576     */
577    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
578
579    /**
580     * All of the processes that have been forced to be foreground.  The key
581     * is the pid of the caller who requested it (we hold a death
582     * link on it).
583     */
584    abstract class ForegroundToken implements IBinder.DeathRecipient {
585        int pid;
586        IBinder token;
587    }
588    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
589
590    /**
591     * List of records for processes that someone had tried to start before the
592     * system was ready.  We don't start them at that point, but ensure they
593     * are started by the time booting is complete.
594     */
595    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
596
597    /**
598     * List of persistent applications that are in the process
599     * of being started.
600     */
601    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
602
603    /**
604     * Processes that are being forcibly torn down.
605     */
606    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
607
608    /**
609     * List of running applications, sorted by recent usage.
610     * The first entry in the list is the least recently used.
611     */
612    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
613
614    /**
615     * Where in mLruProcesses that the processes hosting activities start.
616     */
617    int mLruProcessActivityStart = 0;
618
619    /**
620     * Where in mLruProcesses that the processes hosting services start.
621     * This is after (lower index) than mLruProcessesActivityStart.
622     */
623    int mLruProcessServiceStart = 0;
624
625    /**
626     * List of processes that should gc as soon as things are idle.
627     */
628    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
629
630    /**
631     * Processes we want to collect PSS data from.
632     */
633    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
634
635    /**
636     * Last time we requested PSS data of all processes.
637     */
638    long mLastFullPssTime = SystemClock.uptimeMillis();
639
640    /**
641     * If set, the next time we collect PSS data we should do a full collection
642     * with data from native processes and the kernel.
643     */
644    boolean mFullPssPending = false;
645
646    /**
647     * This is the process holding what we currently consider to be
648     * the "home" activity.
649     */
650    ProcessRecord mHomeProcess;
651
652    /**
653     * This is the process holding the activity the user last visited that
654     * is in a different process from the one they are currently in.
655     */
656    ProcessRecord mPreviousProcess;
657
658    /**
659     * The time at which the previous process was last visible.
660     */
661    long mPreviousProcessVisibleTime;
662
663    /**
664     * Track all uids that have actively running processes.
665     */
666    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
667
668    /**
669     * Which uses have been started, so are allowed to run code.
670     */
671    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<>();
672
673    /**
674     * LRU list of history of current users.  Most recently current is at the end.
675     */
676    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
677
678    /**
679     * Constant array of the users that are currently started.
680     */
681    int[] mStartedUserArray = new int[] { 0 };
682
683    /**
684     * Registered observers of the user switching mechanics.
685     */
686    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
687            = new RemoteCallbackList<IUserSwitchObserver>();
688
689    /**
690     * Currently active user switch.
691     */
692    Object mCurUserSwitchCallback;
693
694    /**
695     * Packages that the user has asked to have run in screen size
696     * compatibility mode instead of filling the screen.
697     */
698    final CompatModePackages mCompatModePackages;
699
700    /**
701     * Set of IntentSenderRecord objects that are currently active.
702     */
703    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
704            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
705
706    /**
707     * Fingerprints (hashCode()) of stack traces that we've
708     * already logged DropBox entries for.  Guarded by itself.  If
709     * something (rogue user app) forces this over
710     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
711     */
712    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
713    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
714
715    /**
716     * Strict Mode background batched logging state.
717     *
718     * The string buffer is guarded by itself, and its lock is also
719     * used to determine if another batched write is already
720     * in-flight.
721     */
722    private final StringBuilder mStrictModeBuffer = new StringBuilder();
723
724    /**
725     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
726     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
727     */
728    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
729
730    /**
731     * Resolver for broadcast intents to registered receivers.
732     * Holds BroadcastFilter (subclass of IntentFilter).
733     */
734    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
735            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
736        @Override
737        protected boolean allowFilterResult(
738                BroadcastFilter filter, List<BroadcastFilter> dest) {
739            IBinder target = filter.receiverList.receiver.asBinder();
740            for (int i = dest.size() - 1; i >= 0; i--) {
741                if (dest.get(i).receiverList.receiver.asBinder() == target) {
742                    return false;
743                }
744            }
745            return true;
746        }
747
748        @Override
749        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
750            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
751                    || userId == filter.owningUserId) {
752                return super.newResult(filter, match, userId);
753            }
754            return null;
755        }
756
757        @Override
758        protected BroadcastFilter[] newArray(int size) {
759            return new BroadcastFilter[size];
760        }
761
762        @Override
763        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
764            return packageName.equals(filter.packageName);
765        }
766    };
767
768    /**
769     * State of all active sticky broadcasts per user.  Keys are the action of the
770     * sticky Intent, values are an ArrayList of all broadcasted intents with
771     * that action (which should usually be one).  The SparseArray is keyed
772     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
773     * for stickies that are sent to all users.
774     */
775    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
776            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
777
778    final ActiveServices mServices;
779
780    final static class Association {
781        final int mSourceUid;
782        final String mSourceProcess;
783        final int mTargetUid;
784        final ComponentName mTargetComponent;
785        final String mTargetProcess;
786
787        int mCount;
788        long mTime;
789
790        int mNesting;
791        long mStartTime;
792
793        Association(int sourceUid, String sourceProcess, int targetUid,
794                ComponentName targetComponent, String targetProcess) {
795            mSourceUid = sourceUid;
796            mSourceProcess = sourceProcess;
797            mTargetUid = targetUid;
798            mTargetComponent = targetComponent;
799            mTargetProcess = targetProcess;
800        }
801    }
802
803    /**
804     * When service association tracking is enabled, this is all of the associations we
805     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
806     * -> association data.
807     */
808    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
809            mAssociations = new SparseArray<>();
810    boolean mTrackingAssociations;
811
812    /**
813     * Backup/restore process management
814     */
815    String mBackupAppName = null;
816    BackupRecord mBackupTarget = null;
817
818    final ProviderMap mProviderMap;
819
820    /**
821     * List of content providers who have clients waiting for them.  The
822     * application is currently being launched and the provider will be
823     * removed from this list once it is published.
824     */
825    final ArrayList<ContentProviderRecord> mLaunchingProviders
826            = new ArrayList<ContentProviderRecord>();
827
828    /**
829     * File storing persisted {@link #mGrantedUriPermissions}.
830     */
831    private final AtomicFile mGrantFile;
832
833    /** XML constants used in {@link #mGrantFile} */
834    private static final String TAG_URI_GRANTS = "uri-grants";
835    private static final String TAG_URI_GRANT = "uri-grant";
836    private static final String ATTR_USER_HANDLE = "userHandle";
837    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
838    private static final String ATTR_TARGET_USER_ID = "targetUserId";
839    private static final String ATTR_SOURCE_PKG = "sourcePkg";
840    private static final String ATTR_TARGET_PKG = "targetPkg";
841    private static final String ATTR_URI = "uri";
842    private static final String ATTR_MODE_FLAGS = "modeFlags";
843    private static final String ATTR_CREATED_TIME = "createdTime";
844    private static final String ATTR_PREFIX = "prefix";
845
846    /**
847     * Global set of specific {@link Uri} permissions that have been granted.
848     * This optimized lookup structure maps from {@link UriPermission#targetUid}
849     * to {@link UriPermission#uri} to {@link UriPermission}.
850     */
851    @GuardedBy("this")
852    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
853            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
854
855    public static class GrantUri {
856        public final int sourceUserId;
857        public final Uri uri;
858        public boolean prefix;
859
860        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
861            this.sourceUserId = sourceUserId;
862            this.uri = uri;
863            this.prefix = prefix;
864        }
865
866        @Override
867        public int hashCode() {
868            int hashCode = 1;
869            hashCode = 31 * hashCode + sourceUserId;
870            hashCode = 31 * hashCode + uri.hashCode();
871            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
872            return hashCode;
873        }
874
875        @Override
876        public boolean equals(Object o) {
877            if (o instanceof GrantUri) {
878                GrantUri other = (GrantUri) o;
879                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
880                        && prefix == other.prefix;
881            }
882            return false;
883        }
884
885        @Override
886        public String toString() {
887            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
888            if (prefix) result += " [prefix]";
889            return result;
890        }
891
892        public String toSafeString() {
893            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
894            if (prefix) result += " [prefix]";
895            return result;
896        }
897
898        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
899            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
900                    ContentProvider.getUriWithoutUserId(uri), false);
901        }
902    }
903
904    CoreSettingsObserver mCoreSettingsObserver;
905
906    /**
907     * Thread-local storage used to carry caller permissions over through
908     * indirect content-provider access.
909     */
910    private class Identity {
911        public final IBinder token;
912        public final int pid;
913        public final int uid;
914
915        Identity(IBinder _token, int _pid, int _uid) {
916            token = _token;
917            pid = _pid;
918            uid = _uid;
919        }
920    }
921
922    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
923
924    /**
925     * All information we have collected about the runtime performance of
926     * any user id that can impact battery performance.
927     */
928    final BatteryStatsService mBatteryStatsService;
929
930    /**
931     * Information about component usage
932     */
933    UsageStatsManagerInternal mUsageStatsService;
934
935    /**
936     * Information about and control over application operations
937     */
938    final AppOpsService mAppOpsService;
939
940    /**
941     * Save recent tasks information across reboots.
942     */
943    final TaskPersister mTaskPersister;
944
945    /**
946     * Current configuration information.  HistoryRecord objects are given
947     * a reference to this object to indicate which configuration they are
948     * currently running in, so this object must be kept immutable.
949     */
950    Configuration mConfiguration = new Configuration();
951
952    /**
953     * Current sequencing integer of the configuration, for skipping old
954     * configurations.
955     */
956    int mConfigurationSeq = 0;
957
958    /**
959     * Hardware-reported OpenGLES version.
960     */
961    final int GL_ES_VERSION;
962
963    /**
964     * List of initialization arguments to pass to all processes when binding applications to them.
965     * For example, references to the commonly used services.
966     */
967    HashMap<String, IBinder> mAppBindArgs;
968
969    /**
970     * Temporary to avoid allocations.  Protected by main lock.
971     */
972    final StringBuilder mStringBuilder = new StringBuilder(256);
973
974    /**
975     * Used to control how we initialize the service.
976     */
977    ComponentName mTopComponent;
978    String mTopAction = Intent.ACTION_MAIN;
979    String mTopData;
980    boolean mProcessesReady = false;
981    boolean mSystemReady = false;
982    boolean mBooting = false;
983    boolean mCallFinishBooting = false;
984    boolean mBootAnimationComplete = false;
985    boolean mWaitingUpdate = false;
986    boolean mDidUpdate = false;
987    boolean mOnBattery = false;
988    boolean mLaunchWarningShown = false;
989
990    Context mContext;
991
992    int mFactoryTest;
993
994    boolean mCheckedForSetup;
995
996    /**
997     * The time at which we will allow normal application switches again,
998     * after a call to {@link #stopAppSwitches()}.
999     */
1000    long mAppSwitchesAllowedTime;
1001
1002    /**
1003     * This is set to true after the first switch after mAppSwitchesAllowedTime
1004     * is set; any switches after that will clear the time.
1005     */
1006    boolean mDidAppSwitch;
1007
1008    /**
1009     * Last time (in realtime) at which we checked for power usage.
1010     */
1011    long mLastPowerCheckRealtime;
1012
1013    /**
1014     * Last time (in uptime) at which we checked for power usage.
1015     */
1016    long mLastPowerCheckUptime;
1017
1018    /**
1019     * Set while we are wanting to sleep, to prevent any
1020     * activities from being started/resumed.
1021     */
1022    private boolean mSleeping = false;
1023
1024    /**
1025     * The process state used for processes that are running the top activities.
1026     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1027     */
1028    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1029
1030    /**
1031     * Set while we are running a voice interaction.  This overrides
1032     * sleeping while it is active.
1033     */
1034    private IVoiceInteractionSession mRunningVoice;
1035
1036    /**
1037     * For some direct access we need to power manager.
1038     */
1039    PowerManagerInternal mLocalPowerManager;
1040
1041    /**
1042     * We want to hold a wake lock while running a voice interaction session, since
1043     * this may happen with the screen off and we need to keep the CPU running to
1044     * be able to continue to interact with the user.
1045     */
1046    PowerManager.WakeLock mVoiceWakeLock;
1047
1048    /**
1049     * State of external calls telling us if the device is awake or asleep.
1050     */
1051    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1052
1053    /**
1054     * A list of tokens that cause the top activity to be put to sleep.
1055     * They are used by components that may hide and block interaction with underlying
1056     * activities.
1057     */
1058    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1059
1060    static final int LOCK_SCREEN_HIDDEN = 0;
1061    static final int LOCK_SCREEN_LEAVING = 1;
1062    static final int LOCK_SCREEN_SHOWN = 2;
1063    /**
1064     * State of external call telling us if the lock screen is shown.
1065     */
1066    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1067
1068    /**
1069     * Set if we are shutting down the system, similar to sleeping.
1070     */
1071    boolean mShuttingDown = false;
1072
1073    /**
1074     * Current sequence id for oom_adj computation traversal.
1075     */
1076    int mAdjSeq = 0;
1077
1078    /**
1079     * Current sequence id for process LRU updating.
1080     */
1081    int mLruSeq = 0;
1082
1083    /**
1084     * Keep track of the non-cached/empty process we last found, to help
1085     * determine how to distribute cached/empty processes next time.
1086     */
1087    int mNumNonCachedProcs = 0;
1088
1089    /**
1090     * Keep track of the number of cached hidden procs, to balance oom adj
1091     * distribution between those and empty procs.
1092     */
1093    int mNumCachedHiddenProcs = 0;
1094
1095    /**
1096     * Keep track of the number of service processes we last found, to
1097     * determine on the next iteration which should be B services.
1098     */
1099    int mNumServiceProcs = 0;
1100    int mNewNumAServiceProcs = 0;
1101    int mNewNumServiceProcs = 0;
1102
1103    /**
1104     * Allow the current computed overall memory level of the system to go down?
1105     * This is set to false when we are killing processes for reasons other than
1106     * memory management, so that the now smaller process list will not be taken as
1107     * an indication that memory is tighter.
1108     */
1109    boolean mAllowLowerMemLevel = false;
1110
1111    /**
1112     * The last computed memory level, for holding when we are in a state that
1113     * processes are going away for other reasons.
1114     */
1115    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1116
1117    /**
1118     * The last total number of process we have, to determine if changes actually look
1119     * like a shrinking number of process due to lower RAM.
1120     */
1121    int mLastNumProcesses;
1122
1123    /**
1124     * The uptime of the last time we performed idle maintenance.
1125     */
1126    long mLastIdleTime = SystemClock.uptimeMillis();
1127
1128    /**
1129     * Total time spent with RAM that has been added in the past since the last idle time.
1130     */
1131    long mLowRamTimeSinceLastIdle = 0;
1132
1133    /**
1134     * If RAM is currently low, when that horrible situation started.
1135     */
1136    long mLowRamStartTime = 0;
1137
1138    /**
1139     * For reporting to battery stats the current top application.
1140     */
1141    private String mCurResumedPackage = null;
1142    private int mCurResumedUid = -1;
1143
1144    /**
1145     * For reporting to battery stats the apps currently running foreground
1146     * service.  The ProcessMap is package/uid tuples; each of these contain
1147     * an array of the currently foreground processes.
1148     */
1149    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1150            = new ProcessMap<ArrayList<ProcessRecord>>();
1151
1152    /**
1153     * This is set if we had to do a delayed dexopt of an app before launching
1154     * it, to increase the ANR timeouts in that case.
1155     */
1156    boolean mDidDexOpt;
1157
1158    /**
1159     * Set if the systemServer made a call to enterSafeMode.
1160     */
1161    boolean mSafeMode;
1162
1163    /**
1164     * If true, we are running under a test environment so will sample PSS from processes
1165     * much more rapidly to try to collect better data when the tests are rapidly
1166     * running through apps.
1167     */
1168    boolean mTestPssMode = false;
1169
1170    String mDebugApp = null;
1171    boolean mWaitForDebugger = false;
1172    boolean mDebugTransient = false;
1173    String mOrigDebugApp = null;
1174    boolean mOrigWaitForDebugger = false;
1175    boolean mAlwaysFinishActivities = false;
1176    IActivityController mController = null;
1177    String mProfileApp = null;
1178    ProcessRecord mProfileProc = null;
1179    String mProfileFile;
1180    ParcelFileDescriptor mProfileFd;
1181    int mSamplingInterval = 0;
1182    boolean mAutoStopProfiler = false;
1183    int mProfileType = 0;
1184    String mOpenGlTraceApp = null;
1185    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1186    String mMemWatchDumpProcName;
1187    String mMemWatchDumpFile;
1188    int mMemWatchDumpPid;
1189    int mMemWatchDumpUid;
1190
1191    final long[] mTmpLong = new long[1];
1192
1193    static final class ProcessChangeItem {
1194        static final int CHANGE_ACTIVITIES = 1<<0;
1195        static final int CHANGE_PROCESS_STATE = 1<<1;
1196        int changes;
1197        int uid;
1198        int pid;
1199        int processState;
1200        boolean foregroundActivities;
1201    }
1202
1203    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1204    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1205
1206    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1207    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1208
1209    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1210    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1211
1212    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1213    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1214
1215    /**
1216     * Runtime CPU use collection thread.  This object's lock is used to
1217     * perform synchronization with the thread (notifying it to run).
1218     */
1219    final Thread mProcessCpuThread;
1220
1221    /**
1222     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1223     * Must acquire this object's lock when accessing it.
1224     * NOTE: this lock will be held while doing long operations (trawling
1225     * through all processes in /proc), so it should never be acquired by
1226     * any critical paths such as when holding the main activity manager lock.
1227     */
1228    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1229            MONITOR_THREAD_CPU_USAGE);
1230    final AtomicLong mLastCpuTime = new AtomicLong(0);
1231    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1232
1233    long mLastWriteTime = 0;
1234
1235    /**
1236     * Used to retain an update lock when the foreground activity is in
1237     * immersive mode.
1238     */
1239    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1240
1241    /**
1242     * Set to true after the system has finished booting.
1243     */
1244    boolean mBooted = false;
1245
1246    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1247    int mProcessLimitOverride = -1;
1248
1249    WindowManagerService mWindowManager;
1250
1251    final ActivityThread mSystemThread;
1252
1253    // Holds the current foreground user's id
1254    int mCurrentUserId = 0;
1255    // Holds the target user's id during a user switch
1256    int mTargetUserId = UserHandle.USER_NULL;
1257    // If there are multiple profiles for the current user, their ids are here
1258    // Currently only the primary user can have managed profiles
1259    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1260
1261    /**
1262     * Mapping from each known user ID to the profile group ID it is associated with.
1263     */
1264    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1265
1266    private UserManagerService mUserManager;
1267
1268    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1269        final ProcessRecord mApp;
1270        final int mPid;
1271        final IApplicationThread mAppThread;
1272
1273        AppDeathRecipient(ProcessRecord app, int pid,
1274                IApplicationThread thread) {
1275            if (DEBUG_ALL) Slog.v(
1276                TAG, "New death recipient " + this
1277                + " for thread " + thread.asBinder());
1278            mApp = app;
1279            mPid = pid;
1280            mAppThread = thread;
1281        }
1282
1283        @Override
1284        public void binderDied() {
1285            if (DEBUG_ALL) Slog.v(
1286                TAG, "Death received in " + this
1287                + " for thread " + mAppThread.asBinder());
1288            synchronized(ActivityManagerService.this) {
1289                appDiedLocked(mApp, mPid, mAppThread, true);
1290            }
1291        }
1292    }
1293
1294    static final int SHOW_ERROR_MSG = 1;
1295    static final int SHOW_NOT_RESPONDING_MSG = 2;
1296    static final int SHOW_FACTORY_ERROR_MSG = 3;
1297    static final int UPDATE_CONFIGURATION_MSG = 4;
1298    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1299    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1300    static final int SERVICE_TIMEOUT_MSG = 12;
1301    static final int UPDATE_TIME_ZONE = 13;
1302    static final int SHOW_UID_ERROR_MSG = 14;
1303    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1304    static final int PROC_START_TIMEOUT_MSG = 20;
1305    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1306    static final int KILL_APPLICATION_MSG = 22;
1307    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1308    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1309    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1310    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1311    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1312    static final int CLEAR_DNS_CACHE_MSG = 28;
1313    static final int UPDATE_HTTP_PROXY_MSG = 29;
1314    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1315    static final int DISPATCH_PROCESSES_CHANGED = 31;
1316    static final int DISPATCH_PROCESS_DIED = 32;
1317    static final int REPORT_MEM_USAGE_MSG = 33;
1318    static final int REPORT_USER_SWITCH_MSG = 34;
1319    static final int CONTINUE_USER_SWITCH_MSG = 35;
1320    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1321    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1322    static final int PERSIST_URI_GRANTS_MSG = 38;
1323    static final int REQUEST_ALL_PSS_MSG = 39;
1324    static final int START_PROFILES_MSG = 40;
1325    static final int UPDATE_TIME = 41;
1326    static final int SYSTEM_USER_START_MSG = 42;
1327    static final int SYSTEM_USER_CURRENT_MSG = 43;
1328    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1329    static final int FINISH_BOOTING_MSG = 45;
1330    static final int START_USER_SWITCH_MSG = 46;
1331    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1332    static final int DISMISS_DIALOG_MSG = 48;
1333    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1334    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1335    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1336    static final int DELETE_DUMPHEAP_MSG = 52;
1337    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1338    static final int DISPATCH_UIDS_CHANGED_MSG = 54;
1339    static final int REPORT_TIME_TRACKER_MSG = 55;
1340
1341    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1342    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1343    static final int FIRST_COMPAT_MODE_MSG = 300;
1344    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1345
1346    CompatModeDialog mCompatModeDialog;
1347    long mLastMemUsageReportTime = 0;
1348
1349    /**
1350     * Flag whether the current user is a "monkey", i.e. whether
1351     * the UI is driven by a UI automation tool.
1352     */
1353    private boolean mUserIsMonkey;
1354
1355    /** Flag whether the device has a Recents UI */
1356    boolean mHasRecents;
1357
1358    /** The dimensions of the thumbnails in the Recents UI. */
1359    int mThumbnailWidth;
1360    int mThumbnailHeight;
1361
1362    final ServiceThread mHandlerThread;
1363    final MainHandler mHandler;
1364    final UiHandler mUiHandler;
1365
1366    final class UiHandler extends Handler {
1367        public UiHandler() {
1368            super(com.android.server.UiThread.get().getLooper(), null, true);
1369        }
1370
1371        @Override
1372        public void handleMessage(Message msg) {
1373            switch (msg.what) {
1374            case SHOW_ERROR_MSG: {
1375                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1376                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1377                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1378                synchronized (ActivityManagerService.this) {
1379                    ProcessRecord proc = (ProcessRecord)data.get("app");
1380                    AppErrorResult res = (AppErrorResult) data.get("result");
1381                    if (proc != null && proc.crashDialog != null) {
1382                        Slog.e(TAG, "App already has crash dialog: " + proc);
1383                        if (res != null) {
1384                            res.set(0);
1385                        }
1386                        return;
1387                    }
1388                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1389                            >= Process.FIRST_APPLICATION_UID
1390                            && proc.pid != MY_PID);
1391                    for (int userId : mCurrentProfileIds) {
1392                        isBackground &= (proc.userId != userId);
1393                    }
1394                    if (isBackground && !showBackground) {
1395                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1396                        if (res != null) {
1397                            res.set(0);
1398                        }
1399                        return;
1400                    }
1401                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1402                        Dialog d = new AppErrorDialog(mContext,
1403                                ActivityManagerService.this, res, proc);
1404                        d.show();
1405                        proc.crashDialog = d;
1406                    } else {
1407                        // The device is asleep, so just pretend that the user
1408                        // saw a crash dialog and hit "force quit".
1409                        if (res != null) {
1410                            res.set(0);
1411                        }
1412                    }
1413                }
1414
1415                ensureBootCompleted();
1416            } break;
1417            case SHOW_NOT_RESPONDING_MSG: {
1418                synchronized (ActivityManagerService.this) {
1419                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1420                    ProcessRecord proc = (ProcessRecord)data.get("app");
1421                    if (proc != null && proc.anrDialog != null) {
1422                        Slog.e(TAG, "App already has anr dialog: " + proc);
1423                        return;
1424                    }
1425
1426                    Intent intent = new Intent("android.intent.action.ANR");
1427                    if (!mProcessesReady) {
1428                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1429                                | Intent.FLAG_RECEIVER_FOREGROUND);
1430                    }
1431                    broadcastIntentLocked(null, null, intent,
1432                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1433                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1434
1435                    if (mShowDialogs) {
1436                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1437                                mContext, proc, (ActivityRecord)data.get("activity"),
1438                                msg.arg1 != 0);
1439                        d.show();
1440                        proc.anrDialog = d;
1441                    } else {
1442                        // Just kill the app if there is no dialog to be shown.
1443                        killAppAtUsersRequest(proc, null);
1444                    }
1445                }
1446
1447                ensureBootCompleted();
1448            } break;
1449            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1450                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1451                synchronized (ActivityManagerService.this) {
1452                    ProcessRecord proc = (ProcessRecord) data.get("app");
1453                    if (proc == null) {
1454                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1455                        break;
1456                    }
1457                    if (proc.crashDialog != null) {
1458                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1459                        return;
1460                    }
1461                    AppErrorResult res = (AppErrorResult) data.get("result");
1462                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1463                        Dialog d = new StrictModeViolationDialog(mContext,
1464                                ActivityManagerService.this, res, proc);
1465                        d.show();
1466                        proc.crashDialog = d;
1467                    } else {
1468                        // The device is asleep, so just pretend that the user
1469                        // saw a crash dialog and hit "force quit".
1470                        res.set(0);
1471                    }
1472                }
1473                ensureBootCompleted();
1474            } break;
1475            case SHOW_FACTORY_ERROR_MSG: {
1476                Dialog d = new FactoryErrorDialog(
1477                    mContext, msg.getData().getCharSequence("msg"));
1478                d.show();
1479                ensureBootCompleted();
1480            } break;
1481            case WAIT_FOR_DEBUGGER_MSG: {
1482                synchronized (ActivityManagerService.this) {
1483                    ProcessRecord app = (ProcessRecord)msg.obj;
1484                    if (msg.arg1 != 0) {
1485                        if (!app.waitedForDebugger) {
1486                            Dialog d = new AppWaitingForDebuggerDialog(
1487                                    ActivityManagerService.this,
1488                                    mContext, app);
1489                            app.waitDialog = d;
1490                            app.waitedForDebugger = true;
1491                            d.show();
1492                        }
1493                    } else {
1494                        if (app.waitDialog != null) {
1495                            app.waitDialog.dismiss();
1496                            app.waitDialog = null;
1497                        }
1498                    }
1499                }
1500            } break;
1501            case SHOW_UID_ERROR_MSG: {
1502                if (mShowDialogs) {
1503                    AlertDialog d = new BaseErrorDialog(mContext);
1504                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1505                    d.setCancelable(false);
1506                    d.setTitle(mContext.getText(R.string.android_system_label));
1507                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1508                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1509                            obtainMessage(DISMISS_DIALOG_MSG, d));
1510                    d.show();
1511                }
1512            } break;
1513            case SHOW_FINGERPRINT_ERROR_MSG: {
1514                if (mShowDialogs) {
1515                    AlertDialog d = new BaseErrorDialog(mContext);
1516                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1517                    d.setCancelable(false);
1518                    d.setTitle(mContext.getText(R.string.android_system_label));
1519                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1520                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1521                            obtainMessage(DISMISS_DIALOG_MSG, d));
1522                    d.show();
1523                }
1524            } break;
1525            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1526                synchronized (ActivityManagerService.this) {
1527                    ActivityRecord ar = (ActivityRecord) msg.obj;
1528                    if (mCompatModeDialog != null) {
1529                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1530                                ar.info.applicationInfo.packageName)) {
1531                            return;
1532                        }
1533                        mCompatModeDialog.dismiss();
1534                        mCompatModeDialog = null;
1535                    }
1536                    if (ar != null && false) {
1537                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1538                                ar.packageName)) {
1539                            int mode = mCompatModePackages.computeCompatModeLocked(
1540                                    ar.info.applicationInfo);
1541                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1542                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1543                                mCompatModeDialog = new CompatModeDialog(
1544                                        ActivityManagerService.this, mContext,
1545                                        ar.info.applicationInfo);
1546                                mCompatModeDialog.show();
1547                            }
1548                        }
1549                    }
1550                }
1551                break;
1552            }
1553            case START_USER_SWITCH_MSG: {
1554                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1555                break;
1556            }
1557            case DISMISS_DIALOG_MSG: {
1558                final Dialog d = (Dialog) msg.obj;
1559                d.dismiss();
1560                break;
1561            }
1562            case DISPATCH_PROCESSES_CHANGED: {
1563                dispatchProcessesChanged();
1564                break;
1565            }
1566            case DISPATCH_PROCESS_DIED: {
1567                final int pid = msg.arg1;
1568                final int uid = msg.arg2;
1569                dispatchProcessDied(pid, uid);
1570                break;
1571            }
1572            case DISPATCH_UIDS_CHANGED_MSG: {
1573                dispatchUidsChanged();
1574            } break;
1575            }
1576        }
1577    }
1578
1579    final class MainHandler extends Handler {
1580        public MainHandler(Looper looper) {
1581            super(looper, null, true);
1582        }
1583
1584        @Override
1585        public void handleMessage(Message msg) {
1586            switch (msg.what) {
1587            case UPDATE_CONFIGURATION_MSG: {
1588                final ContentResolver resolver = mContext.getContentResolver();
1589                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1590                        msg.arg1);
1591            } break;
1592            case GC_BACKGROUND_PROCESSES_MSG: {
1593                synchronized (ActivityManagerService.this) {
1594                    performAppGcsIfAppropriateLocked();
1595                }
1596            } break;
1597            case SERVICE_TIMEOUT_MSG: {
1598                if (mDidDexOpt) {
1599                    mDidDexOpt = false;
1600                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1601                    nmsg.obj = msg.obj;
1602                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1603                    return;
1604                }
1605                mServices.serviceTimeout((ProcessRecord)msg.obj);
1606            } break;
1607            case UPDATE_TIME_ZONE: {
1608                synchronized (ActivityManagerService.this) {
1609                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1610                        ProcessRecord r = mLruProcesses.get(i);
1611                        if (r.thread != null) {
1612                            try {
1613                                r.thread.updateTimeZone();
1614                            } catch (RemoteException ex) {
1615                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1616                            }
1617                        }
1618                    }
1619                }
1620            } break;
1621            case CLEAR_DNS_CACHE_MSG: {
1622                synchronized (ActivityManagerService.this) {
1623                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1624                        ProcessRecord r = mLruProcesses.get(i);
1625                        if (r.thread != null) {
1626                            try {
1627                                r.thread.clearDnsCache();
1628                            } catch (RemoteException ex) {
1629                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1630                            }
1631                        }
1632                    }
1633                }
1634            } break;
1635            case UPDATE_HTTP_PROXY_MSG: {
1636                ProxyInfo proxy = (ProxyInfo)msg.obj;
1637                String host = "";
1638                String port = "";
1639                String exclList = "";
1640                Uri pacFileUrl = Uri.EMPTY;
1641                if (proxy != null) {
1642                    host = proxy.getHost();
1643                    port = Integer.toString(proxy.getPort());
1644                    exclList = proxy.getExclusionListAsString();
1645                    pacFileUrl = proxy.getPacFileUrl();
1646                }
1647                synchronized (ActivityManagerService.this) {
1648                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1649                        ProcessRecord r = mLruProcesses.get(i);
1650                        if (r.thread != null) {
1651                            try {
1652                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1653                            } catch (RemoteException ex) {
1654                                Slog.w(TAG, "Failed to update http proxy for: " +
1655                                        r.info.processName);
1656                            }
1657                        }
1658                    }
1659                }
1660            } break;
1661            case PROC_START_TIMEOUT_MSG: {
1662                if (mDidDexOpt) {
1663                    mDidDexOpt = false;
1664                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1665                    nmsg.obj = msg.obj;
1666                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1667                    return;
1668                }
1669                ProcessRecord app = (ProcessRecord)msg.obj;
1670                synchronized (ActivityManagerService.this) {
1671                    processStartTimedOutLocked(app);
1672                }
1673            } break;
1674            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1675                synchronized (ActivityManagerService.this) {
1676                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1677                }
1678            } break;
1679            case KILL_APPLICATION_MSG: {
1680                synchronized (ActivityManagerService.this) {
1681                    int appid = msg.arg1;
1682                    boolean restart = (msg.arg2 == 1);
1683                    Bundle bundle = (Bundle)msg.obj;
1684                    String pkg = bundle.getString("pkg");
1685                    String reason = bundle.getString("reason");
1686                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1687                            false, UserHandle.USER_ALL, reason);
1688                }
1689            } break;
1690            case FINALIZE_PENDING_INTENT_MSG: {
1691                ((PendingIntentRecord)msg.obj).completeFinalize();
1692            } break;
1693            case POST_HEAVY_NOTIFICATION_MSG: {
1694                INotificationManager inm = NotificationManager.getService();
1695                if (inm == null) {
1696                    return;
1697                }
1698
1699                ActivityRecord root = (ActivityRecord)msg.obj;
1700                ProcessRecord process = root.app;
1701                if (process == null) {
1702                    return;
1703                }
1704
1705                try {
1706                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1707                    String text = mContext.getString(R.string.heavy_weight_notification,
1708                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1709                    Notification notification = new Notification();
1710                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1711                    notification.when = 0;
1712                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1713                    notification.tickerText = text;
1714                    notification.defaults = 0; // please be quiet
1715                    notification.sound = null;
1716                    notification.vibrate = null;
1717                    notification.color = mContext.getColor(
1718                            com.android.internal.R.color.system_notification_accent_color);
1719                    notification.setLatestEventInfo(context, text,
1720                            mContext.getText(R.string.heavy_weight_notification_detail),
1721                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1722                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1723                                    new UserHandle(root.userId)));
1724
1725                    try {
1726                        int[] outId = new int[1];
1727                        inm.enqueueNotificationWithTag("android", "android", null,
1728                                R.string.heavy_weight_notification,
1729                                notification, outId, root.userId);
1730                    } catch (RuntimeException e) {
1731                        Slog.w(ActivityManagerService.TAG,
1732                                "Error showing notification for heavy-weight app", e);
1733                    } catch (RemoteException e) {
1734                    }
1735                } catch (NameNotFoundException e) {
1736                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1737                }
1738            } break;
1739            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1740                INotificationManager inm = NotificationManager.getService();
1741                if (inm == null) {
1742                    return;
1743                }
1744                try {
1745                    inm.cancelNotificationWithTag("android", null,
1746                            R.string.heavy_weight_notification,  msg.arg1);
1747                } catch (RuntimeException e) {
1748                    Slog.w(ActivityManagerService.TAG,
1749                            "Error canceling notification for service", e);
1750                } catch (RemoteException e) {
1751                }
1752            } break;
1753            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1754                synchronized (ActivityManagerService.this) {
1755                    checkExcessivePowerUsageLocked(true);
1756                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1757                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1758                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1759                }
1760            } break;
1761            case REPORT_MEM_USAGE_MSG: {
1762                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1763                Thread thread = new Thread() {
1764                    @Override public void run() {
1765                        reportMemUsage(memInfos);
1766                    }
1767                };
1768                thread.start();
1769                break;
1770            }
1771            case REPORT_USER_SWITCH_MSG: {
1772                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1773                break;
1774            }
1775            case CONTINUE_USER_SWITCH_MSG: {
1776                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1777                break;
1778            }
1779            case USER_SWITCH_TIMEOUT_MSG: {
1780                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1781                break;
1782            }
1783            case IMMERSIVE_MODE_LOCK_MSG: {
1784                final boolean nextState = (msg.arg1 != 0);
1785                if (mUpdateLock.isHeld() != nextState) {
1786                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1787                            "Applying new update lock state '" + nextState
1788                            + "' for " + (ActivityRecord)msg.obj);
1789                    if (nextState) {
1790                        mUpdateLock.acquire();
1791                    } else {
1792                        mUpdateLock.release();
1793                    }
1794                }
1795                break;
1796            }
1797            case PERSIST_URI_GRANTS_MSG: {
1798                writeGrantedUriPermissions();
1799                break;
1800            }
1801            case REQUEST_ALL_PSS_MSG: {
1802                synchronized (ActivityManagerService.this) {
1803                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1804                }
1805                break;
1806            }
1807            case START_PROFILES_MSG: {
1808                synchronized (ActivityManagerService.this) {
1809                    startProfilesLocked();
1810                }
1811                break;
1812            }
1813            case UPDATE_TIME: {
1814                synchronized (ActivityManagerService.this) {
1815                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1816                        ProcessRecord r = mLruProcesses.get(i);
1817                        if (r.thread != null) {
1818                            try {
1819                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1820                            } catch (RemoteException ex) {
1821                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1822                            }
1823                        }
1824                    }
1825                }
1826                break;
1827            }
1828            case SYSTEM_USER_START_MSG: {
1829                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1830                        Integer.toString(msg.arg1), msg.arg1);
1831                mSystemServiceManager.startUser(msg.arg1);
1832                break;
1833            }
1834            case SYSTEM_USER_CURRENT_MSG: {
1835                mBatteryStatsService.noteEvent(
1836                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1837                        Integer.toString(msg.arg2), msg.arg2);
1838                mBatteryStatsService.noteEvent(
1839                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1840                        Integer.toString(msg.arg1), msg.arg1);
1841                mSystemServiceManager.switchUser(msg.arg1);
1842                break;
1843            }
1844            case ENTER_ANIMATION_COMPLETE_MSG: {
1845                synchronized (ActivityManagerService.this) {
1846                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1847                    if (r != null && r.app != null && r.app.thread != null) {
1848                        try {
1849                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1850                        } catch (RemoteException e) {
1851                        }
1852                    }
1853                }
1854                break;
1855            }
1856            case FINISH_BOOTING_MSG: {
1857                if (msg.arg1 != 0) {
1858                    finishBooting();
1859                }
1860                if (msg.arg2 != 0) {
1861                    enableScreenAfterBoot();
1862                }
1863                break;
1864            }
1865            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1866                try {
1867                    Locale l = (Locale) msg.obj;
1868                    IBinder service = ServiceManager.getService("mount");
1869                    IMountService mountService = IMountService.Stub.asInterface(service);
1870                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1871                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1872                } catch (RemoteException e) {
1873                    Log.e(TAG, "Error storing locale for decryption UI", e);
1874                }
1875                break;
1876            }
1877            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1878                synchronized (ActivityManagerService.this) {
1879                    int i = mTaskStackListeners.beginBroadcast();
1880                    while (i > 0) {
1881                        i--;
1882                        try {
1883                            // Make a one-way callback to the listener
1884                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1885                        } catch (RemoteException e){
1886                            // Handled by the RemoteCallbackList
1887                        }
1888                    }
1889                    mTaskStackListeners.finishBroadcast();
1890                }
1891                break;
1892            }
1893            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1894                final int uid = msg.arg1;
1895                final byte[] firstPacket = (byte[]) msg.obj;
1896
1897                synchronized (mPidsSelfLocked) {
1898                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
1899                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
1900                        if (p.uid == uid) {
1901                            try {
1902                                p.thread.notifyCleartextNetwork(firstPacket);
1903                            } catch (RemoteException ignored) {
1904                            }
1905                        }
1906                    }
1907                }
1908                break;
1909            }
1910            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
1911                final String procName;
1912                final int uid;
1913                final long memLimit;
1914                final String reportPackage;
1915                synchronized (ActivityManagerService.this) {
1916                    procName = mMemWatchDumpProcName;
1917                    uid = mMemWatchDumpUid;
1918                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
1919                    if (val == null) {
1920                        val = mMemWatchProcesses.get(procName, 0);
1921                    }
1922                    if (val != null) {
1923                        memLimit = val.first;
1924                        reportPackage = val.second;
1925                    } else {
1926                        memLimit = 0;
1927                        reportPackage = null;
1928                    }
1929                }
1930                if (procName == null) {
1931                    return;
1932                }
1933
1934                if (DEBUG_PSS) Slog.d(TAG_PSS,
1935                        "Showing dump heap notification from " + procName + "/" + uid);
1936
1937                INotificationManager inm = NotificationManager.getService();
1938                if (inm == null) {
1939                    return;
1940                }
1941
1942                String text = mContext.getString(R.string.dump_heap_notification, procName);
1943                Notification notification = new Notification();
1944                notification.icon = com.android.internal.R.drawable.stat_sys_adb;
1945                notification.when = 0;
1946                notification.flags = Notification.FLAG_ONGOING_EVENT|Notification.FLAG_AUTO_CANCEL;
1947                notification.tickerText = text;
1948                notification.defaults = 0; // please be quiet
1949                notification.sound = null;
1950                notification.vibrate = null;
1951                notification.color = mContext.getColor(
1952                        com.android.internal.R.color.system_notification_accent_color);
1953                Intent deleteIntent = new Intent();
1954                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
1955                notification.deleteIntent = PendingIntent.getBroadcastAsUser(mContext, 0,
1956                        deleteIntent, 0, UserHandle.OWNER);
1957                Intent intent = new Intent();
1958                intent.setClassName("android", DumpHeapActivity.class.getName());
1959                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
1960                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
1961                if (reportPackage != null) {
1962                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
1963                }
1964                int userId = UserHandle.getUserId(uid);
1965                notification.setLatestEventInfo(mContext, text,
1966                        mContext.getText(R.string.dump_heap_notification_detail),
1967                        PendingIntent.getActivityAsUser(mContext, 0, intent,
1968                                PendingIntent.FLAG_CANCEL_CURRENT, null,
1969                                new UserHandle(userId)));
1970
1971                try {
1972                    int[] outId = new int[1];
1973                    inm.enqueueNotificationWithTag("android", "android", null,
1974                            R.string.dump_heap_notification,
1975                            notification, outId, userId);
1976                } catch (RuntimeException e) {
1977                    Slog.w(ActivityManagerService.TAG,
1978                            "Error showing notification for dump heap", e);
1979                } catch (RemoteException e) {
1980                }
1981            } break;
1982            case DELETE_DUMPHEAP_MSG: {
1983                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
1984                        DumpHeapActivity.JAVA_URI,
1985                        Intent.FLAG_GRANT_READ_URI_PERMISSION
1986                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
1987                        UserHandle.myUserId());
1988                synchronized (ActivityManagerService.this) {
1989                    mMemWatchDumpFile = null;
1990                    mMemWatchDumpProcName = null;
1991                    mMemWatchDumpPid = -1;
1992                    mMemWatchDumpUid = -1;
1993                }
1994            } break;
1995            case FOREGROUND_PROFILE_CHANGED_MSG: {
1996                dispatchForegroundProfileChanged(msg.arg1);
1997            } break;
1998            case REPORT_TIME_TRACKER_MSG: {
1999                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2000                tracker.deliverResult(mContext);
2001            } break;
2002            }
2003        }
2004    };
2005
2006    static final int COLLECT_PSS_BG_MSG = 1;
2007
2008    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2009        @Override
2010        public void handleMessage(Message msg) {
2011            switch (msg.what) {
2012            case COLLECT_PSS_BG_MSG: {
2013                long start = SystemClock.uptimeMillis();
2014                MemInfoReader memInfo = null;
2015                synchronized (ActivityManagerService.this) {
2016                    if (mFullPssPending) {
2017                        mFullPssPending = false;
2018                        memInfo = new MemInfoReader();
2019                    }
2020                }
2021                if (memInfo != null) {
2022                    updateCpuStatsNow();
2023                    long nativeTotalPss = 0;
2024                    synchronized (mProcessCpuTracker) {
2025                        final int N = mProcessCpuTracker.countStats();
2026                        for (int j=0; j<N; j++) {
2027                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2028                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2029                                // This is definitely an application process; skip it.
2030                                continue;
2031                            }
2032                            synchronized (mPidsSelfLocked) {
2033                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2034                                    // This is one of our own processes; skip it.
2035                                    continue;
2036                                }
2037                            }
2038                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2039                        }
2040                    }
2041                    memInfo.readMemInfo();
2042                    synchronized (ActivityManagerService.this) {
2043                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2044                                + (SystemClock.uptimeMillis()-start) + "ms");
2045                        final long cachedKb = memInfo.getCachedSizeKb();
2046                        final long freeKb = memInfo.getFreeSizeKb();
2047                        final long zramKb = memInfo.getZramTotalSizeKb();
2048                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2049                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2050                                kernelKb*1024, nativeTotalPss*1024);
2051                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2052                                nativeTotalPss);
2053                    }
2054                }
2055
2056                int num = 0;
2057                long[] tmp = new long[1];
2058                do {
2059                    ProcessRecord proc;
2060                    int procState;
2061                    int pid;
2062                    long lastPssTime;
2063                    synchronized (ActivityManagerService.this) {
2064                        if (mPendingPssProcesses.size() <= 0) {
2065                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2066                                    "Collected PSS of " + num + " processes in "
2067                                    + (SystemClock.uptimeMillis() - start) + "ms");
2068                            mPendingPssProcesses.clear();
2069                            return;
2070                        }
2071                        proc = mPendingPssProcesses.remove(0);
2072                        procState = proc.pssProcState;
2073                        lastPssTime = proc.lastPssTime;
2074                        if (proc.thread != null && procState == proc.setProcState
2075                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2076                                        < SystemClock.uptimeMillis()) {
2077                            pid = proc.pid;
2078                        } else {
2079                            proc = null;
2080                            pid = 0;
2081                        }
2082                    }
2083                    if (proc != null) {
2084                        long pss = Debug.getPss(pid, tmp, null);
2085                        synchronized (ActivityManagerService.this) {
2086                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2087                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2088                                num++;
2089                                recordPssSampleLocked(proc, procState, pss, tmp[0],
2090                                        SystemClock.uptimeMillis());
2091                            }
2092                        }
2093                    }
2094                } while (true);
2095            }
2096            }
2097        }
2098    };
2099
2100    public void setSystemProcess() {
2101        try {
2102            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2103            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2104            ServiceManager.addService("meminfo", new MemBinder(this));
2105            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2106            ServiceManager.addService("dbinfo", new DbBinder(this));
2107            if (MONITOR_CPU_USAGE) {
2108                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2109            }
2110            ServiceManager.addService("permission", new PermissionController(this));
2111            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2112
2113            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2114                    "android", STOCK_PM_FLAGS);
2115            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2116
2117            synchronized (this) {
2118                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2119                app.persistent = true;
2120                app.pid = MY_PID;
2121                app.maxAdj = ProcessList.SYSTEM_ADJ;
2122                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2123                synchronized (mPidsSelfLocked) {
2124                    mPidsSelfLocked.put(app.pid, app);
2125                }
2126                updateLruProcessLocked(app, false, null);
2127                updateOomAdjLocked();
2128            }
2129        } catch (PackageManager.NameNotFoundException e) {
2130            throw new RuntimeException(
2131                    "Unable to find android system package", e);
2132        }
2133    }
2134
2135    public void setWindowManager(WindowManagerService wm) {
2136        mWindowManager = wm;
2137        mStackSupervisor.setWindowManager(wm);
2138    }
2139
2140    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2141        mUsageStatsService = usageStatsManager;
2142    }
2143
2144    public void startObservingNativeCrashes() {
2145        final NativeCrashListener ncl = new NativeCrashListener(this);
2146        ncl.start();
2147    }
2148
2149    public IAppOpsService getAppOpsService() {
2150        return mAppOpsService;
2151    }
2152
2153    static class MemBinder extends Binder {
2154        ActivityManagerService mActivityManagerService;
2155        MemBinder(ActivityManagerService activityManagerService) {
2156            mActivityManagerService = activityManagerService;
2157        }
2158
2159        @Override
2160        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2161            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2162                    != PackageManager.PERMISSION_GRANTED) {
2163                pw.println("Permission Denial: can't dump meminfo from from pid="
2164                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2165                        + " without permission " + android.Manifest.permission.DUMP);
2166                return;
2167            }
2168
2169            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2170        }
2171    }
2172
2173    static class GraphicsBinder extends Binder {
2174        ActivityManagerService mActivityManagerService;
2175        GraphicsBinder(ActivityManagerService activityManagerService) {
2176            mActivityManagerService = activityManagerService;
2177        }
2178
2179        @Override
2180        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2181            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2182                    != PackageManager.PERMISSION_GRANTED) {
2183                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2184                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2185                        + " without permission " + android.Manifest.permission.DUMP);
2186                return;
2187            }
2188
2189            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2190        }
2191    }
2192
2193    static class DbBinder extends Binder {
2194        ActivityManagerService mActivityManagerService;
2195        DbBinder(ActivityManagerService activityManagerService) {
2196            mActivityManagerService = activityManagerService;
2197        }
2198
2199        @Override
2200        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2201            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2202                    != PackageManager.PERMISSION_GRANTED) {
2203                pw.println("Permission Denial: can't dump dbinfo from from pid="
2204                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2205                        + " without permission " + android.Manifest.permission.DUMP);
2206                return;
2207            }
2208
2209            mActivityManagerService.dumpDbInfo(fd, pw, args);
2210        }
2211    }
2212
2213    static class CpuBinder extends Binder {
2214        ActivityManagerService mActivityManagerService;
2215        CpuBinder(ActivityManagerService activityManagerService) {
2216            mActivityManagerService = activityManagerService;
2217        }
2218
2219        @Override
2220        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2221            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2222                    != PackageManager.PERMISSION_GRANTED) {
2223                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2224                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2225                        + " without permission " + android.Manifest.permission.DUMP);
2226                return;
2227            }
2228
2229            synchronized (mActivityManagerService.mProcessCpuTracker) {
2230                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2231                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2232                        SystemClock.uptimeMillis()));
2233            }
2234        }
2235    }
2236
2237    public static final class Lifecycle extends SystemService {
2238        private final ActivityManagerService mService;
2239
2240        public Lifecycle(Context context) {
2241            super(context);
2242            mService = new ActivityManagerService(context);
2243        }
2244
2245        @Override
2246        public void onStart() {
2247            mService.start();
2248        }
2249
2250        public ActivityManagerService getService() {
2251            return mService;
2252        }
2253    }
2254
2255    // Note: This method is invoked on the main thread but may need to attach various
2256    // handlers to other threads.  So take care to be explicit about the looper.
2257    public ActivityManagerService(Context systemContext) {
2258        mContext = systemContext;
2259        mFactoryTest = FactoryTest.getMode();
2260        mSystemThread = ActivityThread.currentActivityThread();
2261
2262        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2263
2264        mHandlerThread = new ServiceThread(TAG,
2265                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2266        mHandlerThread.start();
2267        mHandler = new MainHandler(mHandlerThread.getLooper());
2268        mUiHandler = new UiHandler();
2269
2270        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2271                "foreground", BROADCAST_FG_TIMEOUT, false);
2272        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2273                "background", BROADCAST_BG_TIMEOUT, true);
2274        mBroadcastQueues[0] = mFgBroadcastQueue;
2275        mBroadcastQueues[1] = mBgBroadcastQueue;
2276
2277        mServices = new ActiveServices(this);
2278        mProviderMap = new ProviderMap(this);
2279
2280        // TODO: Move creation of battery stats service outside of activity manager service.
2281        File dataDir = Environment.getDataDirectory();
2282        File systemDir = new File(dataDir, "system");
2283        systemDir.mkdirs();
2284        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2285        mBatteryStatsService.getActiveStatistics().readLocked();
2286        mBatteryStatsService.scheduleWriteToDisk();
2287        mOnBattery = DEBUG_POWER ? true
2288                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2289        mBatteryStatsService.getActiveStatistics().setCallback(this);
2290
2291        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2292
2293        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2294
2295        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2296
2297        // User 0 is the first and only user that runs at boot.
2298        mStartedUsers.put(UserHandle.USER_OWNER, new UserStartedState(UserHandle.OWNER, true));
2299        mUserLru.add(UserHandle.USER_OWNER);
2300        updateStartedUserArrayLocked();
2301
2302        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2303            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2304
2305        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2306
2307        mConfiguration.setToDefaults();
2308        mConfiguration.setLocale(Locale.getDefault());
2309
2310        mConfigurationSeq = mConfiguration.seq = 1;
2311        mProcessCpuTracker.init();
2312
2313        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2314        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2315        mRecentTasks = new RecentTasks(this);
2316        mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
2317        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
2318
2319        mProcessCpuThread = new Thread("CpuTracker") {
2320            @Override
2321            public void run() {
2322                while (true) {
2323                    try {
2324                        try {
2325                            synchronized(this) {
2326                                final long now = SystemClock.uptimeMillis();
2327                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2328                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2329                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2330                                //        + ", write delay=" + nextWriteDelay);
2331                                if (nextWriteDelay < nextCpuDelay) {
2332                                    nextCpuDelay = nextWriteDelay;
2333                                }
2334                                if (nextCpuDelay > 0) {
2335                                    mProcessCpuMutexFree.set(true);
2336                                    this.wait(nextCpuDelay);
2337                                }
2338                            }
2339                        } catch (InterruptedException e) {
2340                        }
2341                        updateCpuStatsNow();
2342                    } catch (Exception e) {
2343                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2344                    }
2345                }
2346            }
2347        };
2348
2349        Watchdog.getInstance().addMonitor(this);
2350        Watchdog.getInstance().addThread(mHandler);
2351    }
2352
2353    public void setSystemServiceManager(SystemServiceManager mgr) {
2354        mSystemServiceManager = mgr;
2355    }
2356
2357    public void setInstaller(Installer installer) {
2358        mInstaller = installer;
2359    }
2360
2361    private void start() {
2362        Process.removeAllProcessGroups();
2363        mProcessCpuThread.start();
2364
2365        mBatteryStatsService.publish(mContext);
2366        mAppOpsService.publish(mContext);
2367        Slog.d("AppOps", "AppOpsService published");
2368        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2369    }
2370
2371    public void initPowerManagement() {
2372        mStackSupervisor.initPowerManagement();
2373        mBatteryStatsService.initPowerManagement();
2374        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2375        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2376        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2377        mVoiceWakeLock.setReferenceCounted(false);
2378    }
2379
2380    @Override
2381    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2382            throws RemoteException {
2383        if (code == SYSPROPS_TRANSACTION) {
2384            // We need to tell all apps about the system property change.
2385            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2386            synchronized(this) {
2387                final int NP = mProcessNames.getMap().size();
2388                for (int ip=0; ip<NP; ip++) {
2389                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2390                    final int NA = apps.size();
2391                    for (int ia=0; ia<NA; ia++) {
2392                        ProcessRecord app = apps.valueAt(ia);
2393                        if (app.thread != null) {
2394                            procs.add(app.thread.asBinder());
2395                        }
2396                    }
2397                }
2398            }
2399
2400            int N = procs.size();
2401            for (int i=0; i<N; i++) {
2402                Parcel data2 = Parcel.obtain();
2403                try {
2404                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2405                } catch (RemoteException e) {
2406                }
2407                data2.recycle();
2408            }
2409        }
2410        try {
2411            return super.onTransact(code, data, reply, flags);
2412        } catch (RuntimeException e) {
2413            // The activity manager only throws security exceptions, so let's
2414            // log all others.
2415            if (!(e instanceof SecurityException)) {
2416                Slog.wtf(TAG, "Activity Manager Crash", e);
2417            }
2418            throw e;
2419        }
2420    }
2421
2422    void updateCpuStats() {
2423        final long now = SystemClock.uptimeMillis();
2424        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2425            return;
2426        }
2427        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2428            synchronized (mProcessCpuThread) {
2429                mProcessCpuThread.notify();
2430            }
2431        }
2432    }
2433
2434    void updateCpuStatsNow() {
2435        synchronized (mProcessCpuTracker) {
2436            mProcessCpuMutexFree.set(false);
2437            final long now = SystemClock.uptimeMillis();
2438            boolean haveNewCpuStats = false;
2439
2440            if (MONITOR_CPU_USAGE &&
2441                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2442                mLastCpuTime.set(now);
2443                mProcessCpuTracker.update();
2444                if (mProcessCpuTracker.hasGoodLastStats()) {
2445                    haveNewCpuStats = true;
2446                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2447                    //Slog.i(TAG, "Total CPU usage: "
2448                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2449
2450                    // Slog the cpu usage if the property is set.
2451                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2452                        int user = mProcessCpuTracker.getLastUserTime();
2453                        int system = mProcessCpuTracker.getLastSystemTime();
2454                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2455                        int irq = mProcessCpuTracker.getLastIrqTime();
2456                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2457                        int idle = mProcessCpuTracker.getLastIdleTime();
2458
2459                        int total = user + system + iowait + irq + softIrq + idle;
2460                        if (total == 0) total = 1;
2461
2462                        EventLog.writeEvent(EventLogTags.CPU,
2463                                ((user+system+iowait+irq+softIrq) * 100) / total,
2464                                (user * 100) / total,
2465                                (system * 100) / total,
2466                                (iowait * 100) / total,
2467                                (irq * 100) / total,
2468                                (softIrq * 100) / total);
2469                    }
2470                }
2471            }
2472
2473            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2474            synchronized(bstats) {
2475                synchronized(mPidsSelfLocked) {
2476                    if (haveNewCpuStats) {
2477                        final int perc = bstats.startAddingCpuLocked();
2478                        if (perc >= 0) {
2479                            int remainUTime = 0;
2480                            int remainSTime = 0;
2481                            int totalUTime = 0;
2482                            int totalSTime = 0;
2483                            final int N = mProcessCpuTracker.countStats();
2484                            for (int i=0; i<N; i++) {
2485                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2486                                if (!st.working) {
2487                                    continue;
2488                                }
2489                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2490                                int otherUTime = (st.rel_utime*perc)/100;
2491                                int otherSTime = (st.rel_stime*perc)/100;
2492                                remainUTime += otherUTime;
2493                                remainSTime += otherSTime;
2494                                totalUTime += st.rel_utime;
2495                                totalSTime += st.rel_stime;
2496                                if (pr != null) {
2497                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2498                                    if (ps == null || !ps.isActive()) {
2499                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2500                                                pr.info.uid, pr.processName);
2501                                    }
2502                                    ps.addCpuTimeLocked(st.rel_utime - otherUTime,
2503                                            st.rel_stime - otherSTime);
2504                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2505                                } else {
2506                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2507                                    if (ps == null || !ps.isActive()) {
2508                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2509                                                bstats.mapUid(st.uid), st.name);
2510                                    }
2511                                    ps.addCpuTimeLocked(st.rel_utime - otherUTime,
2512                                            st.rel_stime - otherSTime);
2513                                }
2514                            }
2515                            final int userTime = mProcessCpuTracker.getLastUserTime();
2516                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2517                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2518                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2519                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2520                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2521                            bstats.finishAddingCpuLocked(perc, remainUTime,
2522                                    remainSTime, totalUTime, totalSTime, userTime, systemTime,
2523                                    iowaitTime, irqTime, softIrqTime, idleTime);
2524                        }
2525                    }
2526                }
2527
2528                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2529                    mLastWriteTime = now;
2530                    mBatteryStatsService.scheduleWriteToDisk();
2531                }
2532            }
2533        }
2534    }
2535
2536    @Override
2537    public void batteryNeedsCpuUpdate() {
2538        updateCpuStatsNow();
2539    }
2540
2541    @Override
2542    public void batteryPowerChanged(boolean onBattery) {
2543        // When plugging in, update the CPU stats first before changing
2544        // the plug state.
2545        updateCpuStatsNow();
2546        synchronized (this) {
2547            synchronized(mPidsSelfLocked) {
2548                mOnBattery = DEBUG_POWER ? true : onBattery;
2549            }
2550        }
2551    }
2552
2553    @Override
2554    public void batterySendBroadcast(Intent intent) {
2555        broadcastIntentLocked(null, null, intent, null,
2556                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
2557                Process.SYSTEM_UID, UserHandle.USER_ALL);
2558    }
2559
2560    /**
2561     * Initialize the application bind args. These are passed to each
2562     * process when the bindApplication() IPC is sent to the process. They're
2563     * lazily setup to make sure the services are running when they're asked for.
2564     */
2565    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2566        if (mAppBindArgs == null) {
2567            mAppBindArgs = new HashMap<>();
2568
2569            // Isolated processes won't get this optimization, so that we don't
2570            // violate the rules about which services they have access to.
2571            if (!isolated) {
2572                // Setup the application init args
2573                mAppBindArgs.put("package", ServiceManager.getService("package"));
2574                mAppBindArgs.put("window", ServiceManager.getService("window"));
2575                mAppBindArgs.put(Context.ALARM_SERVICE,
2576                        ServiceManager.getService(Context.ALARM_SERVICE));
2577            }
2578        }
2579        return mAppBindArgs;
2580    }
2581
2582    final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2583        if (r != null && mFocusedActivity != r) {
2584            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2585            ActivityRecord last = mFocusedActivity;
2586            mFocusedActivity = r;
2587            if (r.task.taskType != ActivityRecord.HOME_ACTIVITY_TYPE
2588                    && r.task.taskType != ActivityRecord.RECENTS_ACTIVITY_TYPE) {
2589                if (mCurAppTimeTracker != r.appTimeTracker) {
2590                    // We are switching app tracking.  Complete the current one.
2591                    if (mCurAppTimeTracker != null) {
2592                        mCurAppTimeTracker.stop();
2593                        mHandler.obtainMessage(REPORT_TIME_TRACKER_MSG,
2594                                mCurAppTimeTracker).sendToTarget();
2595                        mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2596                        mCurAppTimeTracker = null;
2597                    }
2598                    if (r.appTimeTracker != null) {
2599                        mCurAppTimeTracker = r.appTimeTracker;
2600                        startTimeTrackingFocusedActivityLocked();
2601                    }
2602                } else {
2603                    startTimeTrackingFocusedActivityLocked();
2604                }
2605            } else {
2606                r.appTimeTracker = null;
2607            }
2608            if (r.task != null && r.task.voiceInteractor != null) {
2609                startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2610            } else {
2611                finishRunningVoiceLocked();
2612                if (last != null && last.task.voiceSession != null) {
2613                    // We had been in a voice interaction session, but now focused has
2614                    // move to something different.  Just finish the session, we can't
2615                    // return to it and retain the proper state and synchronization with
2616                    // the voice interaction service.
2617                    finishVoiceTask(last.task.voiceSession);
2618                }
2619            }
2620            if (mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
2621                mWindowManager.setFocusedApp(r.appToken, true);
2622            }
2623            applyUpdateLockStateLocked(r);
2624            if (mFocusedActivity.userId != mLastFocusedUserId) {
2625                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2626                mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2627                        mFocusedActivity.userId, 0));
2628                mLastFocusedUserId = mFocusedActivity.userId;
2629            }
2630        }
2631        EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY,
2632                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2633                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2634    }
2635
2636    final void clearFocusedActivity(ActivityRecord r) {
2637        if (mFocusedActivity == r) {
2638            ActivityStack stack = mStackSupervisor.getFocusedStack();
2639            if (stack != null) {
2640                ActivityRecord top = stack.topActivity();
2641                if (top != null && top.userId != mLastFocusedUserId) {
2642                    mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2643                    mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2644                                    top.userId, 0));
2645                    mLastFocusedUserId = top.userId;
2646                }
2647            }
2648            mFocusedActivity = null;
2649            EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, -1, "NULL");
2650        }
2651    }
2652
2653    @Override
2654    public void setFocusedStack(int stackId) {
2655        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2656        synchronized (ActivityManagerService.this) {
2657            ActivityStack stack = mStackSupervisor.getStack(stackId);
2658            if (stack != null) {
2659                ActivityRecord r = stack.topRunningActivityLocked(null);
2660                if (r != null) {
2661                    setFocusedActivityLocked(r, "setFocusedStack");
2662                    mStackSupervisor.resumeTopActivitiesLocked(stack, null, null);
2663                }
2664            }
2665        }
2666    }
2667
2668    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2669    @Override
2670    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2671        synchronized (ActivityManagerService.this) {
2672            if (listener != null) {
2673                mTaskStackListeners.register(listener);
2674            }
2675        }
2676    }
2677
2678    @Override
2679    public void notifyActivityDrawn(IBinder token) {
2680        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2681        synchronized (this) {
2682            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2683            if (r != null) {
2684                r.task.stack.notifyActivityDrawnLocked(r);
2685            }
2686        }
2687    }
2688
2689    final void applyUpdateLockStateLocked(ActivityRecord r) {
2690        // Modifications to the UpdateLock state are done on our handler, outside
2691        // the activity manager's locks.  The new state is determined based on the
2692        // state *now* of the relevant activity record.  The object is passed to
2693        // the handler solely for logging detail, not to be consulted/modified.
2694        final boolean nextState = r != null && r.immersive;
2695        mHandler.sendMessage(
2696                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2697    }
2698
2699    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2700        Message msg = Message.obtain();
2701        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2702        msg.obj = r.task.askedCompatMode ? null : r;
2703        mUiHandler.sendMessage(msg);
2704    }
2705
2706    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2707            String what, Object obj, ProcessRecord srcApp) {
2708        app.lastActivityTime = now;
2709
2710        if (app.activities.size() > 0) {
2711            // Don't want to touch dependent processes that are hosting activities.
2712            return index;
2713        }
2714
2715        int lrui = mLruProcesses.lastIndexOf(app);
2716        if (lrui < 0) {
2717            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2718                    + what + " " + obj + " from " + srcApp);
2719            return index;
2720        }
2721
2722        if (lrui >= index) {
2723            // Don't want to cause this to move dependent processes *back* in the
2724            // list as if they were less frequently used.
2725            return index;
2726        }
2727
2728        if (lrui >= mLruProcessActivityStart) {
2729            // Don't want to touch dependent processes that are hosting activities.
2730            return index;
2731        }
2732
2733        mLruProcesses.remove(lrui);
2734        if (index > 0) {
2735            index--;
2736        }
2737        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2738                + " in LRU list: " + app);
2739        mLruProcesses.add(index, app);
2740        return index;
2741    }
2742
2743    final void removeLruProcessLocked(ProcessRecord app) {
2744        int lrui = mLruProcesses.lastIndexOf(app);
2745        if (lrui >= 0) {
2746            if (!app.killed) {
2747                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2748                Process.killProcessQuiet(app.pid);
2749                Process.killProcessGroup(app.info.uid, app.pid);
2750            }
2751            if (lrui <= mLruProcessActivityStart) {
2752                mLruProcessActivityStart--;
2753            }
2754            if (lrui <= mLruProcessServiceStart) {
2755                mLruProcessServiceStart--;
2756            }
2757            mLruProcesses.remove(lrui);
2758        }
2759    }
2760
2761    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2762            ProcessRecord client) {
2763        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2764                || app.treatLikeActivity;
2765        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2766        if (!activityChange && hasActivity) {
2767            // The process has activities, so we are only allowing activity-based adjustments
2768            // to move it.  It should be kept in the front of the list with other
2769            // processes that have activities, and we don't want those to change their
2770            // order except due to activity operations.
2771            return;
2772        }
2773
2774        mLruSeq++;
2775        final long now = SystemClock.uptimeMillis();
2776        app.lastActivityTime = now;
2777
2778        // First a quick reject: if the app is already at the position we will
2779        // put it, then there is nothing to do.
2780        if (hasActivity) {
2781            final int N = mLruProcesses.size();
2782            if (N > 0 && mLruProcesses.get(N-1) == app) {
2783                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
2784                return;
2785            }
2786        } else {
2787            if (mLruProcessServiceStart > 0
2788                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2789                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
2790                return;
2791            }
2792        }
2793
2794        int lrui = mLruProcesses.lastIndexOf(app);
2795
2796        if (app.persistent && lrui >= 0) {
2797            // We don't care about the position of persistent processes, as long as
2798            // they are in the list.
2799            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
2800            return;
2801        }
2802
2803        /* In progress: compute new position first, so we can avoid doing work
2804           if the process is not actually going to move.  Not yet working.
2805        int addIndex;
2806        int nextIndex;
2807        boolean inActivity = false, inService = false;
2808        if (hasActivity) {
2809            // Process has activities, put it at the very tipsy-top.
2810            addIndex = mLruProcesses.size();
2811            nextIndex = mLruProcessServiceStart;
2812            inActivity = true;
2813        } else if (hasService) {
2814            // Process has services, put it at the top of the service list.
2815            addIndex = mLruProcessActivityStart;
2816            nextIndex = mLruProcessServiceStart;
2817            inActivity = true;
2818            inService = true;
2819        } else  {
2820            // Process not otherwise of interest, it goes to the top of the non-service area.
2821            addIndex = mLruProcessServiceStart;
2822            if (client != null) {
2823                int clientIndex = mLruProcesses.lastIndexOf(client);
2824                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2825                        + app);
2826                if (clientIndex >= 0 && addIndex > clientIndex) {
2827                    addIndex = clientIndex;
2828                }
2829            }
2830            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2831        }
2832
2833        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2834                + mLruProcessActivityStart + "): " + app);
2835        */
2836
2837        if (lrui >= 0) {
2838            if (lrui < mLruProcessActivityStart) {
2839                mLruProcessActivityStart--;
2840            }
2841            if (lrui < mLruProcessServiceStart) {
2842                mLruProcessServiceStart--;
2843            }
2844            /*
2845            if (addIndex > lrui) {
2846                addIndex--;
2847            }
2848            if (nextIndex > lrui) {
2849                nextIndex--;
2850            }
2851            */
2852            mLruProcesses.remove(lrui);
2853        }
2854
2855        /*
2856        mLruProcesses.add(addIndex, app);
2857        if (inActivity) {
2858            mLruProcessActivityStart++;
2859        }
2860        if (inService) {
2861            mLruProcessActivityStart++;
2862        }
2863        */
2864
2865        int nextIndex;
2866        if (hasActivity) {
2867            final int N = mLruProcesses.size();
2868            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
2869                // Process doesn't have activities, but has clients with
2870                // activities...  move it up, but one below the top (the top
2871                // should always have a real activity).
2872                if (DEBUG_LRU) Slog.d(TAG_LRU,
2873                        "Adding to second-top of LRU activity list: " + app);
2874                mLruProcesses.add(N - 1, app);
2875                // To keep it from spamming the LRU list (by making a bunch of clients),
2876                // we will push down any other entries owned by the app.
2877                final int uid = app.info.uid;
2878                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
2879                    ProcessRecord subProc = mLruProcesses.get(i);
2880                    if (subProc.info.uid == uid) {
2881                        // We want to push this one down the list.  If the process after
2882                        // it is for the same uid, however, don't do so, because we don't
2883                        // want them internally to be re-ordered.
2884                        if (mLruProcesses.get(i - 1).info.uid != uid) {
2885                            if (DEBUG_LRU) Slog.d(TAG_LRU,
2886                                    "Pushing uid " + uid + " swapping at " + i + ": "
2887                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
2888                            ProcessRecord tmp = mLruProcesses.get(i);
2889                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
2890                            mLruProcesses.set(i - 1, tmp);
2891                            i--;
2892                        }
2893                    } else {
2894                        // A gap, we can stop here.
2895                        break;
2896                    }
2897                }
2898            } else {
2899                // Process has activities, put it at the very tipsy-top.
2900                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
2901                mLruProcesses.add(app);
2902            }
2903            nextIndex = mLruProcessServiceStart;
2904        } else if (hasService) {
2905            // Process has services, put it at the top of the service list.
2906            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
2907            mLruProcesses.add(mLruProcessActivityStart, app);
2908            nextIndex = mLruProcessServiceStart;
2909            mLruProcessActivityStart++;
2910        } else  {
2911            // Process not otherwise of interest, it goes to the top of the non-service area.
2912            int index = mLruProcessServiceStart;
2913            if (client != null) {
2914                // If there is a client, don't allow the process to be moved up higher
2915                // in the list than that client.
2916                int clientIndex = mLruProcesses.lastIndexOf(client);
2917                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
2918                        + " when updating " + app);
2919                if (clientIndex <= lrui) {
2920                    // Don't allow the client index restriction to push it down farther in the
2921                    // list than it already is.
2922                    clientIndex = lrui;
2923                }
2924                if (clientIndex >= 0 && index > clientIndex) {
2925                    index = clientIndex;
2926                }
2927            }
2928            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
2929            mLruProcesses.add(index, app);
2930            nextIndex = index-1;
2931            mLruProcessActivityStart++;
2932            mLruProcessServiceStart++;
2933        }
2934
2935        // If the app is currently using a content provider or service,
2936        // bump those processes as well.
2937        for (int j=app.connections.size()-1; j>=0; j--) {
2938            ConnectionRecord cr = app.connections.valueAt(j);
2939            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2940                    && cr.binding.service.app != null
2941                    && cr.binding.service.app.lruSeq != mLruSeq
2942                    && !cr.binding.service.app.persistent) {
2943                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2944                        "service connection", cr, app);
2945            }
2946        }
2947        for (int j=app.conProviders.size()-1; j>=0; j--) {
2948            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2949            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2950                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2951                        "provider reference", cpr, app);
2952            }
2953        }
2954    }
2955
2956    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2957        if (uid == Process.SYSTEM_UID) {
2958            // The system gets to run in any process.  If there are multiple
2959            // processes with the same uid, just pick the first (this
2960            // should never happen).
2961            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2962            if (procs == null) return null;
2963            final int N = procs.size();
2964            for (int i = 0; i < N; i++) {
2965                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2966            }
2967        }
2968        ProcessRecord proc = mProcessNames.get(processName, uid);
2969        if (false && proc != null && !keepIfLarge
2970                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2971                && proc.lastCachedPss >= 4000) {
2972            // Turn this condition on to cause killing to happen regularly, for testing.
2973            if (proc.baseProcessTracker != null) {
2974                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2975            }
2976            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2977        } else if (proc != null && !keepIfLarge
2978                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2979                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2980            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2981            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2982                if (proc.baseProcessTracker != null) {
2983                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2984                }
2985                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2986            }
2987        }
2988        return proc;
2989    }
2990
2991    void ensurePackageDexOpt(String packageName) {
2992        IPackageManager pm = AppGlobals.getPackageManager();
2993        try {
2994            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2995                mDidDexOpt = true;
2996            }
2997        } catch (RemoteException e) {
2998        }
2999    }
3000
3001    boolean isNextTransitionForward() {
3002        int transit = mWindowManager.getPendingAppTransition();
3003        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
3004                || transit == AppTransition.TRANSIT_TASK_OPEN
3005                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
3006    }
3007
3008    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3009            String processName, String abiOverride, int uid, Runnable crashHandler) {
3010        synchronized(this) {
3011            ApplicationInfo info = new ApplicationInfo();
3012            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3013            // For isolated processes, the former contains the parent's uid and the latter the
3014            // actual uid of the isolated process.
3015            // In the special case introduced by this method (which is, starting an isolated
3016            // process directly from the SystemServer without an actual parent app process) the
3017            // closest thing to a parent's uid is SYSTEM_UID.
3018            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3019            // the |isolated| logic in the ProcessRecord constructor.
3020            info.uid = Process.SYSTEM_UID;
3021            info.processName = processName;
3022            info.className = entryPoint;
3023            info.packageName = "android";
3024            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3025                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3026                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3027                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3028                    crashHandler);
3029            return proc != null ? proc.pid : 0;
3030        }
3031    }
3032
3033    final ProcessRecord startProcessLocked(String processName,
3034            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3035            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3036            boolean isolated, boolean keepIfLarge) {
3037        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3038                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3039                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3040                null /* crashHandler */);
3041    }
3042
3043    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3044            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3045            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3046            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3047        long startTime = SystemClock.elapsedRealtime();
3048        ProcessRecord app;
3049        if (!isolated) {
3050            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3051            checkTime(startTime, "startProcess: after getProcessRecord");
3052
3053            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3054                // If we are in the background, then check to see if this process
3055                // is bad.  If so, we will just silently fail.
3056                if (mBadProcesses.get(info.processName, info.uid) != null) {
3057                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3058                            + "/" + info.processName);
3059                    return null;
3060                }
3061            } else {
3062                // When the user is explicitly starting a process, then clear its
3063                // crash count so that we won't make it bad until they see at
3064                // least one crash dialog again, and make the process good again
3065                // if it had been bad.
3066                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3067                        + "/" + info.processName);
3068                mProcessCrashTimes.remove(info.processName, info.uid);
3069                if (mBadProcesses.get(info.processName, info.uid) != null) {
3070                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3071                            UserHandle.getUserId(info.uid), info.uid,
3072                            info.processName);
3073                    mBadProcesses.remove(info.processName, info.uid);
3074                    if (app != null) {
3075                        app.bad = false;
3076                    }
3077                }
3078            }
3079        } else {
3080            // If this is an isolated process, it can't re-use an existing process.
3081            app = null;
3082        }
3083
3084        // We don't have to do anything more if:
3085        // (1) There is an existing application record; and
3086        // (2) The caller doesn't think it is dead, OR there is no thread
3087        //     object attached to it so we know it couldn't have crashed; and
3088        // (3) There is a pid assigned to it, so it is either starting or
3089        //     already running.
3090        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3091                + " app=" + app + " knownToBeDead=" + knownToBeDead
3092                + " thread=" + (app != null ? app.thread : null)
3093                + " pid=" + (app != null ? app.pid : -1));
3094        if (app != null && app.pid > 0) {
3095            if (!knownToBeDead || app.thread == null) {
3096                // We already have the app running, or are waiting for it to
3097                // come up (we have a pid but not yet its thread), so keep it.
3098                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3099                // If this is a new package in the process, add the package to the list
3100                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3101                checkTime(startTime, "startProcess: done, added package to proc");
3102                return app;
3103            }
3104
3105            // An application record is attached to a previous process,
3106            // clean it up now.
3107            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3108            checkTime(startTime, "startProcess: bad proc running, killing");
3109            Process.killProcessGroup(app.info.uid, app.pid);
3110            handleAppDiedLocked(app, true, true);
3111            checkTime(startTime, "startProcess: done killing old proc");
3112        }
3113
3114        String hostingNameStr = hostingName != null
3115                ? hostingName.flattenToShortString() : null;
3116
3117        if (app == null) {
3118            checkTime(startTime, "startProcess: creating new process record");
3119            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3120            if (app == null) {
3121                Slog.w(TAG, "Failed making new process record for "
3122                        + processName + "/" + info.uid + " isolated=" + isolated);
3123                return null;
3124            }
3125            app.crashHandler = crashHandler;
3126            checkTime(startTime, "startProcess: done creating new process record");
3127        } else {
3128            // If this is a new package in the process, add the package to the list
3129            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3130            checkTime(startTime, "startProcess: added package to existing proc");
3131        }
3132
3133        // If the system is not ready yet, then hold off on starting this
3134        // process until it is.
3135        if (!mProcessesReady
3136                && !isAllowedWhileBooting(info)
3137                && !allowWhileBooting) {
3138            if (!mProcessesOnHold.contains(app)) {
3139                mProcessesOnHold.add(app);
3140            }
3141            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3142                    "System not ready, putting on hold: " + app);
3143            checkTime(startTime, "startProcess: returning with proc on hold");
3144            return app;
3145        }
3146
3147        checkTime(startTime, "startProcess: stepping in to startProcess");
3148        startProcessLocked(
3149                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3150        checkTime(startTime, "startProcess: done starting proc!");
3151        return (app.pid != 0) ? app : null;
3152    }
3153
3154    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3155        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3156    }
3157
3158    private final void startProcessLocked(ProcessRecord app,
3159            String hostingType, String hostingNameStr) {
3160        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3161                null /* entryPoint */, null /* entryPointArgs */);
3162    }
3163
3164    private final void startProcessLocked(ProcessRecord app, String hostingType,
3165            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3166        long startTime = SystemClock.elapsedRealtime();
3167        if (app.pid > 0 && app.pid != MY_PID) {
3168            checkTime(startTime, "startProcess: removing from pids map");
3169            synchronized (mPidsSelfLocked) {
3170                mPidsSelfLocked.remove(app.pid);
3171                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3172            }
3173            checkTime(startTime, "startProcess: done removing from pids map");
3174            app.setPid(0);
3175        }
3176
3177        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3178                "startProcessLocked removing on hold: " + app);
3179        mProcessesOnHold.remove(app);
3180
3181        checkTime(startTime, "startProcess: starting to update cpu stats");
3182        updateCpuStats();
3183        checkTime(startTime, "startProcess: done updating cpu stats");
3184
3185        try {
3186            try {
3187                if (AppGlobals.getPackageManager().isPackageFrozen(app.info.packageName)) {
3188                    // This is caught below as if we had failed to fork zygote
3189                    throw new RuntimeException("Package " + app.info.packageName + " is frozen!");
3190                }
3191            } catch (RemoteException e) {
3192                throw e.rethrowAsRuntimeException();
3193            }
3194
3195            int uid = app.uid;
3196            int[] gids = null;
3197            int mountExternal = Zygote.MOUNT_EXTERNAL_DEFAULT;
3198            if (!app.isolated) {
3199                int[] permGids = null;
3200                try {
3201                    checkTime(startTime, "startProcess: getting gids from package manager");
3202                    permGids = AppGlobals.getPackageManager().getPackageGids(app.info.packageName,
3203                            app.userId);
3204                } catch (RemoteException e) {
3205                    throw e.rethrowAsRuntimeException();
3206                }
3207
3208                /*
3209                 * Add shared application and profile GIDs so applications can share some
3210                 * resources like shared libraries and access user-wide resources
3211                 */
3212                if (ArrayUtils.isEmpty(permGids)) {
3213                    gids = new int[2];
3214                } else {
3215                    gids = new int[permGids.length + 2];
3216                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3217                }
3218                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3219                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3220            }
3221            checkTime(startTime, "startProcess: building args");
3222            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3223                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3224                        && mTopComponent != null
3225                        && app.processName.equals(mTopComponent.getPackageName())) {
3226                    uid = 0;
3227                }
3228                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3229                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3230                    uid = 0;
3231                }
3232            }
3233            int debugFlags = 0;
3234            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3235                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3236                // Also turn on CheckJNI for debuggable apps. It's quite
3237                // awkward to turn on otherwise.
3238                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3239            }
3240            // Run the app in safe mode if its manifest requests so or the
3241            // system is booted in safe mode.
3242            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3243                mSafeMode == true) {
3244                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3245            }
3246            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3247                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3248            }
3249            String jitDebugProperty = SystemProperties.get("debug.usejit");
3250            if ("true".equals(jitDebugProperty)) {
3251                debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3252            } else if (!"false".equals(jitDebugProperty)) {
3253                // If we didn't force disable by setting false, defer to the dalvik vm options.
3254                if ("true".equals(SystemProperties.get("dalvik.vm.usejit"))) {
3255                    debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3256                }
3257            }
3258            String genCFIDebugProperty = SystemProperties.get("debug.gencfi");
3259            if ("true".equals(genCFIDebugProperty)) {
3260                debugFlags |= Zygote.DEBUG_GENERATE_CFI;
3261            }
3262            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3263                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3264            }
3265            if ("1".equals(SystemProperties.get("debug.assert"))) {
3266                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3267            }
3268
3269            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3270            if (requiredAbi == null) {
3271                requiredAbi = Build.SUPPORTED_ABIS[0];
3272            }
3273
3274            String instructionSet = null;
3275            if (app.info.primaryCpuAbi != null) {
3276                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3277            }
3278
3279            app.gids = gids;
3280            app.requiredAbi = requiredAbi;
3281            app.instructionSet = instructionSet;
3282
3283            // Start the process.  It will either succeed and return a result containing
3284            // the PID of the new process, or else throw a RuntimeException.
3285            boolean isActivityProcess = (entryPoint == null);
3286            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3287            checkTime(startTime, "startProcess: asking zygote to start proc");
3288            Process.ProcessStartResult startResult = Process.start(entryPoint,
3289                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3290                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3291                    app.info.dataDir, entryPointArgs);
3292            checkTime(startTime, "startProcess: returned from zygote!");
3293
3294            if (app.isolated) {
3295                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3296            }
3297            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3298            checkTime(startTime, "startProcess: done updating battery stats");
3299
3300            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3301                    UserHandle.getUserId(uid), startResult.pid, uid,
3302                    app.processName, hostingType,
3303                    hostingNameStr != null ? hostingNameStr : "");
3304
3305            if (app.persistent) {
3306                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3307            }
3308
3309            checkTime(startTime, "startProcess: building log message");
3310            StringBuilder buf = mStringBuilder;
3311            buf.setLength(0);
3312            buf.append("Start proc ");
3313            buf.append(startResult.pid);
3314            buf.append(':');
3315            buf.append(app.processName);
3316            buf.append('/');
3317            UserHandle.formatUid(buf, uid);
3318            if (!isActivityProcess) {
3319                buf.append(" [");
3320                buf.append(entryPoint);
3321                buf.append("]");
3322            }
3323            buf.append(" for ");
3324            buf.append(hostingType);
3325            if (hostingNameStr != null) {
3326                buf.append(" ");
3327                buf.append(hostingNameStr);
3328            }
3329            Slog.i(TAG, buf.toString());
3330            app.setPid(startResult.pid);
3331            app.usingWrapper = startResult.usingWrapper;
3332            app.removed = false;
3333            app.killed = false;
3334            app.killedByAm = false;
3335            checkTime(startTime, "startProcess: starting to update pids map");
3336            synchronized (mPidsSelfLocked) {
3337                this.mPidsSelfLocked.put(startResult.pid, app);
3338                if (isActivityProcess) {
3339                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3340                    msg.obj = app;
3341                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3342                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3343                }
3344            }
3345            checkTime(startTime, "startProcess: done updating pids map");
3346        } catch (RuntimeException e) {
3347            // XXX do better error recovery.
3348            app.setPid(0);
3349            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3350            if (app.isolated) {
3351                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3352            }
3353            Slog.e(TAG, "Failure starting process " + app.processName, e);
3354        }
3355    }
3356
3357    void updateUsageStats(ActivityRecord component, boolean resumed) {
3358        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3359                "updateUsageStats: comp=" + component + "res=" + resumed);
3360        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3361        if (resumed) {
3362            if (mUsageStatsService != null) {
3363                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3364                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3365            }
3366            synchronized (stats) {
3367                stats.noteActivityResumedLocked(component.app.uid);
3368            }
3369        } else {
3370            if (mUsageStatsService != null) {
3371                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3372                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3373            }
3374            synchronized (stats) {
3375                stats.noteActivityPausedLocked(component.app.uid);
3376            }
3377        }
3378    }
3379
3380    Intent getHomeIntent() {
3381        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3382        intent.setComponent(mTopComponent);
3383        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3384            intent.addCategory(Intent.CATEGORY_HOME);
3385        }
3386        return intent;
3387    }
3388
3389    boolean startHomeActivityLocked(int userId, String reason) {
3390        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3391                && mTopAction == null) {
3392            // We are running in factory test mode, but unable to find
3393            // the factory test app, so just sit around displaying the
3394            // error message and don't try to start anything.
3395            return false;
3396        }
3397        Intent intent = getHomeIntent();
3398        ActivityInfo aInfo =
3399            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3400        if (aInfo != null) {
3401            intent.setComponent(new ComponentName(
3402                    aInfo.applicationInfo.packageName, aInfo.name));
3403            // Don't do this if the home app is currently being
3404            // instrumented.
3405            aInfo = new ActivityInfo(aInfo);
3406            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3407            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3408                    aInfo.applicationInfo.uid, true);
3409            if (app == null || app.instrumentationClass == null) {
3410                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3411                mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3412            }
3413        }
3414
3415        return true;
3416    }
3417
3418    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3419        ActivityInfo ai = null;
3420        ComponentName comp = intent.getComponent();
3421        try {
3422            if (comp != null) {
3423                // Factory test.
3424                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3425            } else {
3426                ComponentName preferredComponent = mPreferredSetupActivities.get(userId);
3427                if (preferredComponent != null) {
3428                    ai = AppGlobals.getPackageManager().getActivityInfo(
3429                            preferredComponent, flags, userId);
3430                } else {
3431                    ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3432                            intent,
3433                            intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3434                                flags, userId);
3435
3436                    if (info != null) {
3437                        ai = info.activityInfo;
3438                    }
3439                }
3440            }
3441        } catch (RemoteException e) {
3442            // ignore
3443        }
3444
3445        return ai;
3446    }
3447
3448    /**
3449     * Starts the "new version setup screen" if appropriate.
3450     */
3451    void startSetupActivityLocked() {
3452        // Only do this once per boot.
3453        if (mCheckedForSetup) {
3454            return;
3455        }
3456
3457        // We will show this screen if the current one is a different
3458        // version than the last one shown, and we are not running in
3459        // low-level factory test mode.
3460        final ContentResolver resolver = mContext.getContentResolver();
3461        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3462                Settings.Global.getInt(resolver,
3463                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3464            mCheckedForSetup = true;
3465
3466            // See if we should be showing the platform update setup UI.
3467            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3468            List<ResolveInfo> ris = mContext.getPackageManager()
3469                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3470
3471            // We don't allow third party apps to replace this.
3472            ResolveInfo ri = null;
3473            for (int i=0; ris != null && i<ris.size(); i++) {
3474                if ((ris.get(i).activityInfo.applicationInfo.flags
3475                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3476                    ri = ris.get(i);
3477                    break;
3478                }
3479            }
3480
3481            if (ri != null) {
3482                String vers = ri.activityInfo.metaData != null
3483                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3484                        : null;
3485                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3486                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3487                            Intent.METADATA_SETUP_VERSION);
3488                }
3489                String lastVers = Settings.Secure.getString(
3490                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3491                if (vers != null && !vers.equals(lastVers)) {
3492                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3493                    intent.setComponent(new ComponentName(
3494                            ri.activityInfo.packageName, ri.activityInfo.name));
3495                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3496                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3497                            null);
3498                }
3499            }
3500        }
3501    }
3502
3503    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3504        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3505    }
3506
3507    void enforceNotIsolatedCaller(String caller) {
3508        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3509            throw new SecurityException("Isolated process not allowed to call " + caller);
3510        }
3511    }
3512
3513    void enforceShellRestriction(String restriction, int userHandle) {
3514        if (Binder.getCallingUid() == Process.SHELL_UID) {
3515            if (userHandle < 0
3516                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3517                throw new SecurityException("Shell does not have permission to access user "
3518                        + userHandle);
3519            }
3520        }
3521    }
3522
3523    @Override
3524    public int getFrontActivityScreenCompatMode() {
3525        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3526        synchronized (this) {
3527            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3528        }
3529    }
3530
3531    @Override
3532    public void setFrontActivityScreenCompatMode(int mode) {
3533        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3534                "setFrontActivityScreenCompatMode");
3535        synchronized (this) {
3536            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3537        }
3538    }
3539
3540    @Override
3541    public int getPackageScreenCompatMode(String packageName) {
3542        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3543        synchronized (this) {
3544            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3545        }
3546    }
3547
3548    @Override
3549    public void setPackageScreenCompatMode(String packageName, int mode) {
3550        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3551                "setPackageScreenCompatMode");
3552        synchronized (this) {
3553            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3554        }
3555    }
3556
3557    @Override
3558    public boolean getPackageAskScreenCompat(String packageName) {
3559        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3560        synchronized (this) {
3561            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3562        }
3563    }
3564
3565    @Override
3566    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3567        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3568                "setPackageAskScreenCompat");
3569        synchronized (this) {
3570            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3571        }
3572    }
3573
3574    @Override
3575    public int getPackageProcessState(String packageName) {
3576        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3577        synchronized (this) {
3578            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3579                final ProcessRecord proc = mLruProcesses.get(i);
3580                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3581                        || procState > proc.setProcState) {
3582                    boolean found = false;
3583                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3584                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3585                            procState = proc.setProcState;
3586                            found = true;
3587                        }
3588                    }
3589                    if (proc.pkgDeps != null && !found) {
3590                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3591                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3592                                procState = proc.setProcState;
3593                                break;
3594                            }
3595                        }
3596                    }
3597                }
3598            }
3599        }
3600        return procState;
3601    }
3602
3603    private void dispatchProcessesChanged() {
3604        int N;
3605        synchronized (this) {
3606            N = mPendingProcessChanges.size();
3607            if (mActiveProcessChanges.length < N) {
3608                mActiveProcessChanges = new ProcessChangeItem[N];
3609            }
3610            mPendingProcessChanges.toArray(mActiveProcessChanges);
3611            mPendingProcessChanges.clear();
3612            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3613                    "*** Delivering " + N + " process changes");
3614        }
3615
3616        int i = mProcessObservers.beginBroadcast();
3617        while (i > 0) {
3618            i--;
3619            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3620            if (observer != null) {
3621                try {
3622                    for (int j=0; j<N; j++) {
3623                        ProcessChangeItem item = mActiveProcessChanges[j];
3624                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3625                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3626                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3627                                    + item.uid + ": " + item.foregroundActivities);
3628                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3629                                    item.foregroundActivities);
3630                        }
3631                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3632                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3633                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3634                                    + ": " + item.processState);
3635                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3636                        }
3637                    }
3638                } catch (RemoteException e) {
3639                }
3640            }
3641        }
3642        mProcessObservers.finishBroadcast();
3643
3644        synchronized (this) {
3645            for (int j=0; j<N; j++) {
3646                mAvailProcessChanges.add(mActiveProcessChanges[j]);
3647            }
3648        }
3649    }
3650
3651    private void dispatchProcessDied(int pid, int uid) {
3652        int i = mProcessObservers.beginBroadcast();
3653        while (i > 0) {
3654            i--;
3655            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3656            if (observer != null) {
3657                try {
3658                    observer.onProcessDied(pid, uid);
3659                } catch (RemoteException e) {
3660                }
3661            }
3662        }
3663        mProcessObservers.finishBroadcast();
3664    }
3665
3666    private void dispatchUidsChanged() {
3667        int N;
3668        synchronized (this) {
3669            N = mPendingUidChanges.size();
3670            if (mActiveUidChanges.length < N) {
3671                mActiveUidChanges = new UidRecord.ChangeItem[N];
3672            }
3673            for (int i=0; i<N; i++) {
3674                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3675                mActiveUidChanges[i] = change;
3676                change.uidRecord.pendingChange = null;
3677                change.uidRecord = null;
3678            }
3679            mPendingUidChanges.clear();
3680            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3681                    "*** Delivering " + N + " uid changes");
3682        }
3683
3684        if (mLocalPowerManager != null) {
3685            for (int j=0; j<N; j++) {
3686                UidRecord.ChangeItem item = mActiveUidChanges[j];
3687                if (item.gone) {
3688                    mLocalPowerManager.uidGone(item.uid);
3689                } else {
3690                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
3691                }
3692            }
3693        }
3694
3695        int i = mUidObservers.beginBroadcast();
3696        while (i > 0) {
3697            i--;
3698            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
3699            if (observer != null) {
3700                try {
3701                    for (int j=0; j<N; j++) {
3702                        UidRecord.ChangeItem item = mActiveUidChanges[j];
3703                        if (item.gone) {
3704                            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3705                                    "UID gone uid=" + item.uid);
3706                            observer.onUidGone(item.uid);
3707                        } else {
3708                            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3709                                    "UID CHANGED uid=" + item.uid
3710                                    + ": " + item.processState);
3711                            observer.onUidStateChanged(item.uid, item.processState);
3712                        }
3713                    }
3714                } catch (RemoteException e) {
3715                }
3716            }
3717        }
3718        mUidObservers.finishBroadcast();
3719
3720        synchronized (this) {
3721            for (int j=0; j<N; j++) {
3722                mAvailUidChanges.add(mActiveUidChanges[j]);
3723            }
3724        }
3725    }
3726
3727    @Override
3728    public final int startActivity(IApplicationThread caller, String callingPackage,
3729            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3730            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3731        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3732            resultWho, requestCode, startFlags, profilerInfo, options,
3733            UserHandle.getCallingUserId());
3734    }
3735
3736    @Override
3737    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3738            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3739            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3740        enforceNotIsolatedCaller("startActivity");
3741        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3742                false, ALLOW_FULL_ONLY, "startActivity", null);
3743        // TODO: Switch to user app stacks here.
3744        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3745                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3746                profilerInfo, null, null, options, userId, null, null);
3747    }
3748
3749    @Override
3750    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3751            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3752            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3753
3754        // This is very dangerous -- it allows you to perform a start activity (including
3755        // permission grants) as any app that may launch one of your own activities.  So
3756        // we will only allow this to be done from activities that are part of the core framework,
3757        // and then only when they are running as the system.
3758        final ActivityRecord sourceRecord;
3759        final int targetUid;
3760        final String targetPackage;
3761        synchronized (this) {
3762            if (resultTo == null) {
3763                throw new SecurityException("Must be called from an activity");
3764            }
3765            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3766            if (sourceRecord == null) {
3767                throw new SecurityException("Called with bad activity token: " + resultTo);
3768            }
3769            if (!sourceRecord.info.packageName.equals("android")) {
3770                throw new SecurityException(
3771                        "Must be called from an activity that is declared in the android package");
3772            }
3773            if (sourceRecord.app == null) {
3774                throw new SecurityException("Called without a process attached to activity");
3775            }
3776            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3777                // This is still okay, as long as this activity is running under the
3778                // uid of the original calling activity.
3779                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3780                    throw new SecurityException(
3781                            "Calling activity in uid " + sourceRecord.app.uid
3782                                    + " must be system uid or original calling uid "
3783                                    + sourceRecord.launchedFromUid);
3784                }
3785            }
3786            targetUid = sourceRecord.launchedFromUid;
3787            targetPackage = sourceRecord.launchedFromPackage;
3788        }
3789
3790        if (userId == UserHandle.USER_NULL) {
3791            userId = UserHandle.getUserId(sourceRecord.app.uid);
3792        }
3793
3794        // TODO: Switch to user app stacks here.
3795        try {
3796            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3797                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3798                    null, null, options, userId, null, null);
3799            return ret;
3800        } catch (SecurityException e) {
3801            // XXX need to figure out how to propagate to original app.
3802            // A SecurityException here is generally actually a fault of the original
3803            // calling activity (such as a fairly granting permissions), so propagate it
3804            // back to them.
3805            /*
3806            StringBuilder msg = new StringBuilder();
3807            msg.append("While launching");
3808            msg.append(intent.toString());
3809            msg.append(": ");
3810            msg.append(e.getMessage());
3811            */
3812            throw e;
3813        }
3814    }
3815
3816    @Override
3817    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3818            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3819            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3820        enforceNotIsolatedCaller("startActivityAndWait");
3821        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3822                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3823        WaitResult res = new WaitResult();
3824        // TODO: Switch to user app stacks here.
3825        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3826                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3827                options, userId, null, null);
3828        return res;
3829    }
3830
3831    @Override
3832    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3833            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3834            int startFlags, Configuration config, Bundle options, int userId) {
3835        enforceNotIsolatedCaller("startActivityWithConfig");
3836        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3837                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3838        // TODO: Switch to user app stacks here.
3839        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3840                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3841                null, null, config, options, userId, null, null);
3842        return ret;
3843    }
3844
3845    @Override
3846    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
3847            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
3848            int requestCode, int flagsMask, int flagsValues, Bundle options)
3849            throws TransactionTooLargeException {
3850        enforceNotIsolatedCaller("startActivityIntentSender");
3851        // Refuse possible leaked file descriptors
3852        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3853            throw new IllegalArgumentException("File descriptors passed in Intent");
3854        }
3855
3856        IIntentSender sender = intent.getTarget();
3857        if (!(sender instanceof PendingIntentRecord)) {
3858            throw new IllegalArgumentException("Bad PendingIntent object");
3859        }
3860
3861        PendingIntentRecord pir = (PendingIntentRecord)sender;
3862
3863        synchronized (this) {
3864            // If this is coming from the currently resumed activity, it is
3865            // effectively saying that app switches are allowed at this point.
3866            final ActivityStack stack = getFocusedStack();
3867            if (stack.mResumedActivity != null &&
3868                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3869                mAppSwitchesAllowedTime = 0;
3870            }
3871        }
3872        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3873                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3874        return ret;
3875    }
3876
3877    @Override
3878    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3879            Intent intent, String resolvedType, IVoiceInteractionSession session,
3880            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3881            Bundle options, int userId) {
3882        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3883                != PackageManager.PERMISSION_GRANTED) {
3884            String msg = "Permission Denial: startVoiceActivity() from pid="
3885                    + Binder.getCallingPid()
3886                    + ", uid=" + Binder.getCallingUid()
3887                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3888            Slog.w(TAG, msg);
3889            throw new SecurityException(msg);
3890        }
3891        if (session == null || interactor == null) {
3892            throw new NullPointerException("null session or interactor");
3893        }
3894        userId = handleIncomingUser(callingPid, callingUid, userId,
3895                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3896        // TODO: Switch to user app stacks here.
3897        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3898                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3899                null, options, userId, null, null);
3900    }
3901
3902    @Override
3903    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
3904        synchronized (this) {
3905            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
3906                if (keepAwake) {
3907                    mVoiceWakeLock.acquire();
3908                } else {
3909                    mVoiceWakeLock.release();
3910                }
3911            }
3912        }
3913    }
3914
3915    @Override
3916    public boolean startNextMatchingActivity(IBinder callingActivity,
3917            Intent intent, Bundle options) {
3918        // Refuse possible leaked file descriptors
3919        if (intent != null && intent.hasFileDescriptors() == true) {
3920            throw new IllegalArgumentException("File descriptors passed in Intent");
3921        }
3922
3923        synchronized (this) {
3924            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3925            if (r == null) {
3926                ActivityOptions.abort(options);
3927                return false;
3928            }
3929            if (r.app == null || r.app.thread == null) {
3930                // The caller is not running...  d'oh!
3931                ActivityOptions.abort(options);
3932                return false;
3933            }
3934            intent = new Intent(intent);
3935            // The caller is not allowed to change the data.
3936            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3937            // And we are resetting to find the next component...
3938            intent.setComponent(null);
3939
3940            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3941
3942            ActivityInfo aInfo = null;
3943            try {
3944                List<ResolveInfo> resolves =
3945                    AppGlobals.getPackageManager().queryIntentActivities(
3946                            intent, r.resolvedType,
3947                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3948                            UserHandle.getCallingUserId());
3949
3950                // Look for the original activity in the list...
3951                final int N = resolves != null ? resolves.size() : 0;
3952                for (int i=0; i<N; i++) {
3953                    ResolveInfo rInfo = resolves.get(i);
3954                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3955                            && rInfo.activityInfo.name.equals(r.info.name)) {
3956                        // We found the current one...  the next matching is
3957                        // after it.
3958                        i++;
3959                        if (i<N) {
3960                            aInfo = resolves.get(i).activityInfo;
3961                        }
3962                        if (debug) {
3963                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3964                                    + "/" + r.info.name);
3965                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3966                                    + "/" + aInfo.name);
3967                        }
3968                        break;
3969                    }
3970                }
3971            } catch (RemoteException e) {
3972            }
3973
3974            if (aInfo == null) {
3975                // Nobody who is next!
3976                ActivityOptions.abort(options);
3977                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3978                return false;
3979            }
3980
3981            intent.setComponent(new ComponentName(
3982                    aInfo.applicationInfo.packageName, aInfo.name));
3983            intent.setFlags(intent.getFlags()&~(
3984                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3985                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3986                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3987                    Intent.FLAG_ACTIVITY_NEW_TASK));
3988
3989            // Okay now we need to start the new activity, replacing the
3990            // currently running activity.  This is a little tricky because
3991            // we want to start the new one as if the current one is finished,
3992            // but not finish the current one first so that there is no flicker.
3993            // And thus...
3994            final boolean wasFinishing = r.finishing;
3995            r.finishing = true;
3996
3997            // Propagate reply information over to the new activity.
3998            final ActivityRecord resultTo = r.resultTo;
3999            final String resultWho = r.resultWho;
4000            final int requestCode = r.requestCode;
4001            r.resultTo = null;
4002            if (resultTo != null) {
4003                resultTo.removeResultsLocked(r, resultWho, requestCode);
4004            }
4005
4006            final long origId = Binder.clearCallingIdentity();
4007            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
4008                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
4009                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
4010                    -1, r.launchedFromUid, 0, options, false, null, null, null);
4011            Binder.restoreCallingIdentity(origId);
4012
4013            r.finishing = wasFinishing;
4014            if (res != ActivityManager.START_SUCCESS) {
4015                return false;
4016            }
4017            return true;
4018        }
4019    }
4020
4021    @Override
4022    public final int startActivityFromRecents(int taskId, Bundle options) {
4023        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4024            String msg = "Permission Denial: startActivityFromRecents called without " +
4025                    START_TASKS_FROM_RECENTS;
4026            Slog.w(TAG, msg);
4027            throw new SecurityException(msg);
4028        }
4029        return startActivityFromRecentsInner(taskId, options);
4030    }
4031
4032    final int startActivityFromRecentsInner(int taskId, Bundle options) {
4033        final TaskRecord task;
4034        final int callingUid;
4035        final String callingPackage;
4036        final Intent intent;
4037        final int userId;
4038        synchronized (this) {
4039            task = mRecentTasks.taskForIdLocked(taskId);
4040            if (task == null) {
4041                throw new IllegalArgumentException("Task " + taskId + " not found.");
4042            }
4043            if (task.getRootActivity() != null) {
4044                moveTaskToFrontLocked(task.taskId, 0, null);
4045                return ActivityManager.START_TASK_TO_FRONT;
4046            }
4047            callingUid = task.mCallingUid;
4048            callingPackage = task.mCallingPackage;
4049            intent = task.intent;
4050            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4051            userId = task.userId;
4052        }
4053        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4054                options, userId, null, task);
4055    }
4056
4057    final int startActivityInPackage(int uid, String callingPackage,
4058            Intent intent, String resolvedType, IBinder resultTo,
4059            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
4060            IActivityContainer container, TaskRecord inTask) {
4061
4062        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4063                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4064
4065        // TODO: Switch to user app stacks here.
4066        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
4067                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4068                null, null, null, options, userId, container, inTask);
4069        return ret;
4070    }
4071
4072    @Override
4073    public final int startActivities(IApplicationThread caller, String callingPackage,
4074            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
4075            int userId) {
4076        enforceNotIsolatedCaller("startActivities");
4077        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4078                false, ALLOW_FULL_ONLY, "startActivity", null);
4079        // TODO: Switch to user app stacks here.
4080        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
4081                resolvedTypes, resultTo, options, userId);
4082        return ret;
4083    }
4084
4085    final int startActivitiesInPackage(int uid, String callingPackage,
4086            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4087            Bundle options, int userId) {
4088
4089        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4090                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4091        // TODO: Switch to user app stacks here.
4092        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4093                resultTo, options, userId);
4094        return ret;
4095    }
4096
4097    @Override
4098    public void reportActivityFullyDrawn(IBinder token) {
4099        synchronized (this) {
4100            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4101            if (r == null) {
4102                return;
4103            }
4104            r.reportFullyDrawnLocked();
4105        }
4106    }
4107
4108    @Override
4109    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4110        synchronized (this) {
4111            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4112            if (r == null) {
4113                return;
4114            }
4115            if (r.task != null && r.task.mResizeable) {
4116                // Fixed screen orientation isn't supported with resizeable activities.
4117                return;
4118            }
4119            final long origId = Binder.clearCallingIdentity();
4120            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4121            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4122                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4123            if (config != null) {
4124                r.frozenBeforeDestroy = true;
4125                if (!updateConfigurationLocked(config, r, false)) {
4126                    mStackSupervisor.resumeTopActivitiesLocked();
4127                }
4128            }
4129            Binder.restoreCallingIdentity(origId);
4130        }
4131    }
4132
4133    @Override
4134    public int getRequestedOrientation(IBinder token) {
4135        synchronized (this) {
4136            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4137            if (r == null) {
4138                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4139            }
4140            return mWindowManager.getAppOrientation(r.appToken);
4141        }
4142    }
4143
4144    /**
4145     * This is the internal entry point for handling Activity.finish().
4146     *
4147     * @param token The Binder token referencing the Activity we want to finish.
4148     * @param resultCode Result code, if any, from this Activity.
4149     * @param resultData Result data (Intent), if any, from this Activity.
4150     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4151     *            the root Activity in the task.
4152     *
4153     * @return Returns true if the activity successfully finished, or false if it is still running.
4154     */
4155    @Override
4156    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4157            boolean finishTask) {
4158        // Refuse possible leaked file descriptors
4159        if (resultData != null && resultData.hasFileDescriptors() == true) {
4160            throw new IllegalArgumentException("File descriptors passed in Intent");
4161        }
4162
4163        synchronized(this) {
4164            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4165            if (r == null) {
4166                return true;
4167            }
4168            // Keep track of the root activity of the task before we finish it
4169            TaskRecord tr = r.task;
4170            ActivityRecord rootR = tr.getRootActivity();
4171            if (rootR == null) {
4172                Slog.w(TAG, "Finishing task with all activities already finished");
4173            }
4174            // Do not allow task to finish if last task in lockTask mode. Launchable apps can
4175            // finish themselves.
4176            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE && rootR == r &&
4177                    mStackSupervisor.isLastLockedTask(tr)) {
4178                Slog.i(TAG, "Not finishing task in lock task mode");
4179                mStackSupervisor.showLockTaskToast();
4180                return false;
4181            }
4182            if (mController != null) {
4183                // Find the first activity that is not finishing.
4184                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4185                if (next != null) {
4186                    // ask watcher if this is allowed
4187                    boolean resumeOK = true;
4188                    try {
4189                        resumeOK = mController.activityResuming(next.packageName);
4190                    } catch (RemoteException e) {
4191                        mController = null;
4192                        Watchdog.getInstance().setActivityController(null);
4193                    }
4194
4195                    if (!resumeOK) {
4196                        Slog.i(TAG, "Not finishing activity because controller resumed");
4197                        return false;
4198                    }
4199                }
4200            }
4201            final long origId = Binder.clearCallingIdentity();
4202            try {
4203                boolean res;
4204                if (finishTask && r == rootR) {
4205                    // If requested, remove the task that is associated to this activity only if it
4206                    // was the root activity in the task. The result code and data is ignored
4207                    // because we don't support returning them across task boundaries.
4208                    res = removeTaskByIdLocked(tr.taskId, false);
4209                    if (!res) {
4210                        Slog.i(TAG, "Removing task failed to finish activity");
4211                    }
4212                } else {
4213                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4214                            resultData, "app-request", true);
4215                    if (!res) {
4216                        Slog.i(TAG, "Failed to finish by app-request");
4217                    }
4218                }
4219                return res;
4220            } finally {
4221                Binder.restoreCallingIdentity(origId);
4222            }
4223        }
4224    }
4225
4226    @Override
4227    public final void finishHeavyWeightApp() {
4228        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4229                != PackageManager.PERMISSION_GRANTED) {
4230            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4231                    + Binder.getCallingPid()
4232                    + ", uid=" + Binder.getCallingUid()
4233                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4234            Slog.w(TAG, msg);
4235            throw new SecurityException(msg);
4236        }
4237
4238        synchronized(this) {
4239            if (mHeavyWeightProcess == null) {
4240                return;
4241            }
4242
4243            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4244            for (int i = 0; i < activities.size(); i++) {
4245                ActivityRecord r = activities.get(i);
4246                if (!r.finishing && r.isInStackLocked()) {
4247                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4248                            null, "finish-heavy", true);
4249                }
4250            }
4251
4252            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4253                    mHeavyWeightProcess.userId, 0));
4254            mHeavyWeightProcess = null;
4255        }
4256    }
4257
4258    @Override
4259    public void crashApplication(int uid, int initialPid, String packageName,
4260            String message) {
4261        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4262                != PackageManager.PERMISSION_GRANTED) {
4263            String msg = "Permission Denial: crashApplication() from pid="
4264                    + Binder.getCallingPid()
4265                    + ", uid=" + Binder.getCallingUid()
4266                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4267            Slog.w(TAG, msg);
4268            throw new SecurityException(msg);
4269        }
4270
4271        synchronized(this) {
4272            ProcessRecord proc = null;
4273
4274            // Figure out which process to kill.  We don't trust that initialPid
4275            // still has any relation to current pids, so must scan through the
4276            // list.
4277            synchronized (mPidsSelfLocked) {
4278                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4279                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4280                    if (p.uid != uid) {
4281                        continue;
4282                    }
4283                    if (p.pid == initialPid) {
4284                        proc = p;
4285                        break;
4286                    }
4287                    if (p.pkgList.containsKey(packageName)) {
4288                        proc = p;
4289                    }
4290                }
4291            }
4292
4293            if (proc == null) {
4294                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4295                        + " initialPid=" + initialPid
4296                        + " packageName=" + packageName);
4297                return;
4298            }
4299
4300            if (proc.thread != null) {
4301                if (proc.pid == Process.myPid()) {
4302                    Log.w(TAG, "crashApplication: trying to crash self!");
4303                    return;
4304                }
4305                long ident = Binder.clearCallingIdentity();
4306                try {
4307                    proc.thread.scheduleCrash(message);
4308                } catch (RemoteException e) {
4309                }
4310                Binder.restoreCallingIdentity(ident);
4311            }
4312        }
4313    }
4314
4315    @Override
4316    public final void finishSubActivity(IBinder token, String resultWho,
4317            int requestCode) {
4318        synchronized(this) {
4319            final long origId = Binder.clearCallingIdentity();
4320            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4321            if (r != null) {
4322                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4323            }
4324            Binder.restoreCallingIdentity(origId);
4325        }
4326    }
4327
4328    @Override
4329    public boolean finishActivityAffinity(IBinder token) {
4330        synchronized(this) {
4331            final long origId = Binder.clearCallingIdentity();
4332            try {
4333                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4334                if (r == null) {
4335                    return false;
4336                }
4337
4338                // Do not allow the last non-launchable task to finish in Lock Task mode.
4339                final TaskRecord task = r.task;
4340                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE &&
4341                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4342                    mStackSupervisor.showLockTaskToast();
4343                    return false;
4344                }
4345                return task.stack.finishActivityAffinityLocked(r);
4346            } finally {
4347                Binder.restoreCallingIdentity(origId);
4348            }
4349        }
4350    }
4351
4352    @Override
4353    public void finishVoiceTask(IVoiceInteractionSession session) {
4354        synchronized(this) {
4355            final long origId = Binder.clearCallingIdentity();
4356            try {
4357                mStackSupervisor.finishVoiceTask(session);
4358            } finally {
4359                Binder.restoreCallingIdentity(origId);
4360            }
4361        }
4362
4363    }
4364
4365    @Override
4366    public boolean releaseActivityInstance(IBinder token) {
4367        synchronized(this) {
4368            final long origId = Binder.clearCallingIdentity();
4369            try {
4370                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4371                if (r == null) {
4372                    return false;
4373                }
4374                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4375            } finally {
4376                Binder.restoreCallingIdentity(origId);
4377            }
4378        }
4379    }
4380
4381    @Override
4382    public void releaseSomeActivities(IApplicationThread appInt) {
4383        synchronized(this) {
4384            final long origId = Binder.clearCallingIdentity();
4385            try {
4386                ProcessRecord app = getRecordForAppLocked(appInt);
4387                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4388            } finally {
4389                Binder.restoreCallingIdentity(origId);
4390            }
4391        }
4392    }
4393
4394    @Override
4395    public boolean willActivityBeVisible(IBinder token) {
4396        synchronized(this) {
4397            ActivityStack stack = ActivityRecord.getStackLocked(token);
4398            if (stack != null) {
4399                return stack.willActivityBeVisibleLocked(token);
4400            }
4401            return false;
4402        }
4403    }
4404
4405    @Override
4406    public void overridePendingTransition(IBinder token, String packageName,
4407            int enterAnim, int exitAnim) {
4408        synchronized(this) {
4409            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4410            if (self == null) {
4411                return;
4412            }
4413
4414            final long origId = Binder.clearCallingIdentity();
4415
4416            if (self.state == ActivityState.RESUMED
4417                    || self.state == ActivityState.PAUSING) {
4418                mWindowManager.overridePendingAppTransition(packageName,
4419                        enterAnim, exitAnim, null);
4420            }
4421
4422            Binder.restoreCallingIdentity(origId);
4423        }
4424    }
4425
4426    /**
4427     * Main function for removing an existing process from the activity manager
4428     * as a result of that process going away.  Clears out all connections
4429     * to the process.
4430     */
4431    private final void handleAppDiedLocked(ProcessRecord app,
4432            boolean restarting, boolean allowRestart) {
4433        int pid = app.pid;
4434        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4435        if (!kept && !restarting) {
4436            removeLruProcessLocked(app);
4437            if (pid > 0) {
4438                ProcessList.remove(pid);
4439            }
4440        }
4441
4442        if (mProfileProc == app) {
4443            clearProfilerLocked();
4444        }
4445
4446        // Remove this application's activities from active lists.
4447        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4448
4449        app.activities.clear();
4450
4451        if (app.instrumentationClass != null) {
4452            Slog.w(TAG, "Crash of app " + app.processName
4453                  + " running instrumentation " + app.instrumentationClass);
4454            Bundle info = new Bundle();
4455            info.putString("shortMsg", "Process crashed.");
4456            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4457        }
4458
4459        if (!restarting && hasVisibleActivities && !mStackSupervisor.resumeTopActivitiesLocked()) {
4460            // If there was nothing to resume, and we are not already
4461            // restarting this process, but there is a visible activity that
4462            // is hosted by the process...  then make sure all visible
4463            // activities are running, taking care of restarting this
4464            // process.
4465            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4466        }
4467    }
4468
4469    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4470        IBinder threadBinder = thread.asBinder();
4471        // Find the application record.
4472        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4473            ProcessRecord rec = mLruProcesses.get(i);
4474            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4475                return i;
4476            }
4477        }
4478        return -1;
4479    }
4480
4481    final ProcessRecord getRecordForAppLocked(
4482            IApplicationThread thread) {
4483        if (thread == null) {
4484            return null;
4485        }
4486
4487        int appIndex = getLRURecordIndexForAppLocked(thread);
4488        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4489    }
4490
4491    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4492        // If there are no longer any background processes running,
4493        // and the app that died was not running instrumentation,
4494        // then tell everyone we are now low on memory.
4495        boolean haveBg = false;
4496        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4497            ProcessRecord rec = mLruProcesses.get(i);
4498            if (rec.thread != null
4499                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4500                haveBg = true;
4501                break;
4502            }
4503        }
4504
4505        if (!haveBg) {
4506            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4507            if (doReport) {
4508                long now = SystemClock.uptimeMillis();
4509                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4510                    doReport = false;
4511                } else {
4512                    mLastMemUsageReportTime = now;
4513                }
4514            }
4515            final ArrayList<ProcessMemInfo> memInfos
4516                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4517            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4518            long now = SystemClock.uptimeMillis();
4519            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4520                ProcessRecord rec = mLruProcesses.get(i);
4521                if (rec == dyingProc || rec.thread == null) {
4522                    continue;
4523                }
4524                if (doReport) {
4525                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4526                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4527                }
4528                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4529                    // The low memory report is overriding any current
4530                    // state for a GC request.  Make sure to do
4531                    // heavy/important/visible/foreground processes first.
4532                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4533                        rec.lastRequestedGc = 0;
4534                    } else {
4535                        rec.lastRequestedGc = rec.lastLowMemory;
4536                    }
4537                    rec.reportLowMemory = true;
4538                    rec.lastLowMemory = now;
4539                    mProcessesToGc.remove(rec);
4540                    addProcessToGcListLocked(rec);
4541                }
4542            }
4543            if (doReport) {
4544                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4545                mHandler.sendMessage(msg);
4546            }
4547            scheduleAppGcsLocked();
4548        }
4549    }
4550
4551    final void appDiedLocked(ProcessRecord app) {
4552       appDiedLocked(app, app.pid, app.thread, false);
4553    }
4554
4555    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4556            boolean fromBinderDied) {
4557        // First check if this ProcessRecord is actually active for the pid.
4558        synchronized (mPidsSelfLocked) {
4559            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4560            if (curProc != app) {
4561                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4562                return;
4563            }
4564        }
4565
4566        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4567        synchronized (stats) {
4568            stats.noteProcessDiedLocked(app.info.uid, pid);
4569        }
4570
4571        if (!app.killed) {
4572            if (!fromBinderDied) {
4573                Process.killProcessQuiet(pid);
4574            }
4575            Process.killProcessGroup(app.info.uid, pid);
4576            app.killed = true;
4577        }
4578
4579        // Clean up already done if the process has been re-started.
4580        if (app.pid == pid && app.thread != null &&
4581                app.thread.asBinder() == thread.asBinder()) {
4582            boolean doLowMem = app.instrumentationClass == null;
4583            boolean doOomAdj = doLowMem;
4584            if (!app.killedByAm) {
4585                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4586                        + ") has died");
4587                mAllowLowerMemLevel = true;
4588            } else {
4589                // Note that we always want to do oom adj to update our state with the
4590                // new number of procs.
4591                mAllowLowerMemLevel = false;
4592                doLowMem = false;
4593            }
4594            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4595            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4596                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
4597            handleAppDiedLocked(app, false, true);
4598
4599            if (doOomAdj) {
4600                updateOomAdjLocked();
4601            }
4602            if (doLowMem) {
4603                doLowMemReportIfNeededLocked(app);
4604            }
4605        } else if (app.pid != pid) {
4606            // A new process has already been started.
4607            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4608                    + ") has died and restarted (pid " + app.pid + ").");
4609            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4610        } else if (DEBUG_PROCESSES) {
4611            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
4612                    + thread.asBinder());
4613        }
4614    }
4615
4616    /**
4617     * If a stack trace dump file is configured, dump process stack traces.
4618     * @param clearTraces causes the dump file to be erased prior to the new
4619     *    traces being written, if true; when false, the new traces will be
4620     *    appended to any existing file content.
4621     * @param firstPids of dalvik VM processes to dump stack traces for first
4622     * @param lastPids of dalvik VM processes to dump stack traces for last
4623     * @param nativeProcs optional list of native process names to dump stack crawls
4624     * @return file containing stack traces, or null if no dump file is configured
4625     */
4626    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4627            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4628        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4629        if (tracesPath == null || tracesPath.length() == 0) {
4630            return null;
4631        }
4632
4633        File tracesFile = new File(tracesPath);
4634        try {
4635            File tracesDir = tracesFile.getParentFile();
4636            if (!tracesDir.exists()) {
4637                tracesDir.mkdirs();
4638                if (!SELinux.restorecon(tracesDir)) {
4639                    return null;
4640                }
4641            }
4642            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4643
4644            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4645            tracesFile.createNewFile();
4646            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4647        } catch (IOException e) {
4648            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4649            return null;
4650        }
4651
4652        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4653        return tracesFile;
4654    }
4655
4656    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4657            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4658        // Use a FileObserver to detect when traces finish writing.
4659        // The order of traces is considered important to maintain for legibility.
4660        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4661            @Override
4662            public synchronized void onEvent(int event, String path) { notify(); }
4663        };
4664
4665        try {
4666            observer.startWatching();
4667
4668            // First collect all of the stacks of the most important pids.
4669            if (firstPids != null) {
4670                try {
4671                    int num = firstPids.size();
4672                    for (int i = 0; i < num; i++) {
4673                        synchronized (observer) {
4674                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4675                            observer.wait(200);  // Wait for write-close, give up after 200msec
4676                        }
4677                    }
4678                } catch (InterruptedException e) {
4679                    Slog.wtf(TAG, e);
4680                }
4681            }
4682
4683            // Next collect the stacks of the native pids
4684            if (nativeProcs != null) {
4685                int[] pids = Process.getPidsForCommands(nativeProcs);
4686                if (pids != null) {
4687                    for (int pid : pids) {
4688                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4689                    }
4690                }
4691            }
4692
4693            // Lastly, measure CPU usage.
4694            if (processCpuTracker != null) {
4695                processCpuTracker.init();
4696                System.gc();
4697                processCpuTracker.update();
4698                try {
4699                    synchronized (processCpuTracker) {
4700                        processCpuTracker.wait(500); // measure over 1/2 second.
4701                    }
4702                } catch (InterruptedException e) {
4703                }
4704                processCpuTracker.update();
4705
4706                // We'll take the stack crawls of just the top apps using CPU.
4707                final int N = processCpuTracker.countWorkingStats();
4708                int numProcs = 0;
4709                for (int i=0; i<N && numProcs<5; i++) {
4710                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4711                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4712                        numProcs++;
4713                        try {
4714                            synchronized (observer) {
4715                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4716                                observer.wait(200);  // Wait for write-close, give up after 200msec
4717                            }
4718                        } catch (InterruptedException e) {
4719                            Slog.wtf(TAG, e);
4720                        }
4721
4722                    }
4723                }
4724            }
4725        } finally {
4726            observer.stopWatching();
4727        }
4728    }
4729
4730    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4731        if (true || IS_USER_BUILD) {
4732            return;
4733        }
4734        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4735        if (tracesPath == null || tracesPath.length() == 0) {
4736            return;
4737        }
4738
4739        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4740        StrictMode.allowThreadDiskWrites();
4741        try {
4742            final File tracesFile = new File(tracesPath);
4743            final File tracesDir = tracesFile.getParentFile();
4744            final File tracesTmp = new File(tracesDir, "__tmp__");
4745            try {
4746                if (!tracesDir.exists()) {
4747                    tracesDir.mkdirs();
4748                    if (!SELinux.restorecon(tracesDir.getPath())) {
4749                        return;
4750                    }
4751                }
4752                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4753
4754                if (tracesFile.exists()) {
4755                    tracesTmp.delete();
4756                    tracesFile.renameTo(tracesTmp);
4757                }
4758                StringBuilder sb = new StringBuilder();
4759                Time tobj = new Time();
4760                tobj.set(System.currentTimeMillis());
4761                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4762                sb.append(": ");
4763                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4764                sb.append(" since ");
4765                sb.append(msg);
4766                FileOutputStream fos = new FileOutputStream(tracesFile);
4767                fos.write(sb.toString().getBytes());
4768                if (app == null) {
4769                    fos.write("\n*** No application process!".getBytes());
4770                }
4771                fos.close();
4772                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4773            } catch (IOException e) {
4774                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4775                return;
4776            }
4777
4778            if (app != null) {
4779                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4780                firstPids.add(app.pid);
4781                dumpStackTraces(tracesPath, firstPids, null, null, null);
4782            }
4783
4784            File lastTracesFile = null;
4785            File curTracesFile = null;
4786            for (int i=9; i>=0; i--) {
4787                String name = String.format(Locale.US, "slow%02d.txt", i);
4788                curTracesFile = new File(tracesDir, name);
4789                if (curTracesFile.exists()) {
4790                    if (lastTracesFile != null) {
4791                        curTracesFile.renameTo(lastTracesFile);
4792                    } else {
4793                        curTracesFile.delete();
4794                    }
4795                }
4796                lastTracesFile = curTracesFile;
4797            }
4798            tracesFile.renameTo(curTracesFile);
4799            if (tracesTmp.exists()) {
4800                tracesTmp.renameTo(tracesFile);
4801            }
4802        } finally {
4803            StrictMode.setThreadPolicy(oldPolicy);
4804        }
4805    }
4806
4807    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4808            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4809        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4810        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4811
4812        if (mController != null) {
4813            try {
4814                // 0 == continue, -1 = kill process immediately
4815                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4816                if (res < 0 && app.pid != MY_PID) {
4817                    app.kill("anr", true);
4818                }
4819            } catch (RemoteException e) {
4820                mController = null;
4821                Watchdog.getInstance().setActivityController(null);
4822            }
4823        }
4824
4825        long anrTime = SystemClock.uptimeMillis();
4826        if (MONITOR_CPU_USAGE) {
4827            updateCpuStatsNow();
4828        }
4829
4830        synchronized (this) {
4831            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4832            if (mShuttingDown) {
4833                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4834                return;
4835            } else if (app.notResponding) {
4836                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4837                return;
4838            } else if (app.crashing) {
4839                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4840                return;
4841            }
4842
4843            // In case we come through here for the same app before completing
4844            // this one, mark as anring now so we will bail out.
4845            app.notResponding = true;
4846
4847            // Log the ANR to the event log.
4848            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4849                    app.processName, app.info.flags, annotation);
4850
4851            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4852            firstPids.add(app.pid);
4853
4854            int parentPid = app.pid;
4855            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4856            if (parentPid != app.pid) firstPids.add(parentPid);
4857
4858            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4859
4860            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4861                ProcessRecord r = mLruProcesses.get(i);
4862                if (r != null && r.thread != null) {
4863                    int pid = r.pid;
4864                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4865                        if (r.persistent) {
4866                            firstPids.add(pid);
4867                        } else {
4868                            lastPids.put(pid, Boolean.TRUE);
4869                        }
4870                    }
4871                }
4872            }
4873        }
4874
4875        // Log the ANR to the main log.
4876        StringBuilder info = new StringBuilder();
4877        info.setLength(0);
4878        info.append("ANR in ").append(app.processName);
4879        if (activity != null && activity.shortComponentName != null) {
4880            info.append(" (").append(activity.shortComponentName).append(")");
4881        }
4882        info.append("\n");
4883        info.append("PID: ").append(app.pid).append("\n");
4884        if (annotation != null) {
4885            info.append("Reason: ").append(annotation).append("\n");
4886        }
4887        if (parent != null && parent != activity) {
4888            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4889        }
4890
4891        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4892
4893        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4894                NATIVE_STACKS_OF_INTEREST);
4895
4896        String cpuInfo = null;
4897        if (MONITOR_CPU_USAGE) {
4898            updateCpuStatsNow();
4899            synchronized (mProcessCpuTracker) {
4900                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4901            }
4902            info.append(processCpuTracker.printCurrentLoad());
4903            info.append(cpuInfo);
4904        }
4905
4906        info.append(processCpuTracker.printCurrentState(anrTime));
4907
4908        Slog.e(TAG, info.toString());
4909        if (tracesFile == null) {
4910            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4911            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4912        }
4913
4914        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4915                cpuInfo, tracesFile, null);
4916
4917        if (mController != null) {
4918            try {
4919                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4920                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4921                if (res != 0) {
4922                    if (res < 0 && app.pid != MY_PID) {
4923                        app.kill("anr", true);
4924                    } else {
4925                        synchronized (this) {
4926                            mServices.scheduleServiceTimeoutLocked(app);
4927                        }
4928                    }
4929                    return;
4930                }
4931            } catch (RemoteException e) {
4932                mController = null;
4933                Watchdog.getInstance().setActivityController(null);
4934            }
4935        }
4936
4937        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4938        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4939                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4940
4941        synchronized (this) {
4942            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
4943
4944            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4945                app.kill("bg anr", true);
4946                return;
4947            }
4948
4949            // Set the app's notResponding state, and look up the errorReportReceiver
4950            makeAppNotRespondingLocked(app,
4951                    activity != null ? activity.shortComponentName : null,
4952                    annotation != null ? "ANR " + annotation : "ANR",
4953                    info.toString());
4954
4955            // Bring up the infamous App Not Responding dialog
4956            Message msg = Message.obtain();
4957            HashMap<String, Object> map = new HashMap<String, Object>();
4958            msg.what = SHOW_NOT_RESPONDING_MSG;
4959            msg.obj = map;
4960            msg.arg1 = aboveSystem ? 1 : 0;
4961            map.put("app", app);
4962            if (activity != null) {
4963                map.put("activity", activity);
4964            }
4965
4966            mUiHandler.sendMessage(msg);
4967        }
4968    }
4969
4970    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4971        if (!mLaunchWarningShown) {
4972            mLaunchWarningShown = true;
4973            mUiHandler.post(new Runnable() {
4974                @Override
4975                public void run() {
4976                    synchronized (ActivityManagerService.this) {
4977                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4978                        d.show();
4979                        mUiHandler.postDelayed(new Runnable() {
4980                            @Override
4981                            public void run() {
4982                                synchronized (ActivityManagerService.this) {
4983                                    d.dismiss();
4984                                    mLaunchWarningShown = false;
4985                                }
4986                            }
4987                        }, 4000);
4988                    }
4989                }
4990            });
4991        }
4992    }
4993
4994    @Override
4995    public boolean clearApplicationUserData(final String packageName,
4996            final IPackageDataObserver observer, int userId) {
4997        enforceNotIsolatedCaller("clearApplicationUserData");
4998        if (packageName != null && packageName.equals(mDeviceOwnerName)) {
4999            throw new SecurityException("Clearing DeviceOwner data is forbidden.");
5000        }
5001        int uid = Binder.getCallingUid();
5002        int pid = Binder.getCallingPid();
5003        userId = handleIncomingUser(pid, uid,
5004                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5005        long callingId = Binder.clearCallingIdentity();
5006        try {
5007            IPackageManager pm = AppGlobals.getPackageManager();
5008            int pkgUid = -1;
5009            synchronized(this) {
5010                try {
5011                    pkgUid = pm.getPackageUid(packageName, userId);
5012                } catch (RemoteException e) {
5013                }
5014                if (pkgUid == -1) {
5015                    Slog.w(TAG, "Invalid packageName: " + packageName);
5016                    if (observer != null) {
5017                        try {
5018                            observer.onRemoveCompleted(packageName, false);
5019                        } catch (RemoteException e) {
5020                            Slog.i(TAG, "Observer no longer exists.");
5021                        }
5022                    }
5023                    return false;
5024                }
5025                if (uid == pkgUid || checkComponentPermission(
5026                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5027                        pid, uid, -1, true)
5028                        == PackageManager.PERMISSION_GRANTED) {
5029                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5030                } else {
5031                    throw new SecurityException("PID " + pid + " does not have permission "
5032                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5033                                    + " of package " + packageName);
5034                }
5035
5036                // Remove all tasks match the cleared application package and user
5037                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5038                    final TaskRecord tr = mRecentTasks.get(i);
5039                    final String taskPackageName =
5040                            tr.getBaseIntent().getComponent().getPackageName();
5041                    if (tr.userId != userId) continue;
5042                    if (!taskPackageName.equals(packageName)) continue;
5043                    removeTaskByIdLocked(tr.taskId, false);
5044                }
5045            }
5046
5047            try {
5048                // Clear application user data
5049                pm.clearApplicationUserData(packageName, observer, userId);
5050
5051                synchronized(this) {
5052                    // Remove all permissions granted from/to this package
5053                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5054                }
5055
5056                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5057                        Uri.fromParts("package", packageName, null));
5058                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5059                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5060                        null, null, 0, null, null, null, false, false, userId);
5061            } catch (RemoteException e) {
5062            }
5063        } finally {
5064            Binder.restoreCallingIdentity(callingId);
5065        }
5066        return true;
5067    }
5068
5069    @Override
5070    public void killBackgroundProcesses(final String packageName, int userId) {
5071        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5072                != PackageManager.PERMISSION_GRANTED &&
5073                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5074                        != PackageManager.PERMISSION_GRANTED) {
5075            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5076                    + Binder.getCallingPid()
5077                    + ", uid=" + Binder.getCallingUid()
5078                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5079            Slog.w(TAG, msg);
5080            throw new SecurityException(msg);
5081        }
5082
5083        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5084                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5085        long callingId = Binder.clearCallingIdentity();
5086        try {
5087            IPackageManager pm = AppGlobals.getPackageManager();
5088            synchronized(this) {
5089                int appId = -1;
5090                try {
5091                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5092                } catch (RemoteException e) {
5093                }
5094                if (appId == -1) {
5095                    Slog.w(TAG, "Invalid packageName: " + packageName);
5096                    return;
5097                }
5098                killPackageProcessesLocked(packageName, appId, userId,
5099                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5100            }
5101        } finally {
5102            Binder.restoreCallingIdentity(callingId);
5103        }
5104    }
5105
5106    @Override
5107    public void killAllBackgroundProcesses() {
5108        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5109                != PackageManager.PERMISSION_GRANTED) {
5110            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5111                    + Binder.getCallingPid()
5112                    + ", uid=" + Binder.getCallingUid()
5113                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5114            Slog.w(TAG, msg);
5115            throw new SecurityException(msg);
5116        }
5117
5118        long callingId = Binder.clearCallingIdentity();
5119        try {
5120            synchronized(this) {
5121                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5122                final int NP = mProcessNames.getMap().size();
5123                for (int ip=0; ip<NP; ip++) {
5124                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5125                    final int NA = apps.size();
5126                    for (int ia=0; ia<NA; ia++) {
5127                        ProcessRecord app = apps.valueAt(ia);
5128                        if (app.persistent) {
5129                            // we don't kill persistent processes
5130                            continue;
5131                        }
5132                        if (app.removed) {
5133                            procs.add(app);
5134                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5135                            app.removed = true;
5136                            procs.add(app);
5137                        }
5138                    }
5139                }
5140
5141                int N = procs.size();
5142                for (int i=0; i<N; i++) {
5143                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5144                }
5145                mAllowLowerMemLevel = true;
5146                updateOomAdjLocked();
5147                doLowMemReportIfNeededLocked(null);
5148            }
5149        } finally {
5150            Binder.restoreCallingIdentity(callingId);
5151        }
5152    }
5153
5154    @Override
5155    public void forceStopPackage(final String packageName, int userId) {
5156        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5157                != PackageManager.PERMISSION_GRANTED) {
5158            String msg = "Permission Denial: forceStopPackage() from pid="
5159                    + Binder.getCallingPid()
5160                    + ", uid=" + Binder.getCallingUid()
5161                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5162            Slog.w(TAG, msg);
5163            throw new SecurityException(msg);
5164        }
5165        final int callingPid = Binder.getCallingPid();
5166        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5167                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5168        long callingId = Binder.clearCallingIdentity();
5169        try {
5170            IPackageManager pm = AppGlobals.getPackageManager();
5171            synchronized(this) {
5172                int[] users = userId == UserHandle.USER_ALL
5173                        ? getUsersLocked() : new int[] { userId };
5174                for (int user : users) {
5175                    int pkgUid = -1;
5176                    try {
5177                        pkgUid = pm.getPackageUid(packageName, user);
5178                    } catch (RemoteException e) {
5179                    }
5180                    if (pkgUid == -1) {
5181                        Slog.w(TAG, "Invalid packageName: " + packageName);
5182                        continue;
5183                    }
5184                    try {
5185                        pm.setPackageStoppedState(packageName, true, user);
5186                    } catch (RemoteException e) {
5187                    } catch (IllegalArgumentException e) {
5188                        Slog.w(TAG, "Failed trying to unstop package "
5189                                + packageName + ": " + e);
5190                    }
5191                    if (isUserRunningLocked(user, false)) {
5192                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5193                    }
5194                }
5195            }
5196        } finally {
5197            Binder.restoreCallingIdentity(callingId);
5198        }
5199    }
5200
5201    @Override
5202    public void addPackageDependency(String packageName) {
5203        synchronized (this) {
5204            int callingPid = Binder.getCallingPid();
5205            if (callingPid == Process.myPid()) {
5206                //  Yeah, um, no.
5207                return;
5208            }
5209            ProcessRecord proc;
5210            synchronized (mPidsSelfLocked) {
5211                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5212            }
5213            if (proc != null) {
5214                if (proc.pkgDeps == null) {
5215                    proc.pkgDeps = new ArraySet<String>(1);
5216                }
5217                proc.pkgDeps.add(packageName);
5218            }
5219        }
5220    }
5221
5222    /*
5223     * The pkg name and app id have to be specified.
5224     */
5225    @Override
5226    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5227        if (pkg == null) {
5228            return;
5229        }
5230        // Make sure the uid is valid.
5231        if (appid < 0) {
5232            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5233            return;
5234        }
5235        int callerUid = Binder.getCallingUid();
5236        // Only the system server can kill an application
5237        if (callerUid == Process.SYSTEM_UID) {
5238            // Post an aysnc message to kill the application
5239            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5240            msg.arg1 = appid;
5241            msg.arg2 = 0;
5242            Bundle bundle = new Bundle();
5243            bundle.putString("pkg", pkg);
5244            bundle.putString("reason", reason);
5245            msg.obj = bundle;
5246            mHandler.sendMessage(msg);
5247        } else {
5248            throw new SecurityException(callerUid + " cannot kill pkg: " +
5249                    pkg);
5250        }
5251    }
5252
5253    @Override
5254    public void closeSystemDialogs(String reason) {
5255        enforceNotIsolatedCaller("closeSystemDialogs");
5256
5257        final int pid = Binder.getCallingPid();
5258        final int uid = Binder.getCallingUid();
5259        final long origId = Binder.clearCallingIdentity();
5260        try {
5261            synchronized (this) {
5262                // Only allow this from foreground processes, so that background
5263                // applications can't abuse it to prevent system UI from being shown.
5264                if (uid >= Process.FIRST_APPLICATION_UID) {
5265                    ProcessRecord proc;
5266                    synchronized (mPidsSelfLocked) {
5267                        proc = mPidsSelfLocked.get(pid);
5268                    }
5269                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5270                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5271                                + " from background process " + proc);
5272                        return;
5273                    }
5274                }
5275                closeSystemDialogsLocked(reason);
5276            }
5277        } finally {
5278            Binder.restoreCallingIdentity(origId);
5279        }
5280    }
5281
5282    void closeSystemDialogsLocked(String reason) {
5283        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5284        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5285                | Intent.FLAG_RECEIVER_FOREGROUND);
5286        if (reason != null) {
5287            intent.putExtra("reason", reason);
5288        }
5289        mWindowManager.closeSystemDialogs(reason);
5290
5291        mStackSupervisor.closeSystemDialogsLocked();
5292
5293        broadcastIntentLocked(null, null, intent, null,
5294                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5295                Process.SYSTEM_UID, UserHandle.USER_ALL);
5296    }
5297
5298    @Override
5299    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5300        enforceNotIsolatedCaller("getProcessMemoryInfo");
5301        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5302        for (int i=pids.length-1; i>=0; i--) {
5303            ProcessRecord proc;
5304            int oomAdj;
5305            synchronized (this) {
5306                synchronized (mPidsSelfLocked) {
5307                    proc = mPidsSelfLocked.get(pids[i]);
5308                    oomAdj = proc != null ? proc.setAdj : 0;
5309                }
5310            }
5311            infos[i] = new Debug.MemoryInfo();
5312            Debug.getMemoryInfo(pids[i], infos[i]);
5313            if (proc != null) {
5314                synchronized (this) {
5315                    if (proc.thread != null && proc.setAdj == oomAdj) {
5316                        // Record this for posterity if the process has been stable.
5317                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5318                                infos[i].getTotalUss(), false, proc.pkgList);
5319                    }
5320                }
5321            }
5322        }
5323        return infos;
5324    }
5325
5326    @Override
5327    public long[] getProcessPss(int[] pids) {
5328        enforceNotIsolatedCaller("getProcessPss");
5329        long[] pss = new long[pids.length];
5330        for (int i=pids.length-1; i>=0; i--) {
5331            ProcessRecord proc;
5332            int oomAdj;
5333            synchronized (this) {
5334                synchronized (mPidsSelfLocked) {
5335                    proc = mPidsSelfLocked.get(pids[i]);
5336                    oomAdj = proc != null ? proc.setAdj : 0;
5337                }
5338            }
5339            long[] tmpUss = new long[1];
5340            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5341            if (proc != null) {
5342                synchronized (this) {
5343                    if (proc.thread != null && proc.setAdj == oomAdj) {
5344                        // Record this for posterity if the process has been stable.
5345                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5346                    }
5347                }
5348            }
5349        }
5350        return pss;
5351    }
5352
5353    @Override
5354    public void killApplicationProcess(String processName, int uid) {
5355        if (processName == null) {
5356            return;
5357        }
5358
5359        int callerUid = Binder.getCallingUid();
5360        // Only the system server can kill an application
5361        if (callerUid == Process.SYSTEM_UID) {
5362            synchronized (this) {
5363                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5364                if (app != null && app.thread != null) {
5365                    try {
5366                        app.thread.scheduleSuicide();
5367                    } catch (RemoteException e) {
5368                        // If the other end already died, then our work here is done.
5369                    }
5370                } else {
5371                    Slog.w(TAG, "Process/uid not found attempting kill of "
5372                            + processName + " / " + uid);
5373                }
5374            }
5375        } else {
5376            throw new SecurityException(callerUid + " cannot kill app process: " +
5377                    processName);
5378        }
5379    }
5380
5381    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5382        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5383                false, true, false, false, UserHandle.getUserId(uid), reason);
5384        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5385                Uri.fromParts("package", packageName, null));
5386        if (!mProcessesReady) {
5387            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5388                    | Intent.FLAG_RECEIVER_FOREGROUND);
5389        }
5390        intent.putExtra(Intent.EXTRA_UID, uid);
5391        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5392        broadcastIntentLocked(null, null, intent,
5393                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5394                false, false,
5395                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5396    }
5397
5398    private void forceStopUserLocked(int userId, String reason) {
5399        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5400        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5401        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5402                | Intent.FLAG_RECEIVER_FOREGROUND);
5403        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5404        broadcastIntentLocked(null, null, intent,
5405                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5406                false, false,
5407                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5408    }
5409
5410    private final boolean killPackageProcessesLocked(String packageName, int appId,
5411            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5412            boolean doit, boolean evenPersistent, String reason) {
5413        ArrayList<ProcessRecord> procs = new ArrayList<>();
5414
5415        // Remove all processes this package may have touched: all with the
5416        // same UID (except for the system or root user), and all whose name
5417        // matches the package name.
5418        final int NP = mProcessNames.getMap().size();
5419        for (int ip=0; ip<NP; ip++) {
5420            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5421            final int NA = apps.size();
5422            for (int ia=0; ia<NA; ia++) {
5423                ProcessRecord app = apps.valueAt(ia);
5424                if (app.persistent && !evenPersistent) {
5425                    // we don't kill persistent processes
5426                    continue;
5427                }
5428                if (app.removed) {
5429                    if (doit) {
5430                        procs.add(app);
5431                    }
5432                    continue;
5433                }
5434
5435                // Skip process if it doesn't meet our oom adj requirement.
5436                if (app.setAdj < minOomAdj) {
5437                    continue;
5438                }
5439
5440                // If no package is specified, we call all processes under the
5441                // give user id.
5442                if (packageName == null) {
5443                    if (app.userId != userId) {
5444                        continue;
5445                    }
5446                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5447                        continue;
5448                    }
5449                // Package has been specified, we want to hit all processes
5450                // that match it.  We need to qualify this by the processes
5451                // that are running under the specified app and user ID.
5452                } else {
5453                    final boolean isDep = app.pkgDeps != null
5454                            && app.pkgDeps.contains(packageName);
5455                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5456                        continue;
5457                    }
5458                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5459                        continue;
5460                    }
5461                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5462                        continue;
5463                    }
5464                }
5465
5466                // Process has passed all conditions, kill it!
5467                if (!doit) {
5468                    return true;
5469                }
5470                app.removed = true;
5471                procs.add(app);
5472            }
5473        }
5474
5475        int N = procs.size();
5476        for (int i=0; i<N; i++) {
5477            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5478        }
5479        updateOomAdjLocked();
5480        return N > 0;
5481    }
5482
5483    private void cleanupDisabledPackageComponentsLocked(
5484            String packageName, int userId, String[] changedClasses) {
5485
5486        Set<String> disabledClasses = null;
5487        boolean packageDisabled = false;
5488        IPackageManager pm = AppGlobals.getPackageManager();
5489
5490        if (changedClasses == null) {
5491            // Nothing changed...
5492            return;
5493        }
5494
5495        // Determine enable/disable state of the package and its components.
5496        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5497        for (int i = changedClasses.length - 1; i >= 0; i--) {
5498            final String changedClass = changedClasses[i];
5499
5500            if (changedClass.equals(packageName)) {
5501                try {
5502                    // Entire package setting changed
5503                    enabled = pm.getApplicationEnabledSetting(packageName,
5504                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5505                } catch (RemoteException e) {
5506                    // Can't happen...
5507                }
5508                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5509                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5510                if (packageDisabled) {
5511                    // Entire package is disabled.
5512                    // No need to continue to check component states.
5513                    disabledClasses = null;
5514                    break;
5515                }
5516            } else {
5517                try {
5518                    enabled = pm.getComponentEnabledSetting(
5519                            new ComponentName(packageName, changedClass),
5520                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5521                } catch (RemoteException e) {
5522                    // Can't happen...
5523                }
5524                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5525                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5526                    if (disabledClasses == null) {
5527                        disabledClasses = new ArraySet<>(changedClasses.length);
5528                    }
5529                    disabledClasses.add(changedClass);
5530                }
5531            }
5532        }
5533
5534        if (!packageDisabled && disabledClasses == null) {
5535            // Nothing to do here...
5536            return;
5537        }
5538
5539        // Clean-up disabled activities.
5540        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5541                packageName, disabledClasses, true, false, userId) && mBooted) {
5542            mStackSupervisor.resumeTopActivitiesLocked();
5543            mStackSupervisor.scheduleIdleLocked();
5544        }
5545
5546        // Clean-up disabled tasks
5547        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5548
5549        // Clean-up disabled services.
5550        mServices.bringDownDisabledPackageServicesLocked(
5551                packageName, disabledClasses, userId, false, true);
5552
5553        // Clean-up disabled providers.
5554        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5555        mProviderMap.collectPackageProvidersLocked(
5556                packageName, disabledClasses, true, false, userId, providers);
5557        for (int i = providers.size() - 1; i >= 0; i--) {
5558            removeDyingProviderLocked(null, providers.get(i), true);
5559        }
5560
5561        // Clean-up disabled broadcast receivers.
5562        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5563            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5564                    packageName, disabledClasses, userId, true);
5565        }
5566
5567    }
5568
5569    private final boolean forceStopPackageLocked(String packageName, int appId,
5570            boolean callerWillRestart, boolean purgeCache, boolean doit,
5571            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5572        int i;
5573
5574        if (userId == UserHandle.USER_ALL && packageName == null) {
5575            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5576        }
5577
5578        if (appId < 0 && packageName != null) {
5579            try {
5580                appId = UserHandle.getAppId(
5581                        AppGlobals.getPackageManager().getPackageUid(packageName, 0));
5582            } catch (RemoteException e) {
5583            }
5584        }
5585
5586        if (doit) {
5587            if (packageName != null) {
5588                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5589                        + " user=" + userId + ": " + reason);
5590            } else {
5591                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5592            }
5593
5594            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5595            for (int ip = pmap.size() - 1; ip >= 0; ip--) {
5596                SparseArray<Long> ba = pmap.valueAt(ip);
5597                for (i = ba.size() - 1; i >= 0; i--) {
5598                    boolean remove = false;
5599                    final int entUid = ba.keyAt(i);
5600                    if (packageName != null) {
5601                        if (userId == UserHandle.USER_ALL) {
5602                            if (UserHandle.getAppId(entUid) == appId) {
5603                                remove = true;
5604                            }
5605                        } else {
5606                            if (entUid == UserHandle.getUid(userId, appId)) {
5607                                remove = true;
5608                            }
5609                        }
5610                    } else if (UserHandle.getUserId(entUid) == userId) {
5611                        remove = true;
5612                    }
5613                    if (remove) {
5614                        ba.removeAt(i);
5615                    }
5616                }
5617                if (ba.size() == 0) {
5618                    pmap.removeAt(ip);
5619                }
5620            }
5621        }
5622
5623        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5624                -100, callerWillRestart, true, doit, evenPersistent,
5625                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5626
5627        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5628                packageName, null, doit, evenPersistent, userId)) {
5629            if (!doit) {
5630                return true;
5631            }
5632            didSomething = true;
5633        }
5634
5635        if (mServices.bringDownDisabledPackageServicesLocked(
5636                packageName, null, userId, evenPersistent, doit)) {
5637            if (!doit) {
5638                return true;
5639            }
5640            didSomething = true;
5641        }
5642
5643        if (packageName == null) {
5644            // Remove all sticky broadcasts from this user.
5645            mStickyBroadcasts.remove(userId);
5646        }
5647
5648        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5649        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5650                userId, providers)) {
5651            if (!doit) {
5652                return true;
5653            }
5654            didSomething = true;
5655        }
5656        for (i = providers.size() - 1; i >= 0; i--) {
5657            removeDyingProviderLocked(null, providers.get(i), true);
5658        }
5659
5660        // Remove transient permissions granted from/to this package/user
5661        removeUriPermissionsForPackageLocked(packageName, userId, false);
5662
5663        if (doit) {
5664            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
5665                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5666                        packageName, null, userId, doit);
5667            }
5668        }
5669
5670        if (packageName == null || uninstalling) {
5671            // Remove pending intents.  For now we only do this when force
5672            // stopping users, because we have some problems when doing this
5673            // for packages -- app widgets are not currently cleaned up for
5674            // such packages, so they can be left with bad pending intents.
5675            if (mIntentSenderRecords.size() > 0) {
5676                Iterator<WeakReference<PendingIntentRecord>> it
5677                        = mIntentSenderRecords.values().iterator();
5678                while (it.hasNext()) {
5679                    WeakReference<PendingIntentRecord> wpir = it.next();
5680                    if (wpir == null) {
5681                        it.remove();
5682                        continue;
5683                    }
5684                    PendingIntentRecord pir = wpir.get();
5685                    if (pir == null) {
5686                        it.remove();
5687                        continue;
5688                    }
5689                    if (packageName == null) {
5690                        // Stopping user, remove all objects for the user.
5691                        if (pir.key.userId != userId) {
5692                            // Not the same user, skip it.
5693                            continue;
5694                        }
5695                    } else {
5696                        if (UserHandle.getAppId(pir.uid) != appId) {
5697                            // Different app id, skip it.
5698                            continue;
5699                        }
5700                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5701                            // Different user, skip it.
5702                            continue;
5703                        }
5704                        if (!pir.key.packageName.equals(packageName)) {
5705                            // Different package, skip it.
5706                            continue;
5707                        }
5708                    }
5709                    if (!doit) {
5710                        return true;
5711                    }
5712                    didSomething = true;
5713                    it.remove();
5714                    pir.canceled = true;
5715                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5716                        pir.key.activity.pendingResults.remove(pir.ref);
5717                    }
5718                }
5719            }
5720        }
5721
5722        if (doit) {
5723            if (purgeCache && packageName != null) {
5724                AttributeCache ac = AttributeCache.instance();
5725                if (ac != null) {
5726                    ac.removePackage(packageName);
5727                }
5728            }
5729            if (mBooted) {
5730                mStackSupervisor.resumeTopActivitiesLocked();
5731                mStackSupervisor.scheduleIdleLocked();
5732            }
5733        }
5734
5735        return didSomething;
5736    }
5737
5738    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
5739        ProcessRecord old = mProcessNames.remove(name, uid);
5740        if (old != null) {
5741            old.uidRecord.numProcs--;
5742            if (old.uidRecord.numProcs == 0) {
5743                // No more processes using this uid, tell clients it is gone.
5744                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5745                        "No more processes in " + old.uidRecord);
5746                enqueueUidChangeLocked(old.uidRecord, true);
5747                mActiveUids.remove(uid);
5748            }
5749            old.uidRecord = null;
5750        }
5751        mIsolatedProcesses.remove(uid);
5752        return old;
5753    }
5754
5755    private final void addProcessNameLocked(ProcessRecord proc) {
5756        // We shouldn't already have a process under this name, but just in case we
5757        // need to clean up whatever may be there now.
5758        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
5759        if (old != null) {
5760            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
5761        }
5762        UidRecord uidRec = mActiveUids.get(proc.uid);
5763        if (uidRec == null) {
5764            uidRec = new UidRecord(proc.uid);
5765            // This is the first appearance of the uid, report it now!
5766            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5767                    "Creating new process uid: " + uidRec);
5768            mActiveUids.put(proc.uid, uidRec);
5769            enqueueUidChangeLocked(uidRec, false);
5770        }
5771        proc.uidRecord = uidRec;
5772        uidRec.numProcs++;
5773        mProcessNames.put(proc.processName, proc.uid, proc);
5774        if (proc.isolated) {
5775            mIsolatedProcesses.put(proc.uid, proc);
5776        }
5777    }
5778
5779    private final boolean removeProcessLocked(ProcessRecord app,
5780            boolean callerWillRestart, boolean allowRestart, String reason) {
5781        final String name = app.processName;
5782        final int uid = app.uid;
5783        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
5784            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
5785
5786        removeProcessNameLocked(name, uid);
5787        if (mHeavyWeightProcess == app) {
5788            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5789                    mHeavyWeightProcess.userId, 0));
5790            mHeavyWeightProcess = null;
5791        }
5792        boolean needRestart = false;
5793        if (app.pid > 0 && app.pid != MY_PID) {
5794            int pid = app.pid;
5795            synchronized (mPidsSelfLocked) {
5796                mPidsSelfLocked.remove(pid);
5797                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5798            }
5799            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5800            if (app.isolated) {
5801                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5802            }
5803            boolean willRestart = false;
5804            if (app.persistent && !app.isolated) {
5805                if (!callerWillRestart) {
5806                    willRestart = true;
5807                } else {
5808                    needRestart = true;
5809                }
5810            }
5811            app.kill(reason, true);
5812            handleAppDiedLocked(app, willRestart, allowRestart);
5813            if (willRestart) {
5814                removeLruProcessLocked(app);
5815                addAppLocked(app.info, false, null /* ABI override */);
5816            }
5817        } else {
5818            mRemovedProcesses.add(app);
5819        }
5820
5821        return needRestart;
5822    }
5823
5824    private final void processStartTimedOutLocked(ProcessRecord app) {
5825        final int pid = app.pid;
5826        boolean gone = false;
5827        synchronized (mPidsSelfLocked) {
5828            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5829            if (knownApp != null && knownApp.thread == null) {
5830                mPidsSelfLocked.remove(pid);
5831                gone = true;
5832            }
5833        }
5834
5835        if (gone) {
5836            Slog.w(TAG, "Process " + app + " failed to attach");
5837            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5838                    pid, app.uid, app.processName);
5839            removeProcessNameLocked(app.processName, app.uid);
5840            if (mHeavyWeightProcess == app) {
5841                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5842                        mHeavyWeightProcess.userId, 0));
5843                mHeavyWeightProcess = null;
5844            }
5845            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5846            if (app.isolated) {
5847                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5848            }
5849            // Take care of any launching providers waiting for this process.
5850            checkAppInLaunchingProvidersLocked(app, true);
5851            // Take care of any services that are waiting for the process.
5852            mServices.processStartTimedOutLocked(app);
5853            app.kill("start timeout", true);
5854            removeLruProcessLocked(app);
5855            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5856                Slog.w(TAG, "Unattached app died before backup, skipping");
5857                try {
5858                    IBackupManager bm = IBackupManager.Stub.asInterface(
5859                            ServiceManager.getService(Context.BACKUP_SERVICE));
5860                    bm.agentDisconnected(app.info.packageName);
5861                } catch (RemoteException e) {
5862                    // Can't happen; the backup manager is local
5863                }
5864            }
5865            if (isPendingBroadcastProcessLocked(pid)) {
5866                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5867                skipPendingBroadcastLocked(pid);
5868            }
5869        } else {
5870            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5871        }
5872    }
5873
5874    private final boolean attachApplicationLocked(IApplicationThread thread,
5875            int pid) {
5876
5877        // Find the application record that is being attached...  either via
5878        // the pid if we are running in multiple processes, or just pull the
5879        // next app record if we are emulating process with anonymous threads.
5880        ProcessRecord app;
5881        if (pid != MY_PID && pid >= 0) {
5882            synchronized (mPidsSelfLocked) {
5883                app = mPidsSelfLocked.get(pid);
5884            }
5885        } else {
5886            app = null;
5887        }
5888
5889        if (app == null) {
5890            Slog.w(TAG, "No pending application record for pid " + pid
5891                    + " (IApplicationThread " + thread + "); dropping process");
5892            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5893            if (pid > 0 && pid != MY_PID) {
5894                Process.killProcessQuiet(pid);
5895                //TODO: Process.killProcessGroup(app.info.uid, pid);
5896            } else {
5897                try {
5898                    thread.scheduleExit();
5899                } catch (Exception e) {
5900                    // Ignore exceptions.
5901                }
5902            }
5903            return false;
5904        }
5905
5906        // If this application record is still attached to a previous
5907        // process, clean it up now.
5908        if (app.thread != null) {
5909            handleAppDiedLocked(app, true, true);
5910        }
5911
5912        // Tell the process all about itself.
5913
5914        if (DEBUG_ALL) Slog.v(
5915                TAG, "Binding process pid " + pid + " to record " + app);
5916
5917        final String processName = app.processName;
5918        try {
5919            AppDeathRecipient adr = new AppDeathRecipient(
5920                    app, pid, thread);
5921            thread.asBinder().linkToDeath(adr, 0);
5922            app.deathRecipient = adr;
5923        } catch (RemoteException e) {
5924            app.resetPackageList(mProcessStats);
5925            startProcessLocked(app, "link fail", processName);
5926            return false;
5927        }
5928
5929        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5930
5931        app.makeActive(thread, mProcessStats);
5932        app.curAdj = app.setAdj = -100;
5933        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5934        app.forcingToForeground = null;
5935        updateProcessForegroundLocked(app, false, false);
5936        app.hasShownUi = false;
5937        app.debugging = false;
5938        app.cached = false;
5939        app.killedByAm = false;
5940
5941        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5942
5943        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5944        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5945
5946        if (!normalMode) {
5947            Slog.i(TAG, "Launching preboot mode app: " + app);
5948        }
5949
5950        if (DEBUG_ALL) Slog.v(
5951            TAG, "New app record " + app
5952            + " thread=" + thread.asBinder() + " pid=" + pid);
5953        try {
5954            int testMode = IApplicationThread.DEBUG_OFF;
5955            if (mDebugApp != null && mDebugApp.equals(processName)) {
5956                testMode = mWaitForDebugger
5957                    ? IApplicationThread.DEBUG_WAIT
5958                    : IApplicationThread.DEBUG_ON;
5959                app.debugging = true;
5960                if (mDebugTransient) {
5961                    mDebugApp = mOrigDebugApp;
5962                    mWaitForDebugger = mOrigWaitForDebugger;
5963                }
5964            }
5965            String profileFile = app.instrumentationProfileFile;
5966            ParcelFileDescriptor profileFd = null;
5967            int samplingInterval = 0;
5968            boolean profileAutoStop = false;
5969            if (mProfileApp != null && mProfileApp.equals(processName)) {
5970                mProfileProc = app;
5971                profileFile = mProfileFile;
5972                profileFd = mProfileFd;
5973                samplingInterval = mSamplingInterval;
5974                profileAutoStop = mAutoStopProfiler;
5975            }
5976            boolean enableOpenGlTrace = false;
5977            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5978                enableOpenGlTrace = true;
5979                mOpenGlTraceApp = null;
5980            }
5981
5982            // If the app is being launched for restore or full backup, set it up specially
5983            boolean isRestrictedBackupMode = false;
5984            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5985                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5986                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5987                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5988            }
5989
5990            ensurePackageDexOpt(app.instrumentationInfo != null
5991                    ? app.instrumentationInfo.packageName
5992                    : app.info.packageName);
5993            if (app.instrumentationClass != null) {
5994                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5995            }
5996            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
5997                    + processName + " with config " + mConfiguration);
5998            ApplicationInfo appInfo = app.instrumentationInfo != null
5999                    ? app.instrumentationInfo : app.info;
6000            app.compat = compatibilityInfoForPackageLocked(appInfo);
6001            if (profileFd != null) {
6002                profileFd = profileFd.dup();
6003            }
6004            ProfilerInfo profilerInfo = profileFile == null ? null
6005                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6006            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6007                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6008                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6009                    isRestrictedBackupMode || !normalMode, app.persistent,
6010                    new Configuration(mConfiguration), app.compat,
6011                    getCommonServicesLocked(app.isolated),
6012                    mCoreSettingsObserver.getCoreSettingsLocked());
6013            updateLruProcessLocked(app, false, null);
6014            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6015        } catch (Exception e) {
6016            // todo: Yikes!  What should we do?  For now we will try to
6017            // start another process, but that could easily get us in
6018            // an infinite loop of restarting processes...
6019            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6020
6021            app.resetPackageList(mProcessStats);
6022            app.unlinkDeathRecipient();
6023            startProcessLocked(app, "bind fail", processName);
6024            return false;
6025        }
6026
6027        // Remove this record from the list of starting applications.
6028        mPersistentStartingProcesses.remove(app);
6029        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6030                "Attach application locked removing on hold: " + app);
6031        mProcessesOnHold.remove(app);
6032
6033        boolean badApp = false;
6034        boolean didSomething = false;
6035
6036        // See if the top visible activity is waiting to run in this process...
6037        if (normalMode) {
6038            try {
6039                if (mStackSupervisor.attachApplicationLocked(app)) {
6040                    didSomething = true;
6041                }
6042            } catch (Exception e) {
6043                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6044                badApp = true;
6045            }
6046        }
6047
6048        // Find any services that should be running in this process...
6049        if (!badApp) {
6050            try {
6051                didSomething |= mServices.attachApplicationLocked(app, processName);
6052            } catch (Exception e) {
6053                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6054                badApp = true;
6055            }
6056        }
6057
6058        // Check if a next-broadcast receiver is in this process...
6059        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6060            try {
6061                didSomething |= sendPendingBroadcastsLocked(app);
6062            } catch (Exception e) {
6063                // If the app died trying to launch the receiver we declare it 'bad'
6064                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6065                badApp = true;
6066            }
6067        }
6068
6069        // Check whether the next backup agent is in this process...
6070        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6071            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6072                    "New app is backup target, launching agent for " + app);
6073            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6074            try {
6075                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6076                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6077                        mBackupTarget.backupMode);
6078            } catch (Exception e) {
6079                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6080                badApp = true;
6081            }
6082        }
6083
6084        if (badApp) {
6085            app.kill("error during init", true);
6086            handleAppDiedLocked(app, false, true);
6087            return false;
6088        }
6089
6090        if (!didSomething) {
6091            updateOomAdjLocked();
6092        }
6093
6094        return true;
6095    }
6096
6097    @Override
6098    public final void attachApplication(IApplicationThread thread) {
6099        synchronized (this) {
6100            int callingPid = Binder.getCallingPid();
6101            final long origId = Binder.clearCallingIdentity();
6102            attachApplicationLocked(thread, callingPid);
6103            Binder.restoreCallingIdentity(origId);
6104        }
6105    }
6106
6107    @Override
6108    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6109        final long origId = Binder.clearCallingIdentity();
6110        synchronized (this) {
6111            ActivityStack stack = ActivityRecord.getStackLocked(token);
6112            if (stack != null) {
6113                ActivityRecord r =
6114                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6115                if (stopProfiling) {
6116                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6117                        try {
6118                            mProfileFd.close();
6119                        } catch (IOException e) {
6120                        }
6121                        clearProfilerLocked();
6122                    }
6123                }
6124            }
6125        }
6126        Binder.restoreCallingIdentity(origId);
6127    }
6128
6129    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6130        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6131                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6132    }
6133
6134    void enableScreenAfterBoot() {
6135        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6136                SystemClock.uptimeMillis());
6137        mWindowManager.enableScreenAfterBoot();
6138
6139        synchronized (this) {
6140            updateEventDispatchingLocked();
6141        }
6142    }
6143
6144    @Override
6145    public void showBootMessage(final CharSequence msg, final boolean always) {
6146        if (Binder.getCallingUid() != Process.myUid()) {
6147            // These days only the core system can call this, so apps can't get in
6148            // the way of what we show about running them.
6149        }
6150        mWindowManager.showBootMessage(msg, always);
6151    }
6152
6153    @Override
6154    public void keyguardWaitingForActivityDrawn() {
6155        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6156        final long token = Binder.clearCallingIdentity();
6157        try {
6158            synchronized (this) {
6159                if (DEBUG_LOCKSCREEN) logLockScreen("");
6160                mWindowManager.keyguardWaitingForActivityDrawn();
6161                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6162                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6163                    updateSleepIfNeededLocked();
6164                }
6165            }
6166        } finally {
6167            Binder.restoreCallingIdentity(token);
6168        }
6169    }
6170
6171    @Override
6172    public void keyguardGoingAway(boolean disableWindowAnimations,
6173            boolean keyguardGoingToNotificationShade) {
6174        enforceNotIsolatedCaller("keyguardGoingAway");
6175        final long token = Binder.clearCallingIdentity();
6176        try {
6177            synchronized (this) {
6178                if (DEBUG_LOCKSCREEN) logLockScreen("");
6179                mWindowManager.keyguardGoingAway(disableWindowAnimations,
6180                        keyguardGoingToNotificationShade);
6181                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6182                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6183                    updateSleepIfNeededLocked();
6184                }
6185            }
6186        } finally {
6187            Binder.restoreCallingIdentity(token);
6188        }
6189    }
6190
6191    final void finishBooting() {
6192        synchronized (this) {
6193            if (!mBootAnimationComplete) {
6194                mCallFinishBooting = true;
6195                return;
6196            }
6197            mCallFinishBooting = false;
6198        }
6199
6200        ArraySet<String> completedIsas = new ArraySet<String>();
6201        for (String abi : Build.SUPPORTED_ABIS) {
6202            Process.establishZygoteConnectionForAbi(abi);
6203            final String instructionSet = VMRuntime.getInstructionSet(abi);
6204            if (!completedIsas.contains(instructionSet)) {
6205                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6206                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6207                }
6208                completedIsas.add(instructionSet);
6209            }
6210        }
6211
6212        IntentFilter pkgFilter = new IntentFilter();
6213        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6214        pkgFilter.addDataScheme("package");
6215        mContext.registerReceiver(new BroadcastReceiver() {
6216            @Override
6217            public void onReceive(Context context, Intent intent) {
6218                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6219                if (pkgs != null) {
6220                    for (String pkg : pkgs) {
6221                        synchronized (ActivityManagerService.this) {
6222                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6223                                    0, "query restart")) {
6224                                setResultCode(Activity.RESULT_OK);
6225                                return;
6226                            }
6227                        }
6228                    }
6229                }
6230            }
6231        }, pkgFilter);
6232
6233        IntentFilter dumpheapFilter = new IntentFilter();
6234        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6235        mContext.registerReceiver(new BroadcastReceiver() {
6236            @Override
6237            public void onReceive(Context context, Intent intent) {
6238                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6239                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6240                } else {
6241                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6242                }
6243            }
6244        }, dumpheapFilter);
6245
6246        // Let system services know.
6247        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6248
6249        synchronized (this) {
6250            // Ensure that any processes we had put on hold are now started
6251            // up.
6252            final int NP = mProcessesOnHold.size();
6253            if (NP > 0) {
6254                ArrayList<ProcessRecord> procs =
6255                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6256                for (int ip=0; ip<NP; ip++) {
6257                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6258                            + procs.get(ip));
6259                    startProcessLocked(procs.get(ip), "on-hold", null);
6260                }
6261            }
6262
6263            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6264                // Start looking for apps that are abusing wake locks.
6265                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6266                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6267                // Tell anyone interested that we are done booting!
6268                SystemProperties.set("sys.boot_completed", "1");
6269
6270                // And trigger dev.bootcomplete if we are not showing encryption progress
6271                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6272                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6273                    SystemProperties.set("dev.bootcomplete", "1");
6274                }
6275                for (int i=0; i<mStartedUsers.size(); i++) {
6276                    UserStartedState uss = mStartedUsers.valueAt(i);
6277                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6278                        uss.mState = UserStartedState.STATE_RUNNING;
6279                        final int userId = mStartedUsers.keyAt(i);
6280                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6281                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6282                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6283                        broadcastIntentLocked(null, null, intent, null,
6284                                new IIntentReceiver.Stub() {
6285                                    @Override
6286                                    public void performReceive(Intent intent, int resultCode,
6287                                            String data, Bundle extras, boolean ordered,
6288                                            boolean sticky, int sendingUser) {
6289                                        synchronized (ActivityManagerService.this) {
6290                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6291                                                    true, false);
6292                                        }
6293                                    }
6294                                },
6295                                0, null, null,
6296                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6297                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6298                                userId);
6299                    }
6300                }
6301                scheduleStartProfilesLocked();
6302            }
6303        }
6304    }
6305
6306    @Override
6307    public void bootAnimationComplete() {
6308        final boolean callFinishBooting;
6309        synchronized (this) {
6310            callFinishBooting = mCallFinishBooting;
6311            mBootAnimationComplete = true;
6312        }
6313        if (callFinishBooting) {
6314            finishBooting();
6315        }
6316    }
6317
6318    final void ensureBootCompleted() {
6319        boolean booting;
6320        boolean enableScreen;
6321        synchronized (this) {
6322            booting = mBooting;
6323            mBooting = false;
6324            enableScreen = !mBooted;
6325            mBooted = true;
6326        }
6327
6328        if (booting) {
6329            finishBooting();
6330        }
6331
6332        if (enableScreen) {
6333            enableScreenAfterBoot();
6334        }
6335    }
6336
6337    @Override
6338    public final void activityResumed(IBinder token) {
6339        final long origId = Binder.clearCallingIdentity();
6340        synchronized(this) {
6341            ActivityStack stack = ActivityRecord.getStackLocked(token);
6342            if (stack != null) {
6343                ActivityRecord.activityResumedLocked(token);
6344            }
6345        }
6346        Binder.restoreCallingIdentity(origId);
6347    }
6348
6349    @Override
6350    public final void activityPaused(IBinder token) {
6351        final long origId = Binder.clearCallingIdentity();
6352        synchronized(this) {
6353            ActivityStack stack = ActivityRecord.getStackLocked(token);
6354            if (stack != null) {
6355                stack.activityPausedLocked(token, false);
6356            }
6357        }
6358        Binder.restoreCallingIdentity(origId);
6359    }
6360
6361    @Override
6362    public final void activityStopped(IBinder token, Bundle icicle,
6363            PersistableBundle persistentState, CharSequence description) {
6364        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6365
6366        // Refuse possible leaked file descriptors
6367        if (icicle != null && icicle.hasFileDescriptors()) {
6368            throw new IllegalArgumentException("File descriptors passed in Bundle");
6369        }
6370
6371        final long origId = Binder.clearCallingIdentity();
6372
6373        synchronized (this) {
6374            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6375            if (r != null) {
6376                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6377            }
6378        }
6379
6380        trimApplications();
6381
6382        Binder.restoreCallingIdentity(origId);
6383    }
6384
6385    @Override
6386    public final void activityDestroyed(IBinder token) {
6387        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6388        synchronized (this) {
6389            ActivityStack stack = ActivityRecord.getStackLocked(token);
6390            if (stack != null) {
6391                stack.activityDestroyedLocked(token, "activityDestroyed");
6392            }
6393        }
6394    }
6395
6396    @Override
6397    public final void backgroundResourcesReleased(IBinder token) {
6398        final long origId = Binder.clearCallingIdentity();
6399        try {
6400            synchronized (this) {
6401                ActivityStack stack = ActivityRecord.getStackLocked(token);
6402                if (stack != null) {
6403                    stack.backgroundResourcesReleased();
6404                }
6405            }
6406        } finally {
6407            Binder.restoreCallingIdentity(origId);
6408        }
6409    }
6410
6411    @Override
6412    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6413        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6414    }
6415
6416    @Override
6417    public final void notifyEnterAnimationComplete(IBinder token) {
6418        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6419    }
6420
6421    @Override
6422    public String getCallingPackage(IBinder token) {
6423        synchronized (this) {
6424            ActivityRecord r = getCallingRecordLocked(token);
6425            return r != null ? r.info.packageName : null;
6426        }
6427    }
6428
6429    @Override
6430    public ComponentName getCallingActivity(IBinder token) {
6431        synchronized (this) {
6432            ActivityRecord r = getCallingRecordLocked(token);
6433            return r != null ? r.intent.getComponent() : null;
6434        }
6435    }
6436
6437    private ActivityRecord getCallingRecordLocked(IBinder token) {
6438        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6439        if (r == null) {
6440            return null;
6441        }
6442        return r.resultTo;
6443    }
6444
6445    @Override
6446    public ComponentName getActivityClassForToken(IBinder token) {
6447        synchronized(this) {
6448            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6449            if (r == null) {
6450                return null;
6451            }
6452            return r.intent.getComponent();
6453        }
6454    }
6455
6456    @Override
6457    public String getPackageForToken(IBinder token) {
6458        synchronized(this) {
6459            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6460            if (r == null) {
6461                return null;
6462            }
6463            return r.packageName;
6464        }
6465    }
6466
6467    @Override
6468    public IIntentSender getIntentSender(int type,
6469            String packageName, IBinder token, String resultWho,
6470            int requestCode, Intent[] intents, String[] resolvedTypes,
6471            int flags, Bundle options, int userId) {
6472        enforceNotIsolatedCaller("getIntentSender");
6473        // Refuse possible leaked file descriptors
6474        if (intents != null) {
6475            if (intents.length < 1) {
6476                throw new IllegalArgumentException("Intents array length must be >= 1");
6477            }
6478            for (int i=0; i<intents.length; i++) {
6479                Intent intent = intents[i];
6480                if (intent != null) {
6481                    if (intent.hasFileDescriptors()) {
6482                        throw new IllegalArgumentException("File descriptors passed in Intent");
6483                    }
6484                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6485                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6486                        throw new IllegalArgumentException(
6487                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6488                    }
6489                    intents[i] = new Intent(intent);
6490                }
6491            }
6492            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6493                throw new IllegalArgumentException(
6494                        "Intent array length does not match resolvedTypes length");
6495            }
6496        }
6497        if (options != null) {
6498            if (options.hasFileDescriptors()) {
6499                throw new IllegalArgumentException("File descriptors passed in options");
6500            }
6501        }
6502
6503        synchronized(this) {
6504            int callingUid = Binder.getCallingUid();
6505            int origUserId = userId;
6506            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6507                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6508                    ALLOW_NON_FULL, "getIntentSender", null);
6509            if (origUserId == UserHandle.USER_CURRENT) {
6510                // We don't want to evaluate this until the pending intent is
6511                // actually executed.  However, we do want to always do the
6512                // security checking for it above.
6513                userId = UserHandle.USER_CURRENT;
6514            }
6515            try {
6516                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6517                    int uid = AppGlobals.getPackageManager()
6518                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6519                    if (!UserHandle.isSameApp(callingUid, uid)) {
6520                        String msg = "Permission Denial: getIntentSender() from pid="
6521                            + Binder.getCallingPid()
6522                            + ", uid=" + Binder.getCallingUid()
6523                            + ", (need uid=" + uid + ")"
6524                            + " is not allowed to send as package " + packageName;
6525                        Slog.w(TAG, msg);
6526                        throw new SecurityException(msg);
6527                    }
6528                }
6529
6530                return getIntentSenderLocked(type, packageName, callingUid, userId,
6531                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6532
6533            } catch (RemoteException e) {
6534                throw new SecurityException(e);
6535            }
6536        }
6537    }
6538
6539    IIntentSender getIntentSenderLocked(int type, String packageName,
6540            int callingUid, int userId, IBinder token, String resultWho,
6541            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6542            Bundle options) {
6543        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6544        ActivityRecord activity = null;
6545        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6546            activity = ActivityRecord.isInStackLocked(token);
6547            if (activity == null) {
6548                return null;
6549            }
6550            if (activity.finishing) {
6551                return null;
6552            }
6553        }
6554
6555        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6556        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6557        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6558        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6559                |PendingIntent.FLAG_UPDATE_CURRENT);
6560
6561        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6562                type, packageName, activity, resultWho,
6563                requestCode, intents, resolvedTypes, flags, options, userId);
6564        WeakReference<PendingIntentRecord> ref;
6565        ref = mIntentSenderRecords.get(key);
6566        PendingIntentRecord rec = ref != null ? ref.get() : null;
6567        if (rec != null) {
6568            if (!cancelCurrent) {
6569                if (updateCurrent) {
6570                    if (rec.key.requestIntent != null) {
6571                        rec.key.requestIntent.replaceExtras(intents != null ?
6572                                intents[intents.length - 1] : null);
6573                    }
6574                    if (intents != null) {
6575                        intents[intents.length-1] = rec.key.requestIntent;
6576                        rec.key.allIntents = intents;
6577                        rec.key.allResolvedTypes = resolvedTypes;
6578                    } else {
6579                        rec.key.allIntents = null;
6580                        rec.key.allResolvedTypes = null;
6581                    }
6582                }
6583                return rec;
6584            }
6585            rec.canceled = true;
6586            mIntentSenderRecords.remove(key);
6587        }
6588        if (noCreate) {
6589            return rec;
6590        }
6591        rec = new PendingIntentRecord(this, key, callingUid);
6592        mIntentSenderRecords.put(key, rec.ref);
6593        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6594            if (activity.pendingResults == null) {
6595                activity.pendingResults
6596                        = new HashSet<WeakReference<PendingIntentRecord>>();
6597            }
6598            activity.pendingResults.add(rec.ref);
6599        }
6600        return rec;
6601    }
6602
6603    @Override
6604    public void cancelIntentSender(IIntentSender sender) {
6605        if (!(sender instanceof PendingIntentRecord)) {
6606            return;
6607        }
6608        synchronized(this) {
6609            PendingIntentRecord rec = (PendingIntentRecord)sender;
6610            try {
6611                int uid = AppGlobals.getPackageManager()
6612                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6613                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6614                    String msg = "Permission Denial: cancelIntentSender() from pid="
6615                        + Binder.getCallingPid()
6616                        + ", uid=" + Binder.getCallingUid()
6617                        + " is not allowed to cancel packges "
6618                        + rec.key.packageName;
6619                    Slog.w(TAG, msg);
6620                    throw new SecurityException(msg);
6621                }
6622            } catch (RemoteException e) {
6623                throw new SecurityException(e);
6624            }
6625            cancelIntentSenderLocked(rec, true);
6626        }
6627    }
6628
6629    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6630        rec.canceled = true;
6631        mIntentSenderRecords.remove(rec.key);
6632        if (cleanActivity && rec.key.activity != null) {
6633            rec.key.activity.pendingResults.remove(rec.ref);
6634        }
6635    }
6636
6637    @Override
6638    public String getPackageForIntentSender(IIntentSender pendingResult) {
6639        if (!(pendingResult instanceof PendingIntentRecord)) {
6640            return null;
6641        }
6642        try {
6643            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6644            return res.key.packageName;
6645        } catch (ClassCastException e) {
6646        }
6647        return null;
6648    }
6649
6650    @Override
6651    public int getUidForIntentSender(IIntentSender sender) {
6652        if (sender instanceof PendingIntentRecord) {
6653            try {
6654                PendingIntentRecord res = (PendingIntentRecord)sender;
6655                return res.uid;
6656            } catch (ClassCastException e) {
6657            }
6658        }
6659        return -1;
6660    }
6661
6662    @Override
6663    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6664        if (!(pendingResult instanceof PendingIntentRecord)) {
6665            return false;
6666        }
6667        try {
6668            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6669            if (res.key.allIntents == null) {
6670                return false;
6671            }
6672            for (int i=0; i<res.key.allIntents.length; i++) {
6673                Intent intent = res.key.allIntents[i];
6674                if (intent.getPackage() != null && intent.getComponent() != null) {
6675                    return false;
6676                }
6677            }
6678            return true;
6679        } catch (ClassCastException e) {
6680        }
6681        return false;
6682    }
6683
6684    @Override
6685    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6686        if (!(pendingResult instanceof PendingIntentRecord)) {
6687            return false;
6688        }
6689        try {
6690            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6691            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6692                return true;
6693            }
6694            return false;
6695        } catch (ClassCastException e) {
6696        }
6697        return false;
6698    }
6699
6700    @Override
6701    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6702        if (!(pendingResult instanceof PendingIntentRecord)) {
6703            return null;
6704        }
6705        try {
6706            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6707            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6708        } catch (ClassCastException e) {
6709        }
6710        return null;
6711    }
6712
6713    @Override
6714    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6715        if (!(pendingResult instanceof PendingIntentRecord)) {
6716            return null;
6717        }
6718        try {
6719            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6720            synchronized (this) {
6721                return getTagForIntentSenderLocked(res, prefix);
6722            }
6723        } catch (ClassCastException e) {
6724        }
6725        return null;
6726    }
6727
6728    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
6729        final Intent intent = res.key.requestIntent;
6730        if (intent != null) {
6731            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6732                    || res.lastTagPrefix.equals(prefix))) {
6733                return res.lastTag;
6734            }
6735            res.lastTagPrefix = prefix;
6736            final StringBuilder sb = new StringBuilder(128);
6737            if (prefix != null) {
6738                sb.append(prefix);
6739            }
6740            if (intent.getAction() != null) {
6741                sb.append(intent.getAction());
6742            } else if (intent.getComponent() != null) {
6743                intent.getComponent().appendShortString(sb);
6744            } else {
6745                sb.append("?");
6746            }
6747            return res.lastTag = sb.toString();
6748        }
6749        return null;
6750    }
6751
6752    @Override
6753    public void setProcessLimit(int max) {
6754        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6755                "setProcessLimit()");
6756        synchronized (this) {
6757            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6758            mProcessLimitOverride = max;
6759        }
6760        trimApplications();
6761    }
6762
6763    @Override
6764    public int getProcessLimit() {
6765        synchronized (this) {
6766            return mProcessLimitOverride;
6767        }
6768    }
6769
6770    void foregroundTokenDied(ForegroundToken token) {
6771        synchronized (ActivityManagerService.this) {
6772            synchronized (mPidsSelfLocked) {
6773                ForegroundToken cur
6774                    = mForegroundProcesses.get(token.pid);
6775                if (cur != token) {
6776                    return;
6777                }
6778                mForegroundProcesses.remove(token.pid);
6779                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6780                if (pr == null) {
6781                    return;
6782                }
6783                pr.forcingToForeground = null;
6784                updateProcessForegroundLocked(pr, false, false);
6785            }
6786            updateOomAdjLocked();
6787        }
6788    }
6789
6790    @Override
6791    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6792        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6793                "setProcessForeground()");
6794        synchronized(this) {
6795            boolean changed = false;
6796
6797            synchronized (mPidsSelfLocked) {
6798                ProcessRecord pr = mPidsSelfLocked.get(pid);
6799                if (pr == null && isForeground) {
6800                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6801                    return;
6802                }
6803                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6804                if (oldToken != null) {
6805                    oldToken.token.unlinkToDeath(oldToken, 0);
6806                    mForegroundProcesses.remove(pid);
6807                    if (pr != null) {
6808                        pr.forcingToForeground = null;
6809                    }
6810                    changed = true;
6811                }
6812                if (isForeground && token != null) {
6813                    ForegroundToken newToken = new ForegroundToken() {
6814                        @Override
6815                        public void binderDied() {
6816                            foregroundTokenDied(this);
6817                        }
6818                    };
6819                    newToken.pid = pid;
6820                    newToken.token = token;
6821                    try {
6822                        token.linkToDeath(newToken, 0);
6823                        mForegroundProcesses.put(pid, newToken);
6824                        pr.forcingToForeground = token;
6825                        changed = true;
6826                    } catch (RemoteException e) {
6827                        // If the process died while doing this, we will later
6828                        // do the cleanup with the process death link.
6829                    }
6830                }
6831            }
6832
6833            if (changed) {
6834                updateOomAdjLocked();
6835            }
6836        }
6837    }
6838
6839    // =========================================================
6840    // PROCESS INFO
6841    // =========================================================
6842
6843    static class ProcessInfoService extends IProcessInfoService.Stub {
6844        final ActivityManagerService mActivityManagerService;
6845        ProcessInfoService(ActivityManagerService activityManagerService) {
6846            mActivityManagerService = activityManagerService;
6847        }
6848
6849        @Override
6850        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
6851            mActivityManagerService.getProcessStatesForPIDs(/*in*/ pids, /*out*/ states);
6852        }
6853    }
6854
6855    /**
6856     * For each PID in the given input array, write the current process state
6857     * for that process into the output array, or -1 to indicate that no
6858     * process with the given PID exists.
6859     */
6860    public void getProcessStatesForPIDs(/*in*/ int[] pids, /*out*/ int[] states) {
6861        if (pids == null) {
6862            throw new NullPointerException("pids");
6863        } else if (states == null) {
6864            throw new NullPointerException("states");
6865        } else if (pids.length != states.length) {
6866            throw new IllegalArgumentException("input and output arrays have different lengths!");
6867        }
6868
6869        synchronized (mPidsSelfLocked) {
6870            for (int i = 0; i < pids.length; i++) {
6871                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
6872                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
6873                        pr.curProcState;
6874            }
6875        }
6876    }
6877
6878    // =========================================================
6879    // PERMISSIONS
6880    // =========================================================
6881
6882    static class PermissionController extends IPermissionController.Stub {
6883        ActivityManagerService mActivityManagerService;
6884        PermissionController(ActivityManagerService activityManagerService) {
6885            mActivityManagerService = activityManagerService;
6886        }
6887
6888        @Override
6889        public boolean checkPermission(String permission, int pid, int uid) {
6890            return mActivityManagerService.checkPermission(permission, pid,
6891                    uid) == PackageManager.PERMISSION_GRANTED;
6892        }
6893
6894        @Override
6895        public String[] getPackagesForUid(int uid) {
6896            return mActivityManagerService.mContext.getPackageManager()
6897                    .getPackagesForUid(uid);
6898        }
6899
6900        @Override
6901        public boolean isRuntimePermission(String permission) {
6902            try {
6903                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
6904                        .getPermissionInfo(permission, 0);
6905                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
6906            } catch (NameNotFoundException nnfe) {
6907                Slog.e(TAG, "No such permission: "+ permission, nnfe);
6908            }
6909            return false;
6910        }
6911    }
6912
6913    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6914        @Override
6915        public int checkComponentPermission(String permission, int pid, int uid,
6916                int owningUid, boolean exported) {
6917            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6918                    owningUid, exported);
6919        }
6920
6921        @Override
6922        public Object getAMSLock() {
6923            return ActivityManagerService.this;
6924        }
6925    }
6926
6927    /**
6928     * This can be called with or without the global lock held.
6929     */
6930    int checkComponentPermission(String permission, int pid, int uid,
6931            int owningUid, boolean exported) {
6932        if (pid == MY_PID) {
6933            return PackageManager.PERMISSION_GRANTED;
6934        }
6935        return ActivityManager.checkComponentPermission(permission, uid,
6936                owningUid, exported);
6937    }
6938
6939    /**
6940     * As the only public entry point for permissions checking, this method
6941     * can enforce the semantic that requesting a check on a null global
6942     * permission is automatically denied.  (Internally a null permission
6943     * string is used when calling {@link #checkComponentPermission} in cases
6944     * when only uid-based security is needed.)
6945     *
6946     * This can be called with or without the global lock held.
6947     */
6948    @Override
6949    public int checkPermission(String permission, int pid, int uid) {
6950        if (permission == null) {
6951            return PackageManager.PERMISSION_DENIED;
6952        }
6953        return checkComponentPermission(permission, pid, uid, -1, true);
6954    }
6955
6956    @Override
6957    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
6958        if (permission == null) {
6959            return PackageManager.PERMISSION_DENIED;
6960        }
6961
6962        // We might be performing an operation on behalf of an indirect binder
6963        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6964        // client identity accordingly before proceeding.
6965        Identity tlsIdentity = sCallerIdentity.get();
6966        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6967            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6968                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6969            uid = tlsIdentity.uid;
6970            pid = tlsIdentity.pid;
6971        }
6972
6973        return checkComponentPermission(permission, pid, uid, -1, true);
6974    }
6975
6976    /**
6977     * Binder IPC calls go through the public entry point.
6978     * This can be called with or without the global lock held.
6979     */
6980    int checkCallingPermission(String permission) {
6981        return checkPermission(permission,
6982                Binder.getCallingPid(),
6983                UserHandle.getAppId(Binder.getCallingUid()));
6984    }
6985
6986    /**
6987     * This can be called with or without the global lock held.
6988     */
6989    void enforceCallingPermission(String permission, String func) {
6990        if (checkCallingPermission(permission)
6991                == PackageManager.PERMISSION_GRANTED) {
6992            return;
6993        }
6994
6995        String msg = "Permission Denial: " + func + " from pid="
6996                + Binder.getCallingPid()
6997                + ", uid=" + Binder.getCallingUid()
6998                + " requires " + permission;
6999        Slog.w(TAG, msg);
7000        throw new SecurityException(msg);
7001    }
7002
7003    /**
7004     * Determine if UID is holding permissions required to access {@link Uri} in
7005     * the given {@link ProviderInfo}. Final permission checking is always done
7006     * in {@link ContentProvider}.
7007     */
7008    private final boolean checkHoldingPermissionsLocked(
7009            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7010        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7011                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7012        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7013            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7014                    != PERMISSION_GRANTED) {
7015                return false;
7016            }
7017        }
7018        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7019    }
7020
7021    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7022            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7023        if (pi.applicationInfo.uid == uid) {
7024            return true;
7025        } else if (!pi.exported) {
7026            return false;
7027        }
7028
7029        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7030        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7031        try {
7032            // check if target holds top-level <provider> permissions
7033            if (!readMet && pi.readPermission != null && considerUidPermissions
7034                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7035                readMet = true;
7036            }
7037            if (!writeMet && pi.writePermission != null && considerUidPermissions
7038                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7039                writeMet = true;
7040            }
7041
7042            // track if unprotected read/write is allowed; any denied
7043            // <path-permission> below removes this ability
7044            boolean allowDefaultRead = pi.readPermission == null;
7045            boolean allowDefaultWrite = pi.writePermission == null;
7046
7047            // check if target holds any <path-permission> that match uri
7048            final PathPermission[] pps = pi.pathPermissions;
7049            if (pps != null) {
7050                final String path = grantUri.uri.getPath();
7051                int i = pps.length;
7052                while (i > 0 && (!readMet || !writeMet)) {
7053                    i--;
7054                    PathPermission pp = pps[i];
7055                    if (pp.match(path)) {
7056                        if (!readMet) {
7057                            final String pprperm = pp.getReadPermission();
7058                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7059                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7060                                    + ": match=" + pp.match(path)
7061                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7062                            if (pprperm != null) {
7063                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7064                                        == PERMISSION_GRANTED) {
7065                                    readMet = true;
7066                                } else {
7067                                    allowDefaultRead = false;
7068                                }
7069                            }
7070                        }
7071                        if (!writeMet) {
7072                            final String ppwperm = pp.getWritePermission();
7073                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7074                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7075                                    + ": match=" + pp.match(path)
7076                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7077                            if (ppwperm != null) {
7078                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7079                                        == PERMISSION_GRANTED) {
7080                                    writeMet = true;
7081                                } else {
7082                                    allowDefaultWrite = false;
7083                                }
7084                            }
7085                        }
7086                    }
7087                }
7088            }
7089
7090            // grant unprotected <provider> read/write, if not blocked by
7091            // <path-permission> above
7092            if (allowDefaultRead) readMet = true;
7093            if (allowDefaultWrite) writeMet = true;
7094
7095        } catch (RemoteException e) {
7096            return false;
7097        }
7098
7099        return readMet && writeMet;
7100    }
7101
7102    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7103        ProviderInfo pi = null;
7104        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7105        if (cpr != null) {
7106            pi = cpr.info;
7107        } else {
7108            try {
7109                pi = AppGlobals.getPackageManager().resolveContentProvider(
7110                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7111            } catch (RemoteException ex) {
7112            }
7113        }
7114        return pi;
7115    }
7116
7117    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7118        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7119        if (targetUris != null) {
7120            return targetUris.get(grantUri);
7121        }
7122        return null;
7123    }
7124
7125    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7126            String targetPkg, int targetUid, GrantUri grantUri) {
7127        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7128        if (targetUris == null) {
7129            targetUris = Maps.newArrayMap();
7130            mGrantedUriPermissions.put(targetUid, targetUris);
7131        }
7132
7133        UriPermission perm = targetUris.get(grantUri);
7134        if (perm == null) {
7135            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7136            targetUris.put(grantUri, perm);
7137        }
7138
7139        return perm;
7140    }
7141
7142    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7143            final int modeFlags) {
7144        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7145        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7146                : UriPermission.STRENGTH_OWNED;
7147
7148        // Root gets to do everything.
7149        if (uid == 0) {
7150            return true;
7151        }
7152
7153        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7154        if (perms == null) return false;
7155
7156        // First look for exact match
7157        final UriPermission exactPerm = perms.get(grantUri);
7158        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7159            return true;
7160        }
7161
7162        // No exact match, look for prefixes
7163        final int N = perms.size();
7164        for (int i = 0; i < N; i++) {
7165            final UriPermission perm = perms.valueAt(i);
7166            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7167                    && perm.getStrength(modeFlags) >= minStrength) {
7168                return true;
7169            }
7170        }
7171
7172        return false;
7173    }
7174
7175    /**
7176     * @param uri This uri must NOT contain an embedded userId.
7177     * @param userId The userId in which the uri is to be resolved.
7178     */
7179    @Override
7180    public int checkUriPermission(Uri uri, int pid, int uid,
7181            final int modeFlags, int userId, IBinder callerToken) {
7182        enforceNotIsolatedCaller("checkUriPermission");
7183
7184        // Another redirected-binder-call permissions check as in
7185        // {@link checkPermissionWithToken}.
7186        Identity tlsIdentity = sCallerIdentity.get();
7187        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7188            uid = tlsIdentity.uid;
7189            pid = tlsIdentity.pid;
7190        }
7191
7192        // Our own process gets to do everything.
7193        if (pid == MY_PID) {
7194            return PackageManager.PERMISSION_GRANTED;
7195        }
7196        synchronized (this) {
7197            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7198                    ? PackageManager.PERMISSION_GRANTED
7199                    : PackageManager.PERMISSION_DENIED;
7200        }
7201    }
7202
7203    /**
7204     * Check if the targetPkg can be granted permission to access uri by
7205     * the callingUid using the given modeFlags.  Throws a security exception
7206     * if callingUid is not allowed to do this.  Returns the uid of the target
7207     * if the URI permission grant should be performed; returns -1 if it is not
7208     * needed (for example targetPkg already has permission to access the URI).
7209     * If you already know the uid of the target, you can supply it in
7210     * lastTargetUid else set that to -1.
7211     */
7212    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7213            final int modeFlags, int lastTargetUid) {
7214        if (!Intent.isAccessUriMode(modeFlags)) {
7215            return -1;
7216        }
7217
7218        if (targetPkg != null) {
7219            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7220                    "Checking grant " + targetPkg + " permission to " + grantUri);
7221        }
7222
7223        final IPackageManager pm = AppGlobals.getPackageManager();
7224
7225        // If this is not a content: uri, we can't do anything with it.
7226        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7227            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7228                    "Can't grant URI permission for non-content URI: " + grantUri);
7229            return -1;
7230        }
7231
7232        final String authority = grantUri.uri.getAuthority();
7233        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7234        if (pi == null) {
7235            Slog.w(TAG, "No content provider found for permission check: " +
7236                    grantUri.uri.toSafeString());
7237            return -1;
7238        }
7239
7240        int targetUid = lastTargetUid;
7241        if (targetUid < 0 && targetPkg != null) {
7242            try {
7243                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7244                if (targetUid < 0) {
7245                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7246                            "Can't grant URI permission no uid for: " + targetPkg);
7247                    return -1;
7248                }
7249            } catch (RemoteException ex) {
7250                return -1;
7251            }
7252        }
7253
7254        if (targetUid >= 0) {
7255            // First...  does the target actually need this permission?
7256            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7257                // No need to grant the target this permission.
7258                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7259                        "Target " + targetPkg + " already has full permission to " + grantUri);
7260                return -1;
7261            }
7262        } else {
7263            // First...  there is no target package, so can anyone access it?
7264            boolean allowed = pi.exported;
7265            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7266                if (pi.readPermission != null) {
7267                    allowed = false;
7268                }
7269            }
7270            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7271                if (pi.writePermission != null) {
7272                    allowed = false;
7273                }
7274            }
7275            if (allowed) {
7276                return -1;
7277            }
7278        }
7279
7280        /* There is a special cross user grant if:
7281         * - The target is on another user.
7282         * - Apps on the current user can access the uri without any uid permissions.
7283         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7284         * grant uri permissions.
7285         */
7286        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7287                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7288                modeFlags, false /*without considering the uid permissions*/);
7289
7290        // Second...  is the provider allowing granting of URI permissions?
7291        if (!specialCrossUserGrant) {
7292            if (!pi.grantUriPermissions) {
7293                throw new SecurityException("Provider " + pi.packageName
7294                        + "/" + pi.name
7295                        + " does not allow granting of Uri permissions (uri "
7296                        + grantUri + ")");
7297            }
7298            if (pi.uriPermissionPatterns != null) {
7299                final int N = pi.uriPermissionPatterns.length;
7300                boolean allowed = false;
7301                for (int i=0; i<N; i++) {
7302                    if (pi.uriPermissionPatterns[i] != null
7303                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7304                        allowed = true;
7305                        break;
7306                    }
7307                }
7308                if (!allowed) {
7309                    throw new SecurityException("Provider " + pi.packageName
7310                            + "/" + pi.name
7311                            + " does not allow granting of permission to path of Uri "
7312                            + grantUri);
7313                }
7314            }
7315        }
7316
7317        // Third...  does the caller itself have permission to access
7318        // this uri?
7319        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7320            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7321                // Require they hold a strong enough Uri permission
7322                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7323                    throw new SecurityException("Uid " + callingUid
7324                            + " does not have permission to uri " + grantUri);
7325                }
7326            }
7327        }
7328        return targetUid;
7329    }
7330
7331    /**
7332     * @param uri This uri must NOT contain an embedded userId.
7333     * @param userId The userId in which the uri is to be resolved.
7334     */
7335    @Override
7336    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7337            final int modeFlags, int userId) {
7338        enforceNotIsolatedCaller("checkGrantUriPermission");
7339        synchronized(this) {
7340            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7341                    new GrantUri(userId, uri, false), modeFlags, -1);
7342        }
7343    }
7344
7345    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7346            final int modeFlags, UriPermissionOwner owner) {
7347        if (!Intent.isAccessUriMode(modeFlags)) {
7348            return;
7349        }
7350
7351        // So here we are: the caller has the assumed permission
7352        // to the uri, and the target doesn't.  Let's now give this to
7353        // the target.
7354
7355        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7356                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7357
7358        final String authority = grantUri.uri.getAuthority();
7359        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7360        if (pi == null) {
7361            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7362            return;
7363        }
7364
7365        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7366            grantUri.prefix = true;
7367        }
7368        final UriPermission perm = findOrCreateUriPermissionLocked(
7369                pi.packageName, targetPkg, targetUid, grantUri);
7370        perm.grantModes(modeFlags, owner);
7371    }
7372
7373    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7374            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7375        if (targetPkg == null) {
7376            throw new NullPointerException("targetPkg");
7377        }
7378        int targetUid;
7379        final IPackageManager pm = AppGlobals.getPackageManager();
7380        try {
7381            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7382        } catch (RemoteException ex) {
7383            return;
7384        }
7385
7386        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7387                targetUid);
7388        if (targetUid < 0) {
7389            return;
7390        }
7391
7392        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7393                owner);
7394    }
7395
7396    static class NeededUriGrants extends ArrayList<GrantUri> {
7397        final String targetPkg;
7398        final int targetUid;
7399        final int flags;
7400
7401        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7402            this.targetPkg = targetPkg;
7403            this.targetUid = targetUid;
7404            this.flags = flags;
7405        }
7406    }
7407
7408    /**
7409     * Like checkGrantUriPermissionLocked, but takes an Intent.
7410     */
7411    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7412            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7413        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7414                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7415                + " clip=" + (intent != null ? intent.getClipData() : null)
7416                + " from " + intent + "; flags=0x"
7417                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7418
7419        if (targetPkg == null) {
7420            throw new NullPointerException("targetPkg");
7421        }
7422
7423        if (intent == null) {
7424            return null;
7425        }
7426        Uri data = intent.getData();
7427        ClipData clip = intent.getClipData();
7428        if (data == null && clip == null) {
7429            return null;
7430        }
7431        // Default userId for uris in the intent (if they don't specify it themselves)
7432        int contentUserHint = intent.getContentUserHint();
7433        if (contentUserHint == UserHandle.USER_CURRENT) {
7434            contentUserHint = UserHandle.getUserId(callingUid);
7435        }
7436        final IPackageManager pm = AppGlobals.getPackageManager();
7437        int targetUid;
7438        if (needed != null) {
7439            targetUid = needed.targetUid;
7440        } else {
7441            try {
7442                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7443            } catch (RemoteException ex) {
7444                return null;
7445            }
7446            if (targetUid < 0) {
7447                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7448                        "Can't grant URI permission no uid for: " + targetPkg
7449                        + " on user " + targetUserId);
7450                return null;
7451            }
7452        }
7453        if (data != null) {
7454            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7455            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7456                    targetUid);
7457            if (targetUid > 0) {
7458                if (needed == null) {
7459                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7460                }
7461                needed.add(grantUri);
7462            }
7463        }
7464        if (clip != null) {
7465            for (int i=0; i<clip.getItemCount(); i++) {
7466                Uri uri = clip.getItemAt(i).getUri();
7467                if (uri != null) {
7468                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7469                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7470                            targetUid);
7471                    if (targetUid > 0) {
7472                        if (needed == null) {
7473                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7474                        }
7475                        needed.add(grantUri);
7476                    }
7477                } else {
7478                    Intent clipIntent = clip.getItemAt(i).getIntent();
7479                    if (clipIntent != null) {
7480                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7481                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7482                        if (newNeeded != null) {
7483                            needed = newNeeded;
7484                        }
7485                    }
7486                }
7487            }
7488        }
7489
7490        return needed;
7491    }
7492
7493    /**
7494     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7495     */
7496    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7497            UriPermissionOwner owner) {
7498        if (needed != null) {
7499            for (int i=0; i<needed.size(); i++) {
7500                GrantUri grantUri = needed.get(i);
7501                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7502                        grantUri, needed.flags, owner);
7503            }
7504        }
7505    }
7506
7507    void grantUriPermissionFromIntentLocked(int callingUid,
7508            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7509        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7510                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7511        if (needed == null) {
7512            return;
7513        }
7514
7515        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7516    }
7517
7518    /**
7519     * @param uri This uri must NOT contain an embedded userId.
7520     * @param userId The userId in which the uri is to be resolved.
7521     */
7522    @Override
7523    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7524            final int modeFlags, int userId) {
7525        enforceNotIsolatedCaller("grantUriPermission");
7526        GrantUri grantUri = new GrantUri(userId, uri, false);
7527        synchronized(this) {
7528            final ProcessRecord r = getRecordForAppLocked(caller);
7529            if (r == null) {
7530                throw new SecurityException("Unable to find app for caller "
7531                        + caller
7532                        + " when granting permission to uri " + grantUri);
7533            }
7534            if (targetPkg == null) {
7535                throw new IllegalArgumentException("null target");
7536            }
7537            if (grantUri == null) {
7538                throw new IllegalArgumentException("null uri");
7539            }
7540
7541            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7542                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7543                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7544                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7545
7546            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7547                    UserHandle.getUserId(r.uid));
7548        }
7549    }
7550
7551    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7552        if (perm.modeFlags == 0) {
7553            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7554                    perm.targetUid);
7555            if (perms != null) {
7556                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7557                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7558
7559                perms.remove(perm.uri);
7560                if (perms.isEmpty()) {
7561                    mGrantedUriPermissions.remove(perm.targetUid);
7562                }
7563            }
7564        }
7565    }
7566
7567    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7568        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7569                "Revoking all granted permissions to " + grantUri);
7570
7571        final IPackageManager pm = AppGlobals.getPackageManager();
7572        final String authority = grantUri.uri.getAuthority();
7573        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7574        if (pi == null) {
7575            Slog.w(TAG, "No content provider found for permission revoke: "
7576                    + grantUri.toSafeString());
7577            return;
7578        }
7579
7580        // Does the caller have this permission on the URI?
7581        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7582            // If they don't have direct access to the URI, then revoke any
7583            // ownerless URI permissions that have been granted to them.
7584            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7585            if (perms != null) {
7586                boolean persistChanged = false;
7587                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7588                    final UriPermission perm = it.next();
7589                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7590                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7591                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7592                                "Revoking non-owned " + perm.targetUid
7593                                + " permission to " + perm.uri);
7594                        persistChanged |= perm.revokeModes(
7595                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7596                        if (perm.modeFlags == 0) {
7597                            it.remove();
7598                        }
7599                    }
7600                }
7601                if (perms.isEmpty()) {
7602                    mGrantedUriPermissions.remove(callingUid);
7603                }
7604                if (persistChanged) {
7605                    schedulePersistUriGrants();
7606                }
7607            }
7608            return;
7609        }
7610
7611        boolean persistChanged = false;
7612
7613        // Go through all of the permissions and remove any that match.
7614        int N = mGrantedUriPermissions.size();
7615        for (int i = 0; i < N; i++) {
7616            final int targetUid = mGrantedUriPermissions.keyAt(i);
7617            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7618
7619            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7620                final UriPermission perm = it.next();
7621                if (perm.uri.sourceUserId == grantUri.sourceUserId
7622                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7623                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7624                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7625                    persistChanged |= perm.revokeModes(
7626                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7627                    if (perm.modeFlags == 0) {
7628                        it.remove();
7629                    }
7630                }
7631            }
7632
7633            if (perms.isEmpty()) {
7634                mGrantedUriPermissions.remove(targetUid);
7635                N--;
7636                i--;
7637            }
7638        }
7639
7640        if (persistChanged) {
7641            schedulePersistUriGrants();
7642        }
7643    }
7644
7645    /**
7646     * @param uri This uri must NOT contain an embedded userId.
7647     * @param userId The userId in which the uri is to be resolved.
7648     */
7649    @Override
7650    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7651            int userId) {
7652        enforceNotIsolatedCaller("revokeUriPermission");
7653        synchronized(this) {
7654            final ProcessRecord r = getRecordForAppLocked(caller);
7655            if (r == null) {
7656                throw new SecurityException("Unable to find app for caller "
7657                        + caller
7658                        + " when revoking permission to uri " + uri);
7659            }
7660            if (uri == null) {
7661                Slog.w(TAG, "revokeUriPermission: null uri");
7662                return;
7663            }
7664
7665            if (!Intent.isAccessUriMode(modeFlags)) {
7666                return;
7667            }
7668
7669            final String authority = uri.getAuthority();
7670            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7671            if (pi == null) {
7672                Slog.w(TAG, "No content provider found for permission revoke: "
7673                        + uri.toSafeString());
7674                return;
7675            }
7676
7677            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7678        }
7679    }
7680
7681    /**
7682     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7683     * given package.
7684     *
7685     * @param packageName Package name to match, or {@code null} to apply to all
7686     *            packages.
7687     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7688     *            to all users.
7689     * @param persistable If persistable grants should be removed.
7690     */
7691    private void removeUriPermissionsForPackageLocked(
7692            String packageName, int userHandle, boolean persistable) {
7693        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7694            throw new IllegalArgumentException("Must narrow by either package or user");
7695        }
7696
7697        boolean persistChanged = false;
7698
7699        int N = mGrantedUriPermissions.size();
7700        for (int i = 0; i < N; i++) {
7701            final int targetUid = mGrantedUriPermissions.keyAt(i);
7702            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7703
7704            // Only inspect grants matching user
7705            if (userHandle == UserHandle.USER_ALL
7706                    || userHandle == UserHandle.getUserId(targetUid)) {
7707                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7708                    final UriPermission perm = it.next();
7709
7710                    // Only inspect grants matching package
7711                    if (packageName == null || perm.sourcePkg.equals(packageName)
7712                            || perm.targetPkg.equals(packageName)) {
7713                        persistChanged |= perm.revokeModes(persistable
7714                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7715
7716                        // Only remove when no modes remain; any persisted grants
7717                        // will keep this alive.
7718                        if (perm.modeFlags == 0) {
7719                            it.remove();
7720                        }
7721                    }
7722                }
7723
7724                if (perms.isEmpty()) {
7725                    mGrantedUriPermissions.remove(targetUid);
7726                    N--;
7727                    i--;
7728                }
7729            }
7730        }
7731
7732        if (persistChanged) {
7733            schedulePersistUriGrants();
7734        }
7735    }
7736
7737    @Override
7738    public IBinder newUriPermissionOwner(String name) {
7739        enforceNotIsolatedCaller("newUriPermissionOwner");
7740        synchronized(this) {
7741            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7742            return owner.getExternalTokenLocked();
7743        }
7744    }
7745
7746    /**
7747     * @param uri This uri must NOT contain an embedded userId.
7748     * @param sourceUserId The userId in which the uri is to be resolved.
7749     * @param targetUserId The userId of the app that receives the grant.
7750     */
7751    @Override
7752    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7753            final int modeFlags, int sourceUserId, int targetUserId) {
7754        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7755                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7756        synchronized(this) {
7757            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7758            if (owner == null) {
7759                throw new IllegalArgumentException("Unknown owner: " + token);
7760            }
7761            if (fromUid != Binder.getCallingUid()) {
7762                if (Binder.getCallingUid() != Process.myUid()) {
7763                    // Only system code can grant URI permissions on behalf
7764                    // of other users.
7765                    throw new SecurityException("nice try");
7766                }
7767            }
7768            if (targetPkg == null) {
7769                throw new IllegalArgumentException("null target");
7770            }
7771            if (uri == null) {
7772                throw new IllegalArgumentException("null uri");
7773            }
7774
7775            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7776                    modeFlags, owner, targetUserId);
7777        }
7778    }
7779
7780    /**
7781     * @param uri This uri must NOT contain an embedded userId.
7782     * @param userId The userId in which the uri is to be resolved.
7783     */
7784    @Override
7785    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7786        synchronized(this) {
7787            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7788            if (owner == null) {
7789                throw new IllegalArgumentException("Unknown owner: " + token);
7790            }
7791
7792            if (uri == null) {
7793                owner.removeUriPermissionsLocked(mode);
7794            } else {
7795                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7796            }
7797        }
7798    }
7799
7800    private void schedulePersistUriGrants() {
7801        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7802            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7803                    10 * DateUtils.SECOND_IN_MILLIS);
7804        }
7805    }
7806
7807    private void writeGrantedUriPermissions() {
7808        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
7809
7810        // Snapshot permissions so we can persist without lock
7811        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7812        synchronized (this) {
7813            final int size = mGrantedUriPermissions.size();
7814            for (int i = 0; i < size; i++) {
7815                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7816                for (UriPermission perm : perms.values()) {
7817                    if (perm.persistedModeFlags != 0) {
7818                        persist.add(perm.snapshot());
7819                    }
7820                }
7821            }
7822        }
7823
7824        FileOutputStream fos = null;
7825        try {
7826            fos = mGrantFile.startWrite();
7827
7828            XmlSerializer out = new FastXmlSerializer();
7829            out.setOutput(fos, StandardCharsets.UTF_8.name());
7830            out.startDocument(null, true);
7831            out.startTag(null, TAG_URI_GRANTS);
7832            for (UriPermission.Snapshot perm : persist) {
7833                out.startTag(null, TAG_URI_GRANT);
7834                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7835                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7836                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7837                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7838                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7839                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7840                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7841                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7842                out.endTag(null, TAG_URI_GRANT);
7843            }
7844            out.endTag(null, TAG_URI_GRANTS);
7845            out.endDocument();
7846
7847            mGrantFile.finishWrite(fos);
7848        } catch (IOException e) {
7849            if (fos != null) {
7850                mGrantFile.failWrite(fos);
7851            }
7852        }
7853    }
7854
7855    private void readGrantedUriPermissionsLocked() {
7856        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
7857
7858        final long now = System.currentTimeMillis();
7859
7860        FileInputStream fis = null;
7861        try {
7862            fis = mGrantFile.openRead();
7863            final XmlPullParser in = Xml.newPullParser();
7864            in.setInput(fis, StandardCharsets.UTF_8.name());
7865
7866            int type;
7867            while ((type = in.next()) != END_DOCUMENT) {
7868                final String tag = in.getName();
7869                if (type == START_TAG) {
7870                    if (TAG_URI_GRANT.equals(tag)) {
7871                        final int sourceUserId;
7872                        final int targetUserId;
7873                        final int userHandle = readIntAttribute(in,
7874                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7875                        if (userHandle != UserHandle.USER_NULL) {
7876                            // For backwards compatibility.
7877                            sourceUserId = userHandle;
7878                            targetUserId = userHandle;
7879                        } else {
7880                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7881                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7882                        }
7883                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7884                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7885                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7886                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7887                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7888                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7889
7890                        // Sanity check that provider still belongs to source package
7891                        final ProviderInfo pi = getProviderInfoLocked(
7892                                uri.getAuthority(), sourceUserId);
7893                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7894                            int targetUid = -1;
7895                            try {
7896                                targetUid = AppGlobals.getPackageManager()
7897                                        .getPackageUid(targetPkg, targetUserId);
7898                            } catch (RemoteException e) {
7899                            }
7900                            if (targetUid != -1) {
7901                                final UriPermission perm = findOrCreateUriPermissionLocked(
7902                                        sourcePkg, targetPkg, targetUid,
7903                                        new GrantUri(sourceUserId, uri, prefix));
7904                                perm.initPersistedModes(modeFlags, createdTime);
7905                            }
7906                        } else {
7907                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7908                                    + " but instead found " + pi);
7909                        }
7910                    }
7911                }
7912            }
7913        } catch (FileNotFoundException e) {
7914            // Missing grants is okay
7915        } catch (IOException e) {
7916            Slog.wtf(TAG, "Failed reading Uri grants", e);
7917        } catch (XmlPullParserException e) {
7918            Slog.wtf(TAG, "Failed reading Uri grants", e);
7919        } finally {
7920            IoUtils.closeQuietly(fis);
7921        }
7922    }
7923
7924    /**
7925     * @param uri This uri must NOT contain an embedded userId.
7926     * @param userId The userId in which the uri is to be resolved.
7927     */
7928    @Override
7929    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7930        enforceNotIsolatedCaller("takePersistableUriPermission");
7931
7932        Preconditions.checkFlagsArgument(modeFlags,
7933                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7934
7935        synchronized (this) {
7936            final int callingUid = Binder.getCallingUid();
7937            boolean persistChanged = false;
7938            GrantUri grantUri = new GrantUri(userId, uri, false);
7939
7940            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7941                    new GrantUri(userId, uri, false));
7942            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7943                    new GrantUri(userId, uri, true));
7944
7945            final boolean exactValid = (exactPerm != null)
7946                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7947            final boolean prefixValid = (prefixPerm != null)
7948                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7949
7950            if (!(exactValid || prefixValid)) {
7951                throw new SecurityException("No persistable permission grants found for UID "
7952                        + callingUid + " and Uri " + grantUri.toSafeString());
7953            }
7954
7955            if (exactValid) {
7956                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7957            }
7958            if (prefixValid) {
7959                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7960            }
7961
7962            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7963
7964            if (persistChanged) {
7965                schedulePersistUriGrants();
7966            }
7967        }
7968    }
7969
7970    /**
7971     * @param uri This uri must NOT contain an embedded userId.
7972     * @param userId The userId in which the uri is to be resolved.
7973     */
7974    @Override
7975    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7976        enforceNotIsolatedCaller("releasePersistableUriPermission");
7977
7978        Preconditions.checkFlagsArgument(modeFlags,
7979                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7980
7981        synchronized (this) {
7982            final int callingUid = Binder.getCallingUid();
7983            boolean persistChanged = false;
7984
7985            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7986                    new GrantUri(userId, uri, false));
7987            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7988                    new GrantUri(userId, uri, true));
7989            if (exactPerm == null && prefixPerm == null) {
7990                throw new SecurityException("No permission grants found for UID " + callingUid
7991                        + " and Uri " + uri.toSafeString());
7992            }
7993
7994            if (exactPerm != null) {
7995                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7996                removeUriPermissionIfNeededLocked(exactPerm);
7997            }
7998            if (prefixPerm != null) {
7999                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8000                removeUriPermissionIfNeededLocked(prefixPerm);
8001            }
8002
8003            if (persistChanged) {
8004                schedulePersistUriGrants();
8005            }
8006        }
8007    }
8008
8009    /**
8010     * Prune any older {@link UriPermission} for the given UID until outstanding
8011     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8012     *
8013     * @return if any mutations occured that require persisting.
8014     */
8015    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8016        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8017        if (perms == null) return false;
8018        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8019
8020        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8021        for (UriPermission perm : perms.values()) {
8022            if (perm.persistedModeFlags != 0) {
8023                persisted.add(perm);
8024            }
8025        }
8026
8027        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8028        if (trimCount <= 0) return false;
8029
8030        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8031        for (int i = 0; i < trimCount; i++) {
8032            final UriPermission perm = persisted.get(i);
8033
8034            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8035                    "Trimming grant created at " + perm.persistedCreateTime);
8036
8037            perm.releasePersistableModes(~0);
8038            removeUriPermissionIfNeededLocked(perm);
8039        }
8040
8041        return true;
8042    }
8043
8044    @Override
8045    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8046            String packageName, boolean incoming) {
8047        enforceNotIsolatedCaller("getPersistedUriPermissions");
8048        Preconditions.checkNotNull(packageName, "packageName");
8049
8050        final int callingUid = Binder.getCallingUid();
8051        final IPackageManager pm = AppGlobals.getPackageManager();
8052        try {
8053            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8054            if (packageUid != callingUid) {
8055                throw new SecurityException(
8056                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8057            }
8058        } catch (RemoteException e) {
8059            throw new SecurityException("Failed to verify package name ownership");
8060        }
8061
8062        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8063        synchronized (this) {
8064            if (incoming) {
8065                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8066                        callingUid);
8067                if (perms == null) {
8068                    Slog.w(TAG, "No permission grants found for " + packageName);
8069                } else {
8070                    for (UriPermission perm : perms.values()) {
8071                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8072                            result.add(perm.buildPersistedPublicApiObject());
8073                        }
8074                    }
8075                }
8076            } else {
8077                final int size = mGrantedUriPermissions.size();
8078                for (int i = 0; i < size; i++) {
8079                    final ArrayMap<GrantUri, UriPermission> perms =
8080                            mGrantedUriPermissions.valueAt(i);
8081                    for (UriPermission perm : perms.values()) {
8082                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8083                            result.add(perm.buildPersistedPublicApiObject());
8084                        }
8085                    }
8086                }
8087            }
8088        }
8089        return new ParceledListSlice<android.content.UriPermission>(result);
8090    }
8091
8092    @Override
8093    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8094        synchronized (this) {
8095            ProcessRecord app =
8096                who != null ? getRecordForAppLocked(who) : null;
8097            if (app == null) return;
8098
8099            Message msg = Message.obtain();
8100            msg.what = WAIT_FOR_DEBUGGER_MSG;
8101            msg.obj = app;
8102            msg.arg1 = waiting ? 1 : 0;
8103            mUiHandler.sendMessage(msg);
8104        }
8105    }
8106
8107    @Override
8108    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8109        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8110        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8111        outInfo.availMem = Process.getFreeMemory();
8112        outInfo.totalMem = Process.getTotalMemory();
8113        outInfo.threshold = homeAppMem;
8114        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8115        outInfo.hiddenAppThreshold = cachedAppMem;
8116        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8117                ProcessList.SERVICE_ADJ);
8118        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8119                ProcessList.VISIBLE_APP_ADJ);
8120        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8121                ProcessList.FOREGROUND_APP_ADJ);
8122    }
8123
8124    // =========================================================
8125    // TASK MANAGEMENT
8126    // =========================================================
8127
8128    @Override
8129    public List<IAppTask> getAppTasks(String callingPackage) {
8130        int callingUid = Binder.getCallingUid();
8131        long ident = Binder.clearCallingIdentity();
8132
8133        synchronized(this) {
8134            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8135            try {
8136                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8137
8138                final int N = mRecentTasks.size();
8139                for (int i = 0; i < N; i++) {
8140                    TaskRecord tr = mRecentTasks.get(i);
8141                    // Skip tasks that do not match the caller.  We don't need to verify
8142                    // callingPackage, because we are also limiting to callingUid and know
8143                    // that will limit to the correct security sandbox.
8144                    if (tr.effectiveUid != callingUid) {
8145                        continue;
8146                    }
8147                    Intent intent = tr.getBaseIntent();
8148                    if (intent == null ||
8149                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8150                        continue;
8151                    }
8152                    ActivityManager.RecentTaskInfo taskInfo =
8153                            createRecentTaskInfoFromTaskRecord(tr);
8154                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8155                    list.add(taskImpl);
8156                }
8157            } finally {
8158                Binder.restoreCallingIdentity(ident);
8159            }
8160            return list;
8161        }
8162    }
8163
8164    @Override
8165    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8166        final int callingUid = Binder.getCallingUid();
8167        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8168
8169        synchronized(this) {
8170            if (DEBUG_ALL) Slog.v(
8171                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8172
8173            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8174                    callingUid);
8175
8176            // TODO: Improve with MRU list from all ActivityStacks.
8177            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8178        }
8179
8180        return list;
8181    }
8182
8183    /**
8184     * Creates a new RecentTaskInfo from a TaskRecord.
8185     */
8186    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8187        // Update the task description to reflect any changes in the task stack
8188        tr.updateTaskDescription();
8189
8190        // Compose the recent task info
8191        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8192        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8193        rti.persistentId = tr.taskId;
8194        rti.baseIntent = new Intent(tr.getBaseIntent());
8195        rti.origActivity = tr.origActivity;
8196        rti.description = tr.lastDescription;
8197        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8198        rti.userId = tr.userId;
8199        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8200        rti.firstActiveTime = tr.firstActiveTime;
8201        rti.lastActiveTime = tr.lastActiveTime;
8202        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8203        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8204        rti.numActivities = 0;
8205
8206        ActivityRecord base = null;
8207        ActivityRecord top = null;
8208        ActivityRecord tmp;
8209
8210        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8211            tmp = tr.mActivities.get(i);
8212            if (tmp.finishing) {
8213                continue;
8214            }
8215            base = tmp;
8216            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8217                top = base;
8218            }
8219            rti.numActivities++;
8220        }
8221
8222        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8223        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8224
8225        return rti;
8226    }
8227
8228    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8229        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8230                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8231        if (!allowed) {
8232            if (checkPermission(android.Manifest.permission.GET_TASKS,
8233                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8234                // Temporary compatibility: some existing apps on the system image may
8235                // still be requesting the old permission and not switched to the new
8236                // one; if so, we'll still allow them full access.  This means we need
8237                // to see if they are holding the old permission and are a system app.
8238                try {
8239                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8240                        allowed = true;
8241                        Slog.w(TAG, caller + ": caller " + callingUid
8242                                + " is using old GET_TASKS but privileged; allowing");
8243                    }
8244                } catch (RemoteException e) {
8245                }
8246            }
8247        }
8248        if (!allowed) {
8249            Slog.w(TAG, caller + ": caller " + callingUid
8250                    + " does not hold REAL_GET_TASKS; limiting output");
8251        }
8252        return allowed;
8253    }
8254
8255    @Override
8256    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8257        final int callingUid = Binder.getCallingUid();
8258        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8259                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8260
8261        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8262        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8263        synchronized (this) {
8264            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8265                    callingUid);
8266            final boolean detailed = checkCallingPermission(
8267                    android.Manifest.permission.GET_DETAILED_TASKS)
8268                    == PackageManager.PERMISSION_GRANTED;
8269
8270            final int recentsCount = mRecentTasks.size();
8271            ArrayList<ActivityManager.RecentTaskInfo> res =
8272                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8273
8274            final Set<Integer> includedUsers;
8275            if (includeProfiles) {
8276                includedUsers = getProfileIdsLocked(userId);
8277            } else {
8278                includedUsers = new HashSet<>();
8279            }
8280            includedUsers.add(Integer.valueOf(userId));
8281
8282            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8283                TaskRecord tr = mRecentTasks.get(i);
8284                // Only add calling user or related users recent tasks
8285                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8286                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8287                    continue;
8288                }
8289
8290                // Return the entry if desired by the caller.  We always return
8291                // the first entry, because callers always expect this to be the
8292                // foreground app.  We may filter others if the caller has
8293                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8294                // we should exclude the entry.
8295
8296                if (i == 0
8297                        || withExcluded
8298                        || (tr.intent == null)
8299                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8300                                == 0)) {
8301                    if (!allowed) {
8302                        // If the caller doesn't have the GET_TASKS permission, then only
8303                        // allow them to see a small subset of tasks -- their own and home.
8304                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8305                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8306                            continue;
8307                        }
8308                    }
8309                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8310                        if (tr.stack != null && tr.stack.isHomeStack()) {
8311                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8312                                    "Skipping, home stack task: " + tr);
8313                            continue;
8314                        }
8315                    }
8316                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8317                        // Don't include auto remove tasks that are finished or finishing.
8318                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8319                                "Skipping, auto-remove without activity: " + tr);
8320                        continue;
8321                    }
8322                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8323                            && !tr.isAvailable) {
8324                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8325                                "Skipping, unavail real act: " + tr);
8326                        continue;
8327                    }
8328
8329                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8330                    if (!detailed) {
8331                        rti.baseIntent.replaceExtras((Bundle)null);
8332                    }
8333
8334                    res.add(rti);
8335                    maxNum--;
8336                }
8337            }
8338            return res;
8339        }
8340    }
8341
8342    @Override
8343    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8344        synchronized (this) {
8345            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8346                    "getTaskThumbnail()");
8347            TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id, false);
8348            if (tr != null) {
8349                return tr.getTaskThumbnailLocked();
8350            }
8351        }
8352        return null;
8353    }
8354
8355    @Override
8356    public int addAppTask(IBinder activityToken, Intent intent,
8357            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8358        final int callingUid = Binder.getCallingUid();
8359        final long callingIdent = Binder.clearCallingIdentity();
8360
8361        try {
8362            synchronized (this) {
8363                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8364                if (r == null) {
8365                    throw new IllegalArgumentException("Activity does not exist; token="
8366                            + activityToken);
8367                }
8368                ComponentName comp = intent.getComponent();
8369                if (comp == null) {
8370                    throw new IllegalArgumentException("Intent " + intent
8371                            + " must specify explicit component");
8372                }
8373                if (thumbnail.getWidth() != mThumbnailWidth
8374                        || thumbnail.getHeight() != mThumbnailHeight) {
8375                    throw new IllegalArgumentException("Bad thumbnail size: got "
8376                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8377                            + mThumbnailWidth + "x" + mThumbnailHeight);
8378                }
8379                if (intent.getSelector() != null) {
8380                    intent.setSelector(null);
8381                }
8382                if (intent.getSourceBounds() != null) {
8383                    intent.setSourceBounds(null);
8384                }
8385                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8386                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8387                        // The caller has added this as an auto-remove task...  that makes no
8388                        // sense, so turn off auto-remove.
8389                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8390                    }
8391                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8392                    // Must be a new task.
8393                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8394                }
8395                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8396                    mLastAddedTaskActivity = null;
8397                }
8398                ActivityInfo ainfo = mLastAddedTaskActivity;
8399                if (ainfo == null) {
8400                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8401                            comp, 0, UserHandle.getUserId(callingUid));
8402                    if (ainfo.applicationInfo.uid != callingUid) {
8403                        throw new SecurityException(
8404                                "Can't add task for another application: target uid="
8405                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8406                    }
8407                }
8408
8409                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8410                        intent, description);
8411
8412                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
8413                if (trimIdx >= 0) {
8414                    // If this would have caused a trim, then we'll abort because that
8415                    // means it would be added at the end of the list but then just removed.
8416                    return INVALID_TASK_ID;
8417                }
8418
8419                final int N = mRecentTasks.size();
8420                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8421                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8422                    tr.removedFromRecents();
8423                }
8424
8425                task.inRecents = true;
8426                mRecentTasks.add(task);
8427                r.task.stack.addTask(task, false, false);
8428
8429                task.setLastThumbnail(thumbnail);
8430                task.freeLastThumbnail();
8431
8432                return task.taskId;
8433            }
8434        } finally {
8435            Binder.restoreCallingIdentity(callingIdent);
8436        }
8437    }
8438
8439    @Override
8440    public Point getAppTaskThumbnailSize() {
8441        synchronized (this) {
8442            return new Point(mThumbnailWidth,  mThumbnailHeight);
8443        }
8444    }
8445
8446    @Override
8447    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8448        synchronized (this) {
8449            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8450            if (r != null) {
8451                r.setTaskDescription(td);
8452                r.task.updateTaskDescription();
8453            }
8454        }
8455    }
8456
8457    @Override
8458    public void setTaskResizeable(int taskId, boolean resizeable) {
8459        synchronized (this) {
8460            TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8461            if (task == null) {
8462                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
8463                return;
8464            }
8465            if (task.mResizeable != resizeable) {
8466                task.mResizeable = resizeable;
8467                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8468                mStackSupervisor.resumeTopActivitiesLocked();
8469            }
8470        }
8471    }
8472
8473    @Override
8474    public void resizeTask(int taskId, Rect bounds) {
8475        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8476                "resizeTask()");
8477        long ident = Binder.clearCallingIdentity();
8478        try {
8479            synchronized (this) {
8480                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8481                if (task == null) {
8482                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
8483                    return;
8484                }
8485                mStackSupervisor.resizeTaskLocked(task, bounds);
8486            }
8487        } finally {
8488            Binder.restoreCallingIdentity(ident);
8489        }
8490    }
8491
8492    @Override
8493    public Bitmap getTaskDescriptionIcon(String filename) {
8494        if (!FileUtils.isValidExtFilename(filename)
8495                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8496            throw new IllegalArgumentException("Bad filename: " + filename);
8497        }
8498        return mTaskPersister.getTaskDescriptionIcon(filename);
8499    }
8500
8501    @Override
8502    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8503            throws RemoteException {
8504        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8505                opts.getCustomInPlaceResId() == 0) {
8506            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8507                    "with valid animation");
8508        }
8509        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8510        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8511                opts.getCustomInPlaceResId());
8512        mWindowManager.executeAppTransition();
8513    }
8514
8515    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8516        mRecentTasks.remove(tr);
8517        tr.removedFromRecents();
8518        ComponentName component = tr.getBaseIntent().getComponent();
8519        if (component == null) {
8520            Slog.w(TAG, "No component for base intent of task: " + tr);
8521            return;
8522        }
8523
8524        if (!killProcess) {
8525            return;
8526        }
8527
8528        // Determine if the process(es) for this task should be killed.
8529        final String pkg = component.getPackageName();
8530        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8531        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8532        for (int i = 0; i < pmap.size(); i++) {
8533
8534            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8535            for (int j = 0; j < uids.size(); j++) {
8536                ProcessRecord proc = uids.valueAt(j);
8537                if (proc.userId != tr.userId) {
8538                    // Don't kill process for a different user.
8539                    continue;
8540                }
8541                if (proc == mHomeProcess) {
8542                    // Don't kill the home process along with tasks from the same package.
8543                    continue;
8544                }
8545                if (!proc.pkgList.containsKey(pkg)) {
8546                    // Don't kill process that is not associated with this task.
8547                    continue;
8548                }
8549
8550                for (int k = 0; k < proc.activities.size(); k++) {
8551                    TaskRecord otherTask = proc.activities.get(k).task;
8552                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8553                        // Don't kill process(es) that has an activity in a different task that is
8554                        // also in recents.
8555                        return;
8556                    }
8557                }
8558
8559                // Add process to kill list.
8560                procsToKill.add(proc);
8561            }
8562        }
8563
8564        // Find any running services associated with this app and stop if needed.
8565        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8566
8567        // Kill the running processes.
8568        for (int i = 0; i < procsToKill.size(); i++) {
8569            ProcessRecord pr = procsToKill.get(i);
8570            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8571                pr.kill("remove task", true);
8572            } else {
8573                pr.waitingToKill = "remove task";
8574            }
8575        }
8576    }
8577
8578    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8579        // Remove all tasks with activities in the specified package from the list of recent tasks
8580        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8581            TaskRecord tr = mRecentTasks.get(i);
8582            if (tr.userId != userId) continue;
8583
8584            ComponentName cn = tr.intent.getComponent();
8585            if (cn != null && cn.getPackageName().equals(packageName)) {
8586                // If the package name matches, remove the task.
8587                removeTaskByIdLocked(tr.taskId, true);
8588            }
8589        }
8590    }
8591
8592    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
8593            int userId) {
8594
8595        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8596            TaskRecord tr = mRecentTasks.get(i);
8597            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
8598                continue;
8599            }
8600
8601            ComponentName cn = tr.intent.getComponent();
8602            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
8603                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
8604            if (sameComponent) {
8605                removeTaskByIdLocked(tr.taskId, false);
8606            }
8607        }
8608    }
8609
8610    /**
8611     * Removes the task with the specified task id.
8612     *
8613     * @param taskId Identifier of the task to be removed.
8614     * @param killProcess Kill any process associated with the task if possible.
8615     * @return Returns true if the given task was found and removed.
8616     */
8617    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8618        TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8619        if (tr != null) {
8620            tr.removeTaskActivitiesLocked();
8621            cleanUpRemovedTaskLocked(tr, killProcess);
8622            if (tr.isPersistable) {
8623                notifyTaskPersisterLocked(null, true);
8624            }
8625            return true;
8626        }
8627        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8628        return false;
8629    }
8630
8631    @Override
8632    public boolean removeTask(int taskId) {
8633        synchronized (this) {
8634            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8635                    "removeTask()");
8636            long ident = Binder.clearCallingIdentity();
8637            try {
8638                return removeTaskByIdLocked(taskId, true);
8639            } finally {
8640                Binder.restoreCallingIdentity(ident);
8641            }
8642        }
8643    }
8644
8645    /**
8646     * TODO: Add mController hook
8647     */
8648    @Override
8649    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8650        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
8651
8652        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
8653        synchronized(this) {
8654            moveTaskToFrontLocked(taskId, flags, options);
8655        }
8656    }
8657
8658    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8659        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8660                Binder.getCallingUid(), -1, -1, "Task to front")) {
8661            ActivityOptions.abort(options);
8662            return;
8663        }
8664        final long origId = Binder.clearCallingIdentity();
8665        try {
8666            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8667            if (task == null) {
8668                Slog.d(TAG, "Could not find task for id: "+ taskId);
8669                return;
8670            }
8671            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8672                mStackSupervisor.showLockTaskToast();
8673                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8674                return;
8675            }
8676            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8677            if (prev != null && prev.isRecentsActivity()) {
8678                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8679            }
8680            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
8681        } finally {
8682            Binder.restoreCallingIdentity(origId);
8683        }
8684        ActivityOptions.abort(options);
8685    }
8686
8687    /**
8688     * Moves an activity, and all of the other activities within the same task, to the bottom
8689     * of the history stack.  The activity's order within the task is unchanged.
8690     *
8691     * @param token A reference to the activity we wish to move
8692     * @param nonRoot If false then this only works if the activity is the root
8693     *                of a task; if true it will work for any activity in a task.
8694     * @return Returns true if the move completed, false if not.
8695     */
8696    @Override
8697    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8698        enforceNotIsolatedCaller("moveActivityTaskToBack");
8699        synchronized(this) {
8700            final long origId = Binder.clearCallingIdentity();
8701            try {
8702                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8703                final TaskRecord task = mRecentTasks.taskForIdLocked(taskId);
8704                if (task != null) {
8705                    if (mStackSupervisor.isLockedTask(task)) {
8706                        mStackSupervisor.showLockTaskToast();
8707                        return false;
8708                    }
8709                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
8710                }
8711            } finally {
8712                Binder.restoreCallingIdentity(origId);
8713            }
8714        }
8715        return false;
8716    }
8717
8718    @Override
8719    public void moveTaskBackwards(int task) {
8720        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8721                "moveTaskBackwards()");
8722
8723        synchronized(this) {
8724            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8725                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8726                return;
8727            }
8728            final long origId = Binder.clearCallingIdentity();
8729            moveTaskBackwardsLocked(task);
8730            Binder.restoreCallingIdentity(origId);
8731        }
8732    }
8733
8734    private final void moveTaskBackwardsLocked(int task) {
8735        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8736    }
8737
8738    @Override
8739    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
8740            IActivityContainerCallback callback) throws RemoteException {
8741        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8742                "createActivityContainer()");
8743        synchronized (this) {
8744            if (parentActivityToken == null) {
8745                throw new IllegalArgumentException("parent token must not be null");
8746            }
8747            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
8748            if (r == null) {
8749                return null;
8750            }
8751            if (callback == null) {
8752                throw new IllegalArgumentException("callback must not be null");
8753            }
8754            return mStackSupervisor.createVirtualActivityContainer(r, callback);
8755        }
8756    }
8757
8758    @Override
8759    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8760        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8761                "deleteActivityContainer()");
8762        synchronized (this) {
8763            mStackSupervisor.deleteActivityContainer(container);
8764        }
8765    }
8766
8767    @Override
8768    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
8769        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8770                "createStackOnDisplay()");
8771        synchronized (this) {
8772            final int stackId = mStackSupervisor.getNextStackId();
8773            final ActivityStack stack = mStackSupervisor.createStackOnDisplay(stackId, displayId);
8774            if (stack == null) {
8775                return null;
8776            }
8777            return stack.mActivityContainer;
8778        }
8779    }
8780
8781    @Override
8782    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
8783        synchronized (this) {
8784            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8785            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
8786                return stack.mActivityContainer.getDisplayId();
8787            }
8788            return Display.DEFAULT_DISPLAY;
8789        }
8790    }
8791
8792    @Override
8793    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8794        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8795                "moveTaskToStack()");
8796        if (stackId == HOME_STACK_ID) {
8797            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8798                    new RuntimeException("here").fillInStackTrace());
8799        }
8800        synchronized (this) {
8801            long ident = Binder.clearCallingIdentity();
8802            try {
8803                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
8804                        + " to stackId=" + stackId + " toTop=" + toTop);
8805                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop);
8806            } finally {
8807                Binder.restoreCallingIdentity(ident);
8808            }
8809        }
8810    }
8811
8812    @Override
8813    public void resizeStack(int stackId, Rect bounds) {
8814        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8815                "resizeStack()");
8816        long ident = Binder.clearCallingIdentity();
8817        try {
8818            synchronized (this) {
8819                mStackSupervisor.resizeStackLocked(stackId, bounds);
8820            }
8821        } finally {
8822            Binder.restoreCallingIdentity(ident);
8823        }
8824    }
8825
8826    @Override
8827    public List<StackInfo> getAllStackInfos() {
8828        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8829                "getAllStackInfos()");
8830        long ident = Binder.clearCallingIdentity();
8831        try {
8832            synchronized (this) {
8833                return mStackSupervisor.getAllStackInfosLocked();
8834            }
8835        } finally {
8836            Binder.restoreCallingIdentity(ident);
8837        }
8838    }
8839
8840    @Override
8841    public StackInfo getStackInfo(int stackId) {
8842        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8843                "getStackInfo()");
8844        long ident = Binder.clearCallingIdentity();
8845        try {
8846            synchronized (this) {
8847                return mStackSupervisor.getStackInfoLocked(stackId);
8848            }
8849        } finally {
8850            Binder.restoreCallingIdentity(ident);
8851        }
8852    }
8853
8854    @Override
8855    public boolean isInHomeStack(int taskId) {
8856        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8857                "getStackInfo()");
8858        long ident = Binder.clearCallingIdentity();
8859        try {
8860            synchronized (this) {
8861                TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8862                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8863            }
8864        } finally {
8865            Binder.restoreCallingIdentity(ident);
8866        }
8867    }
8868
8869    @Override
8870    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8871        synchronized(this) {
8872            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8873        }
8874    }
8875
8876    @Override
8877    public void updatePreferredSetupActivity(ComponentName preferredActivity, int userId) {
8878        final int callingUid = Binder.getCallingUid();
8879        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
8880            throw new SecurityException(
8881                    "updatePreferredSetupActivity called from non-system process");
8882        }
8883        synchronized (this) {
8884            if (preferredActivity == null) {
8885                mPreferredSetupActivities.delete(userId);
8886            } else {
8887                mPreferredSetupActivities.put(userId, preferredActivity);
8888            }
8889        }
8890    }
8891
8892    @Override
8893    public void updateDeviceOwner(String packageName) {
8894        final int callingUid = Binder.getCallingUid();
8895        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
8896            throw new SecurityException("updateDeviceOwner called from non-system process");
8897        }
8898        synchronized (this) {
8899            mDeviceOwnerName = packageName;
8900        }
8901    }
8902
8903    @Override
8904    public void updateLockTaskPackages(int userId, String[] packages) {
8905        final int callingUid = Binder.getCallingUid();
8906        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
8907            throw new SecurityException("updateLockTaskPackage called from non-system process");
8908        }
8909        synchronized (this) {
8910            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
8911                    Arrays.toString(packages));
8912            mLockTaskPackages.put(userId, packages);
8913            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
8914        }
8915    }
8916
8917
8918    void startLockTaskModeLocked(TaskRecord task) {
8919        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
8920        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
8921            return;
8922        }
8923
8924        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
8925        // is initiated by system after the pinning request was shown and locked mode is initiated
8926        // by an authorized app directly
8927        final int callingUid = Binder.getCallingUid();
8928        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
8929        long ident = Binder.clearCallingIdentity();
8930        try {
8931            final ActivityStack stack = mStackSupervisor.getFocusedStack();
8932            if (!isSystemInitiated) {
8933                task.mLockTaskUid = callingUid;
8934                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
8935                    // startLockTask() called by app and task mode is lockTaskModeDefault.
8936                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
8937                    StatusBarManagerInternal statusBarManager =
8938                            LocalServices.getService(StatusBarManagerInternal.class);
8939                    if (statusBarManager != null) {
8940                        statusBarManager.showScreenPinningRequest();
8941                    }
8942                    return;
8943                }
8944
8945                if (stack == null || task != stack.topTask()) {
8946                    throw new IllegalArgumentException("Invalid task, not in foreground");
8947                }
8948            }
8949            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
8950                    "Locking fully");
8951            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
8952                    ActivityManager.LOCK_TASK_MODE_PINNED :
8953                    ActivityManager.LOCK_TASK_MODE_LOCKED,
8954                    "startLockTask", true);
8955        } finally {
8956            Binder.restoreCallingIdentity(ident);
8957        }
8958    }
8959
8960    @Override
8961    public void startLockTaskMode(int taskId) {
8962        synchronized (this) {
8963            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8964            if (task != null) {
8965                startLockTaskModeLocked(task);
8966            }
8967        }
8968    }
8969
8970    @Override
8971    public void startLockTaskMode(IBinder token) {
8972        synchronized (this) {
8973            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8974            if (r == null) {
8975                return;
8976            }
8977            final TaskRecord task = r.task;
8978            if (task != null) {
8979                startLockTaskModeLocked(task);
8980            }
8981        }
8982    }
8983
8984    @Override
8985    public void startLockTaskModeOnCurrent() throws RemoteException {
8986        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8987                "startLockTaskModeOnCurrent");
8988        long ident = Binder.clearCallingIdentity();
8989        try {
8990            synchronized (this) {
8991                ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
8992                if (r != null) {
8993                    startLockTaskModeLocked(r.task);
8994                }
8995            }
8996        } finally {
8997            Binder.restoreCallingIdentity(ident);
8998        }
8999    }
9000
9001    @Override
9002    public void stopLockTaskMode() {
9003        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9004        if (lockTask == null) {
9005            // Our work here is done.
9006            return;
9007        }
9008        // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9009        if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9010                Binder.getCallingUid() != lockTask.mLockTaskUid) {
9011            throw new SecurityException("Invalid uid, expected " + lockTask.mLockTaskUid);
9012        }
9013        long ident = Binder.clearCallingIdentity();
9014        try {
9015            Log.d(TAG, "stopLockTaskMode");
9016            // Stop lock task
9017            synchronized (this) {
9018                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9019                        "stopLockTask", true);
9020            }
9021        } finally {
9022            Binder.restoreCallingIdentity(ident);
9023        }
9024    }
9025
9026    @Override
9027    public void stopLockTaskModeOnCurrent() throws RemoteException {
9028        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9029                "stopLockTaskModeOnCurrent");
9030        long ident = Binder.clearCallingIdentity();
9031        try {
9032            stopLockTaskMode();
9033        } finally {
9034            Binder.restoreCallingIdentity(ident);
9035        }
9036    }
9037
9038    @Override
9039    public boolean isInLockTaskMode() {
9040        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9041    }
9042
9043    @Override
9044    public int getLockTaskModeState() {
9045        synchronized (this) {
9046            return mStackSupervisor.getLockTaskModeState();
9047        }
9048    }
9049
9050    @Override
9051    public void showLockTaskEscapeMessage(IBinder token) {
9052        synchronized (this) {
9053            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9054            if (r == null) {
9055                return;
9056            }
9057            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9058        }
9059    }
9060
9061    // =========================================================
9062    // CONTENT PROVIDERS
9063    // =========================================================
9064
9065    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9066        List<ProviderInfo> providers = null;
9067        try {
9068            providers = AppGlobals.getPackageManager().
9069                queryContentProviders(app.processName, app.uid,
9070                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
9071        } catch (RemoteException ex) {
9072        }
9073        if (DEBUG_MU) Slog.v(TAG_MU,
9074                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9075        int userId = app.userId;
9076        if (providers != null) {
9077            int N = providers.size();
9078            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9079            for (int i=0; i<N; i++) {
9080                ProviderInfo cpi =
9081                    (ProviderInfo)providers.get(i);
9082                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9083                        cpi.name, cpi.flags);
9084                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_OWNER) {
9085                    // This is a singleton provider, but a user besides the
9086                    // default user is asking to initialize a process it runs
9087                    // in...  well, no, it doesn't actually run in this process,
9088                    // it runs in the process of the default user.  Get rid of it.
9089                    providers.remove(i);
9090                    N--;
9091                    i--;
9092                    continue;
9093                }
9094
9095                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9096                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9097                if (cpr == null) {
9098                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9099                    mProviderMap.putProviderByClass(comp, cpr);
9100                }
9101                if (DEBUG_MU) Slog.v(TAG_MU,
9102                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9103                app.pubProviders.put(cpi.name, cpr);
9104                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9105                    // Don't add this if it is a platform component that is marked
9106                    // to run in multiple processes, because this is actually
9107                    // part of the framework so doesn't make sense to track as a
9108                    // separate apk in the process.
9109                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9110                            mProcessStats);
9111                }
9112                ensurePackageDexOpt(cpi.applicationInfo.packageName);
9113            }
9114        }
9115        return providers;
9116    }
9117
9118    /**
9119     * Check if {@link ProcessRecord} has a possible chance at accessing the
9120     * given {@link ProviderInfo}. Final permission checking is always done
9121     * in {@link ContentProvider}.
9122     */
9123    private final String checkContentProviderPermissionLocked(
9124            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9125        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9126        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9127        boolean checkedGrants = false;
9128        if (checkUser) {
9129            // Looking for cross-user grants before enforcing the typical cross-users permissions
9130            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
9131            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9132                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9133                    return null;
9134                }
9135                checkedGrants = true;
9136            }
9137            userId = handleIncomingUser(callingPid, callingUid, userId,
9138                    false, ALLOW_NON_FULL,
9139                    "checkContentProviderPermissionLocked " + cpi.authority, null);
9140            if (userId != tmpTargetUserId) {
9141                // When we actually went to determine the final targer user ID, this ended
9142                // up different than our initial check for the authority.  This is because
9143                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9144                // SELF.  So we need to re-check the grants again.
9145                checkedGrants = false;
9146            }
9147        }
9148        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9149                cpi.applicationInfo.uid, cpi.exported)
9150                == PackageManager.PERMISSION_GRANTED) {
9151            return null;
9152        }
9153        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9154                cpi.applicationInfo.uid, cpi.exported)
9155                == PackageManager.PERMISSION_GRANTED) {
9156            return null;
9157        }
9158
9159        PathPermission[] pps = cpi.pathPermissions;
9160        if (pps != null) {
9161            int i = pps.length;
9162            while (i > 0) {
9163                i--;
9164                PathPermission pp = pps[i];
9165                String pprperm = pp.getReadPermission();
9166                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9167                        cpi.applicationInfo.uid, cpi.exported)
9168                        == PackageManager.PERMISSION_GRANTED) {
9169                    return null;
9170                }
9171                String ppwperm = pp.getWritePermission();
9172                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9173                        cpi.applicationInfo.uid, cpi.exported)
9174                        == PackageManager.PERMISSION_GRANTED) {
9175                    return null;
9176                }
9177            }
9178        }
9179        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9180            return null;
9181        }
9182
9183        String msg;
9184        if (!cpi.exported) {
9185            msg = "Permission Denial: opening provider " + cpi.name
9186                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9187                    + ", uid=" + callingUid + ") that is not exported from uid "
9188                    + cpi.applicationInfo.uid;
9189        } else {
9190            msg = "Permission Denial: opening provider " + cpi.name
9191                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9192                    + ", uid=" + callingUid + ") requires "
9193                    + cpi.readPermission + " or " + cpi.writePermission;
9194        }
9195        Slog.w(TAG, msg);
9196        return msg;
9197    }
9198
9199    /**
9200     * Returns if the ContentProvider has granted a uri to callingUid
9201     */
9202    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9203        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9204        if (perms != null) {
9205            for (int i=perms.size()-1; i>=0; i--) {
9206                GrantUri grantUri = perms.keyAt(i);
9207                if (grantUri.sourceUserId == userId || !checkUser) {
9208                    if (matchesProvider(grantUri.uri, cpi)) {
9209                        return true;
9210                    }
9211                }
9212            }
9213        }
9214        return false;
9215    }
9216
9217    /**
9218     * Returns true if the uri authority is one of the authorities specified in the provider.
9219     */
9220    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9221        String uriAuth = uri.getAuthority();
9222        String cpiAuth = cpi.authority;
9223        if (cpiAuth.indexOf(';') == -1) {
9224            return cpiAuth.equals(uriAuth);
9225        }
9226        String[] cpiAuths = cpiAuth.split(";");
9227        int length = cpiAuths.length;
9228        for (int i = 0; i < length; i++) {
9229            if (cpiAuths[i].equals(uriAuth)) return true;
9230        }
9231        return false;
9232    }
9233
9234    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9235            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9236        if (r != null) {
9237            for (int i=0; i<r.conProviders.size(); i++) {
9238                ContentProviderConnection conn = r.conProviders.get(i);
9239                if (conn.provider == cpr) {
9240                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9241                            "Adding provider requested by "
9242                            + r.processName + " from process "
9243                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9244                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9245                    if (stable) {
9246                        conn.stableCount++;
9247                        conn.numStableIncs++;
9248                    } else {
9249                        conn.unstableCount++;
9250                        conn.numUnstableIncs++;
9251                    }
9252                    return conn;
9253                }
9254            }
9255            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9256            if (stable) {
9257                conn.stableCount = 1;
9258                conn.numStableIncs = 1;
9259            } else {
9260                conn.unstableCount = 1;
9261                conn.numUnstableIncs = 1;
9262            }
9263            cpr.connections.add(conn);
9264            r.conProviders.add(conn);
9265            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9266            return conn;
9267        }
9268        cpr.addExternalProcessHandleLocked(externalProcessToken);
9269        return null;
9270    }
9271
9272    boolean decProviderCountLocked(ContentProviderConnection conn,
9273            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9274        if (conn != null) {
9275            cpr = conn.provider;
9276            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9277                    "Removing provider requested by "
9278                    + conn.client.processName + " from process "
9279                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9280                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9281            if (stable) {
9282                conn.stableCount--;
9283            } else {
9284                conn.unstableCount--;
9285            }
9286            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9287                cpr.connections.remove(conn);
9288                conn.client.conProviders.remove(conn);
9289                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9290                return true;
9291            }
9292            return false;
9293        }
9294        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9295        return false;
9296    }
9297
9298    private void checkTime(long startTime, String where) {
9299        long now = SystemClock.elapsedRealtime();
9300        if ((now-startTime) > 1000) {
9301            // If we are taking more than a second, log about it.
9302            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9303        }
9304    }
9305
9306    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9307            String name, IBinder token, boolean stable, int userId) {
9308        ContentProviderRecord cpr;
9309        ContentProviderConnection conn = null;
9310        ProviderInfo cpi = null;
9311
9312        synchronized(this) {
9313            long startTime = SystemClock.elapsedRealtime();
9314
9315            ProcessRecord r = null;
9316            if (caller != null) {
9317                r = getRecordForAppLocked(caller);
9318                if (r == null) {
9319                    throw new SecurityException(
9320                            "Unable to find app for caller " + caller
9321                          + " (pid=" + Binder.getCallingPid()
9322                          + ") when getting content provider " + name);
9323                }
9324            }
9325
9326            boolean checkCrossUser = true;
9327
9328            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9329
9330            // First check if this content provider has been published...
9331            cpr = mProviderMap.getProviderByName(name, userId);
9332            // If that didn't work, check if it exists for user 0 and then
9333            // verify that it's a singleton provider before using it.
9334            if (cpr == null && userId != UserHandle.USER_OWNER) {
9335                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9336                if (cpr != null) {
9337                    cpi = cpr.info;
9338                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9339                            cpi.name, cpi.flags)
9340                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9341                        userId = UserHandle.USER_OWNER;
9342                        checkCrossUser = false;
9343                    } else {
9344                        cpr = null;
9345                        cpi = null;
9346                    }
9347                }
9348            }
9349
9350            boolean providerRunning = cpr != null;
9351            if (providerRunning) {
9352                cpi = cpr.info;
9353                String msg;
9354                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9355                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9356                        != null) {
9357                    throw new SecurityException(msg);
9358                }
9359                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9360
9361                if (r != null && cpr.canRunHere(r)) {
9362                    // This provider has been published or is in the process
9363                    // of being published...  but it is also allowed to run
9364                    // in the caller's process, so don't make a connection
9365                    // and just let the caller instantiate its own instance.
9366                    ContentProviderHolder holder = cpr.newHolder(null);
9367                    // don't give caller the provider object, it needs
9368                    // to make its own.
9369                    holder.provider = null;
9370                    return holder;
9371                }
9372
9373                final long origId = Binder.clearCallingIdentity();
9374
9375                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9376
9377                // In this case the provider instance already exists, so we can
9378                // return it right away.
9379                conn = incProviderCountLocked(r, cpr, token, stable);
9380                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9381                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9382                        // If this is a perceptible app accessing the provider,
9383                        // make sure to count it as being accessed and thus
9384                        // back up on the LRU list.  This is good because
9385                        // content providers are often expensive to start.
9386                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9387                        updateLruProcessLocked(cpr.proc, false, null);
9388                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9389                    }
9390                }
9391
9392                if (cpr.proc != null) {
9393                    if (false) {
9394                        if (cpr.name.flattenToShortString().equals(
9395                                "com.android.providers.calendar/.CalendarProvider2")) {
9396                            Slog.v(TAG, "****************** KILLING "
9397                                + cpr.name.flattenToShortString());
9398                            Process.killProcess(cpr.proc.pid);
9399                        }
9400                    }
9401                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9402                    boolean success = updateOomAdjLocked(cpr.proc);
9403                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9404                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
9405                    // NOTE: there is still a race here where a signal could be
9406                    // pending on the process even though we managed to update its
9407                    // adj level.  Not sure what to do about this, but at least
9408                    // the race is now smaller.
9409                    if (!success) {
9410                        // Uh oh...  it looks like the provider's process
9411                        // has been killed on us.  We need to wait for a new
9412                        // process to be started, and make sure its death
9413                        // doesn't kill our process.
9414                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
9415                                + " is crashing; detaching " + r);
9416                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9417                        checkTime(startTime, "getContentProviderImpl: before appDied");
9418                        appDiedLocked(cpr.proc);
9419                        checkTime(startTime, "getContentProviderImpl: after appDied");
9420                        if (!lastRef) {
9421                            // This wasn't the last ref our process had on
9422                            // the provider...  we have now been killed, bail.
9423                            return null;
9424                        }
9425                        providerRunning = false;
9426                        conn = null;
9427                    }
9428                }
9429
9430                Binder.restoreCallingIdentity(origId);
9431            }
9432
9433            boolean singleton;
9434            if (!providerRunning) {
9435                try {
9436                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9437                    cpi = AppGlobals.getPackageManager().
9438                        resolveContentProvider(name,
9439                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9440                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9441                } catch (RemoteException ex) {
9442                }
9443                if (cpi == null) {
9444                    return null;
9445                }
9446                // If the provider is a singleton AND
9447                // (it's a call within the same user || the provider is a
9448                // privileged app)
9449                // Then allow connecting to the singleton provider
9450                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9451                        cpi.name, cpi.flags)
9452                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9453                if (singleton) {
9454                    userId = UserHandle.USER_OWNER;
9455                }
9456                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9457                checkTime(startTime, "getContentProviderImpl: got app info for user");
9458
9459                String msg;
9460                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9461                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9462                        != null) {
9463                    throw new SecurityException(msg);
9464                }
9465                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9466
9467                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9468                        && !cpi.processName.equals("system")) {
9469                    // If this content provider does not run in the system
9470                    // process, and the system is not yet ready to run other
9471                    // processes, then fail fast instead of hanging.
9472                    throw new IllegalArgumentException(
9473                            "Attempt to launch content provider before system ready");
9474                }
9475
9476                // Make sure that the user who owns this provider is running.  If not,
9477                // we don't want to allow it to run.
9478                if (!isUserRunningLocked(userId, false)) {
9479                    Slog.w(TAG, "Unable to launch app "
9480                            + cpi.applicationInfo.packageName + "/"
9481                            + cpi.applicationInfo.uid + " for provider "
9482                            + name + ": user " + userId + " is stopped");
9483                    return null;
9484                }
9485
9486                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9487                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9488                cpr = mProviderMap.getProviderByClass(comp, userId);
9489                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9490                final boolean firstClass = cpr == null;
9491                if (firstClass) {
9492                    final long ident = Binder.clearCallingIdentity();
9493                    try {
9494                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9495                        ApplicationInfo ai =
9496                            AppGlobals.getPackageManager().
9497                                getApplicationInfo(
9498                                        cpi.applicationInfo.packageName,
9499                                        STOCK_PM_FLAGS, userId);
9500                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9501                        if (ai == null) {
9502                            Slog.w(TAG, "No package info for content provider "
9503                                    + cpi.name);
9504                            return null;
9505                        }
9506                        ai = getAppInfoForUser(ai, userId);
9507                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9508                    } catch (RemoteException ex) {
9509                        // pm is in same process, this will never happen.
9510                    } finally {
9511                        Binder.restoreCallingIdentity(ident);
9512                    }
9513                }
9514
9515                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9516
9517                if (r != null && cpr.canRunHere(r)) {
9518                    // If this is a multiprocess provider, then just return its
9519                    // info and allow the caller to instantiate it.  Only do
9520                    // this if the provider is the same user as the caller's
9521                    // process, or can run as root (so can be in any process).
9522                    return cpr.newHolder(null);
9523                }
9524
9525                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
9526                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
9527                            + cpr.info.name + " callers=" + Debug.getCallers(6));
9528
9529                // This is single process, and our app is now connecting to it.
9530                // See if we are already in the process of launching this
9531                // provider.
9532                final int N = mLaunchingProviders.size();
9533                int i;
9534                for (i = 0; i < N; i++) {
9535                    if (mLaunchingProviders.get(i) == cpr) {
9536                        break;
9537                    }
9538                }
9539
9540                // If the provider is not already being launched, then get it
9541                // started.
9542                if (i >= N) {
9543                    final long origId = Binder.clearCallingIdentity();
9544
9545                    try {
9546                        // Content provider is now in use, its package can't be stopped.
9547                        try {
9548                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9549                            AppGlobals.getPackageManager().setPackageStoppedState(
9550                                    cpr.appInfo.packageName, false, userId);
9551                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9552                        } catch (RemoteException e) {
9553                        } catch (IllegalArgumentException e) {
9554                            Slog.w(TAG, "Failed trying to unstop package "
9555                                    + cpr.appInfo.packageName + ": " + e);
9556                        }
9557
9558                        // Use existing process if already started
9559                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9560                        ProcessRecord proc = getProcessRecordLocked(
9561                                cpi.processName, cpr.appInfo.uid, false);
9562                        if (proc != null && proc.thread != null) {
9563                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
9564                                    "Installing in existing process " + proc);
9565                            if (!proc.pubProviders.containsKey(cpi.name)) {
9566                                checkTime(startTime, "getContentProviderImpl: scheduling install");
9567                                proc.pubProviders.put(cpi.name, cpr);
9568                                try {
9569                                    proc.thread.scheduleInstallProvider(cpi);
9570                                } catch (RemoteException e) {
9571                                }
9572                            }
9573                        } else {
9574                            checkTime(startTime, "getContentProviderImpl: before start process");
9575                            proc = startProcessLocked(cpi.processName,
9576                                    cpr.appInfo, false, 0, "content provider",
9577                                    new ComponentName(cpi.applicationInfo.packageName,
9578                                            cpi.name), false, false, false);
9579                            checkTime(startTime, "getContentProviderImpl: after start process");
9580                            if (proc == null) {
9581                                Slog.w(TAG, "Unable to launch app "
9582                                        + cpi.applicationInfo.packageName + "/"
9583                                        + cpi.applicationInfo.uid + " for provider "
9584                                        + name + ": process is bad");
9585                                return null;
9586                            }
9587                        }
9588                        cpr.launchingApp = proc;
9589                        mLaunchingProviders.add(cpr);
9590                    } finally {
9591                        Binder.restoreCallingIdentity(origId);
9592                    }
9593                }
9594
9595                checkTime(startTime, "getContentProviderImpl: updating data structures");
9596
9597                // Make sure the provider is published (the same provider class
9598                // may be published under multiple names).
9599                if (firstClass) {
9600                    mProviderMap.putProviderByClass(comp, cpr);
9601                }
9602
9603                mProviderMap.putProviderByName(name, cpr);
9604                conn = incProviderCountLocked(r, cpr, token, stable);
9605                if (conn != null) {
9606                    conn.waiting = true;
9607                }
9608            }
9609            checkTime(startTime, "getContentProviderImpl: done!");
9610        }
9611
9612        // Wait for the provider to be published...
9613        synchronized (cpr) {
9614            while (cpr.provider == null) {
9615                if (cpr.launchingApp == null) {
9616                    Slog.w(TAG, "Unable to launch app "
9617                            + cpi.applicationInfo.packageName + "/"
9618                            + cpi.applicationInfo.uid + " for provider "
9619                            + name + ": launching app became null");
9620                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9621                            UserHandle.getUserId(cpi.applicationInfo.uid),
9622                            cpi.applicationInfo.packageName,
9623                            cpi.applicationInfo.uid, name);
9624                    return null;
9625                }
9626                try {
9627                    if (DEBUG_MU) Slog.v(TAG_MU,
9628                            "Waiting to start provider " + cpr
9629                            + " launchingApp=" + cpr.launchingApp);
9630                    if (conn != null) {
9631                        conn.waiting = true;
9632                    }
9633                    cpr.wait();
9634                } catch (InterruptedException ex) {
9635                } finally {
9636                    if (conn != null) {
9637                        conn.waiting = false;
9638                    }
9639                }
9640            }
9641        }
9642        return cpr != null ? cpr.newHolder(conn) : null;
9643    }
9644
9645    @Override
9646    public final ContentProviderHolder getContentProvider(
9647            IApplicationThread caller, String name, int userId, boolean stable) {
9648        enforceNotIsolatedCaller("getContentProvider");
9649        if (caller == null) {
9650            String msg = "null IApplicationThread when getting content provider "
9651                    + name;
9652            Slog.w(TAG, msg);
9653            throw new SecurityException(msg);
9654        }
9655        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9656        // with cross-user grant.
9657        return getContentProviderImpl(caller, name, null, stable, userId);
9658    }
9659
9660    public ContentProviderHolder getContentProviderExternal(
9661            String name, int userId, IBinder token) {
9662        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9663            "Do not have permission in call getContentProviderExternal()");
9664        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9665                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9666        return getContentProviderExternalUnchecked(name, token, userId);
9667    }
9668
9669    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9670            IBinder token, int userId) {
9671        return getContentProviderImpl(null, name, token, true, userId);
9672    }
9673
9674    /**
9675     * Drop a content provider from a ProcessRecord's bookkeeping
9676     */
9677    public void removeContentProvider(IBinder connection, boolean stable) {
9678        enforceNotIsolatedCaller("removeContentProvider");
9679        long ident = Binder.clearCallingIdentity();
9680        try {
9681            synchronized (this) {
9682                ContentProviderConnection conn;
9683                try {
9684                    conn = (ContentProviderConnection)connection;
9685                } catch (ClassCastException e) {
9686                    String msg ="removeContentProvider: " + connection
9687                            + " not a ContentProviderConnection";
9688                    Slog.w(TAG, msg);
9689                    throw new IllegalArgumentException(msg);
9690                }
9691                if (conn == null) {
9692                    throw new NullPointerException("connection is null");
9693                }
9694                if (decProviderCountLocked(conn, null, null, stable)) {
9695                    updateOomAdjLocked();
9696                }
9697            }
9698        } finally {
9699            Binder.restoreCallingIdentity(ident);
9700        }
9701    }
9702
9703    public void removeContentProviderExternal(String name, IBinder token) {
9704        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9705            "Do not have permission in call removeContentProviderExternal()");
9706        int userId = UserHandle.getCallingUserId();
9707        long ident = Binder.clearCallingIdentity();
9708        try {
9709            removeContentProviderExternalUnchecked(name, token, userId);
9710        } finally {
9711            Binder.restoreCallingIdentity(ident);
9712        }
9713    }
9714
9715    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9716        synchronized (this) {
9717            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9718            if(cpr == null) {
9719                //remove from mProvidersByClass
9720                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
9721                return;
9722            }
9723
9724            //update content provider record entry info
9725            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9726            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9727            if (localCpr.hasExternalProcessHandles()) {
9728                if (localCpr.removeExternalProcessHandleLocked(token)) {
9729                    updateOomAdjLocked();
9730                } else {
9731                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9732                            + " with no external reference for token: "
9733                            + token + ".");
9734                }
9735            } else {
9736                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9737                        + " with no external references.");
9738            }
9739        }
9740    }
9741
9742    public final void publishContentProviders(IApplicationThread caller,
9743            List<ContentProviderHolder> providers) {
9744        if (providers == null) {
9745            return;
9746        }
9747
9748        enforceNotIsolatedCaller("publishContentProviders");
9749        synchronized (this) {
9750            final ProcessRecord r = getRecordForAppLocked(caller);
9751            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9752            if (r == null) {
9753                throw new SecurityException(
9754                        "Unable to find app for caller " + caller
9755                      + " (pid=" + Binder.getCallingPid()
9756                      + ") when publishing content providers");
9757            }
9758
9759            final long origId = Binder.clearCallingIdentity();
9760
9761            final int N = providers.size();
9762            for (int i=0; i<N; i++) {
9763                ContentProviderHolder src = providers.get(i);
9764                if (src == null || src.info == null || src.provider == null) {
9765                    continue;
9766                }
9767                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9768                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9769                if (dst != null) {
9770                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9771                    mProviderMap.putProviderByClass(comp, dst);
9772                    String names[] = dst.info.authority.split(";");
9773                    for (int j = 0; j < names.length; j++) {
9774                        mProviderMap.putProviderByName(names[j], dst);
9775                    }
9776
9777                    int NL = mLaunchingProviders.size();
9778                    int j;
9779                    for (j=0; j<NL; j++) {
9780                        if (mLaunchingProviders.get(j) == dst) {
9781                            mLaunchingProviders.remove(j);
9782                            j--;
9783                            NL--;
9784                        }
9785                    }
9786                    synchronized (dst) {
9787                        dst.provider = src.provider;
9788                        dst.proc = r;
9789                        dst.notifyAll();
9790                    }
9791                    updateOomAdjLocked(r);
9792                }
9793            }
9794
9795            Binder.restoreCallingIdentity(origId);
9796        }
9797    }
9798
9799    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9800        ContentProviderConnection conn;
9801        try {
9802            conn = (ContentProviderConnection)connection;
9803        } catch (ClassCastException e) {
9804            String msg ="refContentProvider: " + connection
9805                    + " not a ContentProviderConnection";
9806            Slog.w(TAG, msg);
9807            throw new IllegalArgumentException(msg);
9808        }
9809        if (conn == null) {
9810            throw new NullPointerException("connection is null");
9811        }
9812
9813        synchronized (this) {
9814            if (stable > 0) {
9815                conn.numStableIncs += stable;
9816            }
9817            stable = conn.stableCount + stable;
9818            if (stable < 0) {
9819                throw new IllegalStateException("stableCount < 0: " + stable);
9820            }
9821
9822            if (unstable > 0) {
9823                conn.numUnstableIncs += unstable;
9824            }
9825            unstable = conn.unstableCount + unstable;
9826            if (unstable < 0) {
9827                throw new IllegalStateException("unstableCount < 0: " + unstable);
9828            }
9829
9830            if ((stable+unstable) <= 0) {
9831                throw new IllegalStateException("ref counts can't go to zero here: stable="
9832                        + stable + " unstable=" + unstable);
9833            }
9834            conn.stableCount = stable;
9835            conn.unstableCount = unstable;
9836            return !conn.dead;
9837        }
9838    }
9839
9840    public void unstableProviderDied(IBinder connection) {
9841        ContentProviderConnection conn;
9842        try {
9843            conn = (ContentProviderConnection)connection;
9844        } catch (ClassCastException e) {
9845            String msg ="refContentProvider: " + connection
9846                    + " not a ContentProviderConnection";
9847            Slog.w(TAG, msg);
9848            throw new IllegalArgumentException(msg);
9849        }
9850        if (conn == null) {
9851            throw new NullPointerException("connection is null");
9852        }
9853
9854        // Safely retrieve the content provider associated with the connection.
9855        IContentProvider provider;
9856        synchronized (this) {
9857            provider = conn.provider.provider;
9858        }
9859
9860        if (provider == null) {
9861            // Um, yeah, we're way ahead of you.
9862            return;
9863        }
9864
9865        // Make sure the caller is being honest with us.
9866        if (provider.asBinder().pingBinder()) {
9867            // Er, no, still looks good to us.
9868            synchronized (this) {
9869                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9870                        + " says " + conn + " died, but we don't agree");
9871                return;
9872            }
9873        }
9874
9875        // Well look at that!  It's dead!
9876        synchronized (this) {
9877            if (conn.provider.provider != provider) {
9878                // But something changed...  good enough.
9879                return;
9880            }
9881
9882            ProcessRecord proc = conn.provider.proc;
9883            if (proc == null || proc.thread == null) {
9884                // Seems like the process is already cleaned up.
9885                return;
9886            }
9887
9888            // As far as we're concerned, this is just like receiving a
9889            // death notification...  just a bit prematurely.
9890            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9891                    + ") early provider death");
9892            final long ident = Binder.clearCallingIdentity();
9893            try {
9894                appDiedLocked(proc);
9895            } finally {
9896                Binder.restoreCallingIdentity(ident);
9897            }
9898        }
9899    }
9900
9901    @Override
9902    public void appNotRespondingViaProvider(IBinder connection) {
9903        enforceCallingPermission(
9904                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9905
9906        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9907        if (conn == null) {
9908            Slog.w(TAG, "ContentProviderConnection is null");
9909            return;
9910        }
9911
9912        final ProcessRecord host = conn.provider.proc;
9913        if (host == null) {
9914            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9915            return;
9916        }
9917
9918        final long token = Binder.clearCallingIdentity();
9919        try {
9920            appNotResponding(host, null, null, false, "ContentProvider not responding");
9921        } finally {
9922            Binder.restoreCallingIdentity(token);
9923        }
9924    }
9925
9926    public final void installSystemProviders() {
9927        List<ProviderInfo> providers;
9928        synchronized (this) {
9929            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9930            providers = generateApplicationProvidersLocked(app);
9931            if (providers != null) {
9932                for (int i=providers.size()-1; i>=0; i--) {
9933                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9934                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9935                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9936                                + ": not system .apk");
9937                        providers.remove(i);
9938                    }
9939                }
9940            }
9941        }
9942        if (providers != null) {
9943            mSystemThread.installSystemProviders(providers);
9944        }
9945
9946        mCoreSettingsObserver = new CoreSettingsObserver(this);
9947
9948        //mUsageStatsService.monitorPackages();
9949    }
9950
9951    /**
9952     * Allows apps to retrieve the MIME type of a URI.
9953     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9954     * users, then it does not need permission to access the ContentProvider.
9955     * Either, it needs cross-user uri grants.
9956     *
9957     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9958     *
9959     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9960     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9961     */
9962    public String getProviderMimeType(Uri uri, int userId) {
9963        enforceNotIsolatedCaller("getProviderMimeType");
9964        final String name = uri.getAuthority();
9965        int callingUid = Binder.getCallingUid();
9966        int callingPid = Binder.getCallingPid();
9967        long ident = 0;
9968        boolean clearedIdentity = false;
9969        userId = unsafeConvertIncomingUser(userId);
9970        if (canClearIdentity(callingPid, callingUid, userId)) {
9971            clearedIdentity = true;
9972            ident = Binder.clearCallingIdentity();
9973        }
9974        ContentProviderHolder holder = null;
9975        try {
9976            holder = getContentProviderExternalUnchecked(name, null, userId);
9977            if (holder != null) {
9978                return holder.provider.getType(uri);
9979            }
9980        } catch (RemoteException e) {
9981            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9982            return null;
9983        } finally {
9984            // We need to clear the identity to call removeContentProviderExternalUnchecked
9985            if (!clearedIdentity) {
9986                ident = Binder.clearCallingIdentity();
9987            }
9988            try {
9989                if (holder != null) {
9990                    removeContentProviderExternalUnchecked(name, null, userId);
9991                }
9992            } finally {
9993                Binder.restoreCallingIdentity(ident);
9994            }
9995        }
9996
9997        return null;
9998    }
9999
10000    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
10001        if (UserHandle.getUserId(callingUid) == userId) {
10002            return true;
10003        }
10004        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
10005                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
10006                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
10007                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
10008                return true;
10009        }
10010        return false;
10011    }
10012
10013    // =========================================================
10014    // GLOBAL MANAGEMENT
10015    // =========================================================
10016
10017    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
10018            boolean isolated, int isolatedUid) {
10019        String proc = customProcess != null ? customProcess : info.processName;
10020        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10021        final int userId = UserHandle.getUserId(info.uid);
10022        int uid = info.uid;
10023        if (isolated) {
10024            if (isolatedUid == 0) {
10025                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
10026                while (true) {
10027                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
10028                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
10029                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
10030                    }
10031                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
10032                    mNextIsolatedProcessUid++;
10033                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
10034                        // No process for this uid, use it.
10035                        break;
10036                    }
10037                    stepsLeft--;
10038                    if (stepsLeft <= 0) {
10039                        return null;
10040                    }
10041                }
10042            } else {
10043                // Special case for startIsolatedProcess (internal only), where
10044                // the uid of the isolated process is specified by the caller.
10045                uid = isolatedUid;
10046            }
10047        }
10048        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
10049        if (!mBooted && !mBooting
10050                && userId == UserHandle.USER_OWNER
10051                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10052            r.persistent = true;
10053        }
10054        addProcessNameLocked(r);
10055        return r;
10056    }
10057
10058    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
10059            String abiOverride) {
10060        ProcessRecord app;
10061        if (!isolated) {
10062            app = getProcessRecordLocked(info.processName, info.uid, true);
10063        } else {
10064            app = null;
10065        }
10066
10067        if (app == null) {
10068            app = newProcessRecordLocked(info, null, isolated, 0);
10069            updateLruProcessLocked(app, false, null);
10070            updateOomAdjLocked();
10071        }
10072
10073        // This package really, really can not be stopped.
10074        try {
10075            AppGlobals.getPackageManager().setPackageStoppedState(
10076                    info.packageName, false, UserHandle.getUserId(app.uid));
10077        } catch (RemoteException e) {
10078        } catch (IllegalArgumentException e) {
10079            Slog.w(TAG, "Failed trying to unstop package "
10080                    + info.packageName + ": " + e);
10081        }
10082
10083        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10084            app.persistent = true;
10085            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10086        }
10087        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10088            mPersistentStartingProcesses.add(app);
10089            startProcessLocked(app, "added application", app.processName, abiOverride,
10090                    null /* entryPoint */, null /* entryPointArgs */);
10091        }
10092
10093        return app;
10094    }
10095
10096    public void unhandledBack() {
10097        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10098                "unhandledBack()");
10099
10100        synchronized(this) {
10101            final long origId = Binder.clearCallingIdentity();
10102            try {
10103                getFocusedStack().unhandledBackLocked();
10104            } finally {
10105                Binder.restoreCallingIdentity(origId);
10106            }
10107        }
10108    }
10109
10110    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10111        enforceNotIsolatedCaller("openContentUri");
10112        final int userId = UserHandle.getCallingUserId();
10113        String name = uri.getAuthority();
10114        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10115        ParcelFileDescriptor pfd = null;
10116        if (cph != null) {
10117            // We record the binder invoker's uid in thread-local storage before
10118            // going to the content provider to open the file.  Later, in the code
10119            // that handles all permissions checks, we look for this uid and use
10120            // that rather than the Activity Manager's own uid.  The effect is that
10121            // we do the check against the caller's permissions even though it looks
10122            // to the content provider like the Activity Manager itself is making
10123            // the request.
10124            Binder token = new Binder();
10125            sCallerIdentity.set(new Identity(
10126                    token, Binder.getCallingPid(), Binder.getCallingUid()));
10127            try {
10128                pfd = cph.provider.openFile(null, uri, "r", null, token);
10129            } catch (FileNotFoundException e) {
10130                // do nothing; pfd will be returned null
10131            } finally {
10132                // Ensure that whatever happens, we clean up the identity state
10133                sCallerIdentity.remove();
10134                // Ensure we're done with the provider.
10135                removeContentProviderExternalUnchecked(name, null, userId);
10136            }
10137        } else {
10138            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10139        }
10140        return pfd;
10141    }
10142
10143    // Actually is sleeping or shutting down or whatever else in the future
10144    // is an inactive state.
10145    public boolean isSleepingOrShuttingDown() {
10146        return isSleeping() || mShuttingDown;
10147    }
10148
10149    public boolean isSleeping() {
10150        return mSleeping;
10151    }
10152
10153    void onWakefulnessChanged(int wakefulness) {
10154        synchronized(this) {
10155            mWakefulness = wakefulness;
10156            updateSleepIfNeededLocked();
10157        }
10158    }
10159
10160    void finishRunningVoiceLocked() {
10161        if (mRunningVoice != null) {
10162            mRunningVoice = null;
10163            updateSleepIfNeededLocked();
10164        }
10165    }
10166
10167    void startTimeTrackingFocusedActivityLocked() {
10168        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
10169            mCurAppTimeTracker.start(mFocusedActivity.packageName);
10170        }
10171    }
10172
10173    void updateSleepIfNeededLocked() {
10174        if (mSleeping && !shouldSleepLocked()) {
10175            mSleeping = false;
10176            startTimeTrackingFocusedActivityLocked();
10177            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
10178            mStackSupervisor.comeOutOfSleepIfNeededLocked();
10179            updateOomAdjLocked();
10180        } else if (!mSleeping && shouldSleepLocked()) {
10181            mSleeping = true;
10182            if (mCurAppTimeTracker != null) {
10183                mCurAppTimeTracker.stop();
10184            }
10185            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
10186            mStackSupervisor.goingToSleepLocked();
10187            updateOomAdjLocked();
10188
10189            // Initialize the wake times of all processes.
10190            checkExcessivePowerUsageLocked(false);
10191            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10192            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10193            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10194        }
10195    }
10196
10197    private boolean shouldSleepLocked() {
10198        // Resume applications while running a voice interactor.
10199        if (mRunningVoice != null) {
10200            return false;
10201        }
10202
10203        // TODO: Transform the lock screen state into a sleep token instead.
10204        switch (mWakefulness) {
10205            case PowerManagerInternal.WAKEFULNESS_AWAKE:
10206            case PowerManagerInternal.WAKEFULNESS_DREAMING:
10207            case PowerManagerInternal.WAKEFULNESS_DOZING:
10208                // Pause applications whenever the lock screen is shown or any sleep
10209                // tokens have been acquired.
10210                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
10211            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10212            default:
10213                // If we're asleep then pause applications unconditionally.
10214                return true;
10215        }
10216    }
10217
10218    /** Pokes the task persister. */
10219    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10220        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10221            // Never persist the home stack.
10222            return;
10223        }
10224        mTaskPersister.wakeup(task, flush);
10225    }
10226
10227    /** Notifies all listeners when the task stack has changed. */
10228    void notifyTaskStackChangedLocked() {
10229        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10230        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10231        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10232    }
10233
10234    @Override
10235    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
10236        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
10237    }
10238
10239    @Override
10240    public boolean shutdown(int timeout) {
10241        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10242                != PackageManager.PERMISSION_GRANTED) {
10243            throw new SecurityException("Requires permission "
10244                    + android.Manifest.permission.SHUTDOWN);
10245        }
10246
10247        boolean timedout = false;
10248
10249        synchronized(this) {
10250            mShuttingDown = true;
10251            updateEventDispatchingLocked();
10252            timedout = mStackSupervisor.shutdownLocked(timeout);
10253        }
10254
10255        mAppOpsService.shutdown();
10256        if (mUsageStatsService != null) {
10257            mUsageStatsService.prepareShutdown();
10258        }
10259        mBatteryStatsService.shutdown();
10260        synchronized (this) {
10261            mProcessStats.shutdownLocked();
10262            notifyTaskPersisterLocked(null, true);
10263        }
10264
10265        return timedout;
10266    }
10267
10268    public final void activitySlept(IBinder token) {
10269        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
10270
10271        final long origId = Binder.clearCallingIdentity();
10272
10273        synchronized (this) {
10274            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10275            if (r != null) {
10276                mStackSupervisor.activitySleptLocked(r);
10277            }
10278        }
10279
10280        Binder.restoreCallingIdentity(origId);
10281    }
10282
10283    private String lockScreenShownToString() {
10284        switch (mLockScreenShown) {
10285            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10286            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10287            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10288            default: return "Unknown=" + mLockScreenShown;
10289        }
10290    }
10291
10292    void logLockScreen(String msg) {
10293        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
10294                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10295                + PowerManagerInternal.wakefulnessToString(mWakefulness)
10296                + " mSleeping=" + mSleeping);
10297    }
10298
10299    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
10300        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
10301        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
10302            if (mRunningVoice == null) {
10303                mVoiceWakeLock.acquire();
10304                updateSleepIfNeededLocked();
10305            }
10306            mRunningVoice = session;
10307        }
10308    }
10309
10310    private void updateEventDispatchingLocked() {
10311        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10312    }
10313
10314    public void setLockScreenShown(boolean shown) {
10315        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10316                != PackageManager.PERMISSION_GRANTED) {
10317            throw new SecurityException("Requires permission "
10318                    + android.Manifest.permission.DEVICE_POWER);
10319        }
10320
10321        synchronized(this) {
10322            long ident = Binder.clearCallingIdentity();
10323            try {
10324                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10325                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10326                updateSleepIfNeededLocked();
10327            } finally {
10328                Binder.restoreCallingIdentity(ident);
10329            }
10330        }
10331    }
10332
10333    @Override
10334    public void stopAppSwitches() {
10335        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10336                != PackageManager.PERMISSION_GRANTED) {
10337            throw new SecurityException("Requires permission "
10338                    + android.Manifest.permission.STOP_APP_SWITCHES);
10339        }
10340
10341        synchronized(this) {
10342            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10343                    + APP_SWITCH_DELAY_TIME;
10344            mDidAppSwitch = false;
10345            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10346            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10347            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10348        }
10349    }
10350
10351    public void resumeAppSwitches() {
10352        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10353                != PackageManager.PERMISSION_GRANTED) {
10354            throw new SecurityException("Requires permission "
10355                    + android.Manifest.permission.STOP_APP_SWITCHES);
10356        }
10357
10358        synchronized(this) {
10359            // Note that we don't execute any pending app switches... we will
10360            // let those wait until either the timeout, or the next start
10361            // activity request.
10362            mAppSwitchesAllowedTime = 0;
10363        }
10364    }
10365
10366    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10367            int callingPid, int callingUid, String name) {
10368        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10369            return true;
10370        }
10371
10372        int perm = checkComponentPermission(
10373                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10374                sourceUid, -1, true);
10375        if (perm == PackageManager.PERMISSION_GRANTED) {
10376            return true;
10377        }
10378
10379        // If the actual IPC caller is different from the logical source, then
10380        // also see if they are allowed to control app switches.
10381        if (callingUid != -1 && callingUid != sourceUid) {
10382            perm = checkComponentPermission(
10383                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10384                    callingUid, -1, true);
10385            if (perm == PackageManager.PERMISSION_GRANTED) {
10386                return true;
10387            }
10388        }
10389
10390        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10391        return false;
10392    }
10393
10394    public void setDebugApp(String packageName, boolean waitForDebugger,
10395            boolean persistent) {
10396        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10397                "setDebugApp()");
10398
10399        long ident = Binder.clearCallingIdentity();
10400        try {
10401            // Note that this is not really thread safe if there are multiple
10402            // callers into it at the same time, but that's not a situation we
10403            // care about.
10404            if (persistent) {
10405                final ContentResolver resolver = mContext.getContentResolver();
10406                Settings.Global.putString(
10407                    resolver, Settings.Global.DEBUG_APP,
10408                    packageName);
10409                Settings.Global.putInt(
10410                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10411                    waitForDebugger ? 1 : 0);
10412            }
10413
10414            synchronized (this) {
10415                if (!persistent) {
10416                    mOrigDebugApp = mDebugApp;
10417                    mOrigWaitForDebugger = mWaitForDebugger;
10418                }
10419                mDebugApp = packageName;
10420                mWaitForDebugger = waitForDebugger;
10421                mDebugTransient = !persistent;
10422                if (packageName != null) {
10423                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10424                            false, UserHandle.USER_ALL, "set debug app");
10425                }
10426            }
10427        } finally {
10428            Binder.restoreCallingIdentity(ident);
10429        }
10430    }
10431
10432    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10433        synchronized (this) {
10434            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10435            if (!isDebuggable) {
10436                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10437                    throw new SecurityException("Process not debuggable: " + app.packageName);
10438                }
10439            }
10440
10441            mOpenGlTraceApp = processName;
10442        }
10443    }
10444
10445    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10446        synchronized (this) {
10447            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10448            if (!isDebuggable) {
10449                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10450                    throw new SecurityException("Process not debuggable: " + app.packageName);
10451                }
10452            }
10453            mProfileApp = processName;
10454            mProfileFile = profilerInfo.profileFile;
10455            if (mProfileFd != null) {
10456                try {
10457                    mProfileFd.close();
10458                } catch (IOException e) {
10459                }
10460                mProfileFd = null;
10461            }
10462            mProfileFd = profilerInfo.profileFd;
10463            mSamplingInterval = profilerInfo.samplingInterval;
10464            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10465            mProfileType = 0;
10466        }
10467    }
10468
10469    @Override
10470    public void setAlwaysFinish(boolean enabled) {
10471        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10472                "setAlwaysFinish()");
10473
10474        Settings.Global.putInt(
10475                mContext.getContentResolver(),
10476                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10477
10478        synchronized (this) {
10479            mAlwaysFinishActivities = enabled;
10480        }
10481    }
10482
10483    @Override
10484    public void setActivityController(IActivityController controller) {
10485        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10486                "setActivityController()");
10487        synchronized (this) {
10488            mController = controller;
10489            Watchdog.getInstance().setActivityController(controller);
10490        }
10491    }
10492
10493    @Override
10494    public void setUserIsMonkey(boolean userIsMonkey) {
10495        synchronized (this) {
10496            synchronized (mPidsSelfLocked) {
10497                final int callingPid = Binder.getCallingPid();
10498                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10499                if (precessRecord == null) {
10500                    throw new SecurityException("Unknown process: " + callingPid);
10501                }
10502                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10503                    throw new SecurityException("Only an instrumentation process "
10504                            + "with a UiAutomation can call setUserIsMonkey");
10505                }
10506            }
10507            mUserIsMonkey = userIsMonkey;
10508        }
10509    }
10510
10511    @Override
10512    public boolean isUserAMonkey() {
10513        synchronized (this) {
10514            // If there is a controller also implies the user is a monkey.
10515            return (mUserIsMonkey || mController != null);
10516        }
10517    }
10518
10519    public void requestBugReport() {
10520        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10521        SystemProperties.set("ctl.start", "bugreport");
10522    }
10523
10524    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10525        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10526    }
10527
10528    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10529        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10530            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10531        }
10532        return KEY_DISPATCHING_TIMEOUT;
10533    }
10534
10535    @Override
10536    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10537        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10538                != PackageManager.PERMISSION_GRANTED) {
10539            throw new SecurityException("Requires permission "
10540                    + android.Manifest.permission.FILTER_EVENTS);
10541        }
10542        ProcessRecord proc;
10543        long timeout;
10544        synchronized (this) {
10545            synchronized (mPidsSelfLocked) {
10546                proc = mPidsSelfLocked.get(pid);
10547            }
10548            timeout = getInputDispatchingTimeoutLocked(proc);
10549        }
10550
10551        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10552            return -1;
10553        }
10554
10555        return timeout;
10556    }
10557
10558    /**
10559     * Handle input dispatching timeouts.
10560     * Returns whether input dispatching should be aborted or not.
10561     */
10562    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10563            final ActivityRecord activity, final ActivityRecord parent,
10564            final boolean aboveSystem, String reason) {
10565        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10566                != PackageManager.PERMISSION_GRANTED) {
10567            throw new SecurityException("Requires permission "
10568                    + android.Manifest.permission.FILTER_EVENTS);
10569        }
10570
10571        final String annotation;
10572        if (reason == null) {
10573            annotation = "Input dispatching timed out";
10574        } else {
10575            annotation = "Input dispatching timed out (" + reason + ")";
10576        }
10577
10578        if (proc != null) {
10579            synchronized (this) {
10580                if (proc.debugging) {
10581                    return false;
10582                }
10583
10584                if (mDidDexOpt) {
10585                    // Give more time since we were dexopting.
10586                    mDidDexOpt = false;
10587                    return false;
10588                }
10589
10590                if (proc.instrumentationClass != null) {
10591                    Bundle info = new Bundle();
10592                    info.putString("shortMsg", "keyDispatchingTimedOut");
10593                    info.putString("longMsg", annotation);
10594                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10595                    return true;
10596                }
10597            }
10598            mHandler.post(new Runnable() {
10599                @Override
10600                public void run() {
10601                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10602                }
10603            });
10604        }
10605
10606        return true;
10607    }
10608
10609    @Override
10610    public Bundle getAssistContextExtras(int requestType) {
10611        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
10612                UserHandle.getCallingUserId());
10613        if (pae == null) {
10614            return null;
10615        }
10616        synchronized (pae) {
10617            while (!pae.haveResult) {
10618                try {
10619                    pae.wait();
10620                } catch (InterruptedException e) {
10621                }
10622            }
10623        }
10624        synchronized (this) {
10625            buildAssistBundleLocked(pae, pae.result);
10626            mPendingAssistExtras.remove(pae);
10627            mHandler.removeCallbacks(pae);
10628        }
10629        return pae.extras;
10630    }
10631
10632    @Override
10633    public void requestAssistContextExtras(int requestType, IResultReceiver receiver) {
10634        enqueueAssistContext(requestType, null, null, receiver, UserHandle.getCallingUserId());
10635    }
10636
10637    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10638            IResultReceiver receiver, int userHandle) {
10639        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10640                "enqueueAssistContext()");
10641        synchronized (this) {
10642            ActivityRecord activity = getFocusedStack().topActivity();
10643            if (activity == null) {
10644                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
10645                return null;
10646            }
10647            if (activity.app == null || activity.app.thread == null) {
10648                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10649                return null;
10650            }
10651            if (activity.app.pid == Binder.getCallingPid()) {
10652                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10653                return null;
10654            }
10655            PendingAssistExtras pae;
10656            Bundle extras = new Bundle();
10657            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10658            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
10659            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
10660            try {
10661                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10662                        requestType);
10663                mPendingAssistExtras.add(pae);
10664                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10665            } catch (RemoteException e) {
10666                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10667                return null;
10668            }
10669            return pae;
10670        }
10671    }
10672
10673    void pendingAssistExtrasTimedOutLocked(PendingAssistExtras pae) {
10674        mPendingAssistExtras.remove(pae);
10675        if (pae.receiver != null) {
10676            // Caller wants result sent back to them.
10677            try {
10678                pae.receiver.send(0, null);
10679            } catch (RemoteException e) {
10680            }
10681        }
10682    }
10683
10684    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
10685        if (result != null) {
10686            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
10687        }
10688        if (pae.hint != null) {
10689            pae.extras.putBoolean(pae.hint, true);
10690        }
10691    }
10692
10693    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10694        PendingAssistExtras pae = (PendingAssistExtras)token;
10695        synchronized (pae) {
10696            pae.result = extras;
10697            pae.haveResult = true;
10698            pae.notifyAll();
10699            if (pae.intent == null && pae.receiver == null) {
10700                // Caller is just waiting for the result.
10701                return;
10702            }
10703        }
10704
10705        // We are now ready to launch the assist activity.
10706        synchronized (this) {
10707            buildAssistBundleLocked(pae, extras);
10708            boolean exists = mPendingAssistExtras.remove(pae);
10709            mHandler.removeCallbacks(pae);
10710            if (!exists) {
10711                // Timed out.
10712                return;
10713            }
10714            if (pae.receiver != null) {
10715                // Caller wants result sent back to them.
10716                try {
10717                    pae.receiver.send(0, pae.extras);
10718                } catch (RemoteException e) {
10719                }
10720                return;
10721            }
10722        }
10723        pae.intent.replaceExtras(pae.extras);
10724        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10725                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10726                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10727        closeSystemDialogs("assist");
10728        try {
10729            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10730        } catch (ActivityNotFoundException e) {
10731            Slog.w(TAG, "No activity to handle assist action.", e);
10732        }
10733    }
10734
10735    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10736        return enqueueAssistContext(requestType, intent, hint, null, userHandle) != null;
10737    }
10738
10739    public void registerProcessObserver(IProcessObserver observer) {
10740        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10741                "registerProcessObserver()");
10742        synchronized (this) {
10743            mProcessObservers.register(observer);
10744        }
10745    }
10746
10747    @Override
10748    public void unregisterProcessObserver(IProcessObserver observer) {
10749        synchronized (this) {
10750            mProcessObservers.unregister(observer);
10751        }
10752    }
10753
10754    public void registerUidObserver(IUidObserver observer) {
10755        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10756                "registerUidObserver()");
10757        synchronized (this) {
10758            mUidObservers.register(observer);
10759        }
10760    }
10761
10762    @Override
10763    public void unregisterUidObserver(IUidObserver observer) {
10764        synchronized (this) {
10765            mUidObservers.unregister(observer);
10766        }
10767    }
10768
10769    @Override
10770    public boolean convertFromTranslucent(IBinder token) {
10771        final long origId = Binder.clearCallingIdentity();
10772        try {
10773            synchronized (this) {
10774                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10775                if (r == null) {
10776                    return false;
10777                }
10778                final boolean translucentChanged = r.changeWindowTranslucency(true);
10779                if (translucentChanged) {
10780                    r.task.stack.releaseBackgroundResources(r);
10781                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10782                }
10783                mWindowManager.setAppFullscreen(token, true);
10784                return translucentChanged;
10785            }
10786        } finally {
10787            Binder.restoreCallingIdentity(origId);
10788        }
10789    }
10790
10791    @Override
10792    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10793        final long origId = Binder.clearCallingIdentity();
10794        try {
10795            synchronized (this) {
10796                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10797                if (r == null) {
10798                    return false;
10799                }
10800                int index = r.task.mActivities.lastIndexOf(r);
10801                if (index > 0) {
10802                    ActivityRecord under = r.task.mActivities.get(index - 1);
10803                    under.returningOptions = options;
10804                }
10805                final boolean translucentChanged = r.changeWindowTranslucency(false);
10806                if (translucentChanged) {
10807                    r.task.stack.convertActivityToTranslucent(r);
10808                }
10809                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10810                mWindowManager.setAppFullscreen(token, false);
10811                return translucentChanged;
10812            }
10813        } finally {
10814            Binder.restoreCallingIdentity(origId);
10815        }
10816    }
10817
10818    @Override
10819    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10820        final long origId = Binder.clearCallingIdentity();
10821        try {
10822            synchronized (this) {
10823                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10824                if (r != null) {
10825                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10826                }
10827            }
10828            return false;
10829        } finally {
10830            Binder.restoreCallingIdentity(origId);
10831        }
10832    }
10833
10834    @Override
10835    public boolean isBackgroundVisibleBehind(IBinder token) {
10836        final long origId = Binder.clearCallingIdentity();
10837        try {
10838            synchronized (this) {
10839                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10840                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10841                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10842                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10843                return visible;
10844            }
10845        } finally {
10846            Binder.restoreCallingIdentity(origId);
10847        }
10848    }
10849
10850    @Override
10851    public ActivityOptions getActivityOptions(IBinder token) {
10852        final long origId = Binder.clearCallingIdentity();
10853        try {
10854            synchronized (this) {
10855                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10856                if (r != null) {
10857                    final ActivityOptions activityOptions = r.pendingOptions;
10858                    r.pendingOptions = null;
10859                    return activityOptions;
10860                }
10861                return null;
10862            }
10863        } finally {
10864            Binder.restoreCallingIdentity(origId);
10865        }
10866    }
10867
10868    @Override
10869    public void setImmersive(IBinder token, boolean immersive) {
10870        synchronized(this) {
10871            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10872            if (r == null) {
10873                throw new IllegalArgumentException();
10874            }
10875            r.immersive = immersive;
10876
10877            // update associated state if we're frontmost
10878            if (r == mFocusedActivity) {
10879                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
10880                applyUpdateLockStateLocked(r);
10881            }
10882        }
10883    }
10884
10885    @Override
10886    public boolean isImmersive(IBinder token) {
10887        synchronized (this) {
10888            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10889            if (r == null) {
10890                throw new IllegalArgumentException();
10891            }
10892            return r.immersive;
10893        }
10894    }
10895
10896    public boolean isTopActivityImmersive() {
10897        enforceNotIsolatedCaller("startActivity");
10898        synchronized (this) {
10899            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10900            return (r != null) ? r.immersive : false;
10901        }
10902    }
10903
10904    @Override
10905    public boolean isTopOfTask(IBinder token) {
10906        synchronized (this) {
10907            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10908            if (r == null) {
10909                throw new IllegalArgumentException();
10910            }
10911            return r.task.getTopActivity() == r;
10912        }
10913    }
10914
10915    public final void enterSafeMode() {
10916        synchronized(this) {
10917            // It only makes sense to do this before the system is ready
10918            // and started launching other packages.
10919            if (!mSystemReady) {
10920                try {
10921                    AppGlobals.getPackageManager().enterSafeMode();
10922                } catch (RemoteException e) {
10923                }
10924            }
10925
10926            mSafeMode = true;
10927        }
10928    }
10929
10930    public final void showSafeModeOverlay() {
10931        View v = LayoutInflater.from(mContext).inflate(
10932                com.android.internal.R.layout.safe_mode, null);
10933        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10934        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10935        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10936        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10937        lp.gravity = Gravity.BOTTOM | Gravity.START;
10938        lp.format = v.getBackground().getOpacity();
10939        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10940                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10941        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10942        ((WindowManager)mContext.getSystemService(
10943                Context.WINDOW_SERVICE)).addView(v, lp);
10944    }
10945
10946    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
10947        if (!(sender instanceof PendingIntentRecord)) {
10948            return;
10949        }
10950        final PendingIntentRecord rec = (PendingIntentRecord)sender;
10951        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10952        synchronized (stats) {
10953            if (mBatteryStatsService.isOnBattery()) {
10954                mBatteryStatsService.enforceCallingPermission();
10955                int MY_UID = Binder.getCallingUid();
10956                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10957                BatteryStatsImpl.Uid.Pkg pkg =
10958                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10959                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10960                pkg.noteWakeupAlarmLocked(tag);
10961            }
10962        }
10963    }
10964
10965    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
10966        if (!(sender instanceof PendingIntentRecord)) {
10967            return;
10968        }
10969        final PendingIntentRecord rec = (PendingIntentRecord)sender;
10970        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10971        synchronized (stats) {
10972            mBatteryStatsService.enforceCallingPermission();
10973            int MY_UID = Binder.getCallingUid();
10974            int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10975            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
10976        }
10977    }
10978
10979    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
10980        if (!(sender instanceof PendingIntentRecord)) {
10981            return;
10982        }
10983        final PendingIntentRecord rec = (PendingIntentRecord)sender;
10984        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10985        synchronized (stats) {
10986            mBatteryStatsService.enforceCallingPermission();
10987            int MY_UID = Binder.getCallingUid();
10988            int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10989            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
10990        }
10991    }
10992
10993    public boolean killPids(int[] pids, String pReason, boolean secure) {
10994        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10995            throw new SecurityException("killPids only available to the system");
10996        }
10997        String reason = (pReason == null) ? "Unknown" : pReason;
10998        // XXX Note: don't acquire main activity lock here, because the window
10999        // manager calls in with its locks held.
11000
11001        boolean killed = false;
11002        synchronized (mPidsSelfLocked) {
11003            int[] types = new int[pids.length];
11004            int worstType = 0;
11005            for (int i=0; i<pids.length; i++) {
11006                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11007                if (proc != null) {
11008                    int type = proc.setAdj;
11009                    types[i] = type;
11010                    if (type > worstType) {
11011                        worstType = type;
11012                    }
11013                }
11014            }
11015
11016            // If the worst oom_adj is somewhere in the cached proc LRU range,
11017            // then constrain it so we will kill all cached procs.
11018            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
11019                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
11020                worstType = ProcessList.CACHED_APP_MIN_ADJ;
11021            }
11022
11023            // If this is not a secure call, don't let it kill processes that
11024            // are important.
11025            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
11026                worstType = ProcessList.SERVICE_ADJ;
11027            }
11028
11029            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
11030            for (int i=0; i<pids.length; i++) {
11031                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11032                if (proc == null) {
11033                    continue;
11034                }
11035                int adj = proc.setAdj;
11036                if (adj >= worstType && !proc.killedByAm) {
11037                    proc.kill(reason, true);
11038                    killed = true;
11039                }
11040            }
11041        }
11042        return killed;
11043    }
11044
11045    @Override
11046    public void killUid(int uid, String reason) {
11047        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
11048        synchronized (this) {
11049            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
11050                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
11051                    reason != null ? reason : "kill uid");
11052        }
11053    }
11054
11055    @Override
11056    public boolean killProcessesBelowForeground(String reason) {
11057        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11058            throw new SecurityException("killProcessesBelowForeground() only available to system");
11059        }
11060
11061        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
11062    }
11063
11064    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
11065        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11066            throw new SecurityException("killProcessesBelowAdj() only available to system");
11067        }
11068
11069        boolean killed = false;
11070        synchronized (mPidsSelfLocked) {
11071            final int size = mPidsSelfLocked.size();
11072            for (int i = 0; i < size; i++) {
11073                final int pid = mPidsSelfLocked.keyAt(i);
11074                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11075                if (proc == null) continue;
11076
11077                final int adj = proc.setAdj;
11078                if (adj > belowAdj && !proc.killedByAm) {
11079                    proc.kill(reason, true);
11080                    killed = true;
11081                }
11082            }
11083        }
11084        return killed;
11085    }
11086
11087    @Override
11088    public void hang(final IBinder who, boolean allowRestart) {
11089        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11090                != PackageManager.PERMISSION_GRANTED) {
11091            throw new SecurityException("Requires permission "
11092                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11093        }
11094
11095        final IBinder.DeathRecipient death = new DeathRecipient() {
11096            @Override
11097            public void binderDied() {
11098                synchronized (this) {
11099                    notifyAll();
11100                }
11101            }
11102        };
11103
11104        try {
11105            who.linkToDeath(death, 0);
11106        } catch (RemoteException e) {
11107            Slog.w(TAG, "hang: given caller IBinder is already dead.");
11108            return;
11109        }
11110
11111        synchronized (this) {
11112            Watchdog.getInstance().setAllowRestart(allowRestart);
11113            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
11114            synchronized (death) {
11115                while (who.isBinderAlive()) {
11116                    try {
11117                        death.wait();
11118                    } catch (InterruptedException e) {
11119                    }
11120                }
11121            }
11122            Watchdog.getInstance().setAllowRestart(true);
11123        }
11124    }
11125
11126    @Override
11127    public void restart() {
11128        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11129                != PackageManager.PERMISSION_GRANTED) {
11130            throw new SecurityException("Requires permission "
11131                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11132        }
11133
11134        Log.i(TAG, "Sending shutdown broadcast...");
11135
11136        BroadcastReceiver br = new BroadcastReceiver() {
11137            @Override public void onReceive(Context context, Intent intent) {
11138                // Now the broadcast is done, finish up the low-level shutdown.
11139                Log.i(TAG, "Shutting down activity manager...");
11140                shutdown(10000);
11141                Log.i(TAG, "Shutdown complete, restarting!");
11142                Process.killProcess(Process.myPid());
11143                System.exit(10);
11144            }
11145        };
11146
11147        // First send the high-level shut down broadcast.
11148        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
11149        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
11150        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
11151        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
11152        mContext.sendOrderedBroadcastAsUser(intent,
11153                UserHandle.ALL, null, br, mHandler, 0, null, null);
11154        */
11155        br.onReceive(mContext, intent);
11156    }
11157
11158    private long getLowRamTimeSinceIdle(long now) {
11159        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
11160    }
11161
11162    @Override
11163    public void performIdleMaintenance() {
11164        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11165                != PackageManager.PERMISSION_GRANTED) {
11166            throw new SecurityException("Requires permission "
11167                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11168        }
11169
11170        synchronized (this) {
11171            final long now = SystemClock.uptimeMillis();
11172            final long timeSinceLastIdle = now - mLastIdleTime;
11173            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
11174            mLastIdleTime = now;
11175            mLowRamTimeSinceLastIdle = 0;
11176            if (mLowRamStartTime != 0) {
11177                mLowRamStartTime = now;
11178            }
11179
11180            StringBuilder sb = new StringBuilder(128);
11181            sb.append("Idle maintenance over ");
11182            TimeUtils.formatDuration(timeSinceLastIdle, sb);
11183            sb.append(" low RAM for ");
11184            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11185            Slog.i(TAG, sb.toString());
11186
11187            // If at least 1/3 of our time since the last idle period has been spent
11188            // with RAM low, then we want to kill processes.
11189            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
11190
11191            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11192                ProcessRecord proc = mLruProcesses.get(i);
11193                if (proc.notCachedSinceIdle) {
11194                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
11195                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
11196                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
11197                        if (doKilling && proc.initialIdlePss != 0
11198                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
11199                            sb = new StringBuilder(128);
11200                            sb.append("Kill");
11201                            sb.append(proc.processName);
11202                            sb.append(" in idle maint: pss=");
11203                            sb.append(proc.lastPss);
11204                            sb.append(", initialPss=");
11205                            sb.append(proc.initialIdlePss);
11206                            sb.append(", period=");
11207                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
11208                            sb.append(", lowRamPeriod=");
11209                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11210                            Slog.wtfQuiet(TAG, sb.toString());
11211                            proc.kill("idle maint (pss " + proc.lastPss
11212                                    + " from " + proc.initialIdlePss + ")", true);
11213                        }
11214                    }
11215                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
11216                    proc.notCachedSinceIdle = true;
11217                    proc.initialIdlePss = 0;
11218                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
11219                            mTestPssMode, isSleeping(), now);
11220                }
11221            }
11222
11223            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
11224            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
11225        }
11226    }
11227
11228    private void retrieveSettings() {
11229        final ContentResolver resolver = mContext.getContentResolver();
11230        String debugApp = Settings.Global.getString(
11231            resolver, Settings.Global.DEBUG_APP);
11232        boolean waitForDebugger = Settings.Global.getInt(
11233            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11234        boolean alwaysFinishActivities = Settings.Global.getInt(
11235            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11236        boolean forceRtl = Settings.Global.getInt(
11237                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11238        // Transfer any global setting for forcing RTL layout, into a System Property
11239        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11240
11241        Configuration configuration = new Configuration();
11242        Settings.System.getConfiguration(resolver, configuration);
11243        if (forceRtl) {
11244            // This will take care of setting the correct layout direction flags
11245            configuration.setLayoutDirection(configuration.locale);
11246        }
11247
11248        synchronized (this) {
11249            mDebugApp = mOrigDebugApp = debugApp;
11250            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11251            mAlwaysFinishActivities = alwaysFinishActivities;
11252            // This happens before any activities are started, so we can
11253            // change mConfiguration in-place.
11254            updateConfigurationLocked(configuration, null, true);
11255            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
11256                    "Initial config: " + mConfiguration);
11257        }
11258    }
11259
11260    /** Loads resources after the current configuration has been set. */
11261    private void loadResourcesOnSystemReady() {
11262        final Resources res = mContext.getResources();
11263        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11264        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11265        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11266    }
11267
11268    public boolean testIsSystemReady() {
11269        // no need to synchronize(this) just to read & return the value
11270        return mSystemReady;
11271    }
11272
11273    private static File getCalledPreBootReceiversFile() {
11274        File dataDir = Environment.getDataDirectory();
11275        File systemDir = new File(dataDir, "system");
11276        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11277        return fname;
11278    }
11279
11280    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11281        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11282        File file = getCalledPreBootReceiversFile();
11283        FileInputStream fis = null;
11284        try {
11285            fis = new FileInputStream(file);
11286            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11287            int fvers = dis.readInt();
11288            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11289                String vers = dis.readUTF();
11290                String codename = dis.readUTF();
11291                String build = dis.readUTF();
11292                if (android.os.Build.VERSION.RELEASE.equals(vers)
11293                        && android.os.Build.VERSION.CODENAME.equals(codename)
11294                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11295                    int num = dis.readInt();
11296                    while (num > 0) {
11297                        num--;
11298                        String pkg = dis.readUTF();
11299                        String cls = dis.readUTF();
11300                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11301                    }
11302                }
11303            }
11304        } catch (FileNotFoundException e) {
11305        } catch (IOException e) {
11306            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11307        } finally {
11308            if (fis != null) {
11309                try {
11310                    fis.close();
11311                } catch (IOException e) {
11312                }
11313            }
11314        }
11315        return lastDoneReceivers;
11316    }
11317
11318    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11319        File file = getCalledPreBootReceiversFile();
11320        FileOutputStream fos = null;
11321        DataOutputStream dos = null;
11322        try {
11323            fos = new FileOutputStream(file);
11324            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11325            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11326            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11327            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11328            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11329            dos.writeInt(list.size());
11330            for (int i=0; i<list.size(); i++) {
11331                dos.writeUTF(list.get(i).getPackageName());
11332                dos.writeUTF(list.get(i).getClassName());
11333            }
11334        } catch (IOException e) {
11335            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11336            file.delete();
11337        } finally {
11338            FileUtils.sync(fos);
11339            if (dos != null) {
11340                try {
11341                    dos.close();
11342                } catch (IOException e) {
11343                    // TODO Auto-generated catch block
11344                    e.printStackTrace();
11345                }
11346            }
11347        }
11348    }
11349
11350    final class PreBootContinuation extends IIntentReceiver.Stub {
11351        final Intent intent;
11352        final Runnable onFinishCallback;
11353        final ArrayList<ComponentName> doneReceivers;
11354        final List<ResolveInfo> ris;
11355        final int[] users;
11356        int lastRi = -1;
11357        int curRi = 0;
11358        int curUser = 0;
11359
11360        PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
11361                ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
11362            intent = _intent;
11363            onFinishCallback = _onFinishCallback;
11364            doneReceivers = _doneReceivers;
11365            ris = _ris;
11366            users = _users;
11367        }
11368
11369        void go() {
11370            if (lastRi != curRi) {
11371                ActivityInfo ai = ris.get(curRi).activityInfo;
11372                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11373                intent.setComponent(comp);
11374                doneReceivers.add(comp);
11375                lastRi = curRi;
11376                CharSequence label = ai.loadLabel(mContext.getPackageManager());
11377                showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
11378            }
11379            Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
11380                    + " for user " + users[curUser]);
11381            EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
11382            broadcastIntentLocked(null, null, intent, null, this,
11383                    0, null, null, null, AppOpsManager.OP_NONE,
11384                    true, false, MY_PID, Process.SYSTEM_UID,
11385                    users[curUser]);
11386        }
11387
11388        public void performReceive(Intent intent, int resultCode,
11389                String data, Bundle extras, boolean ordered,
11390                boolean sticky, int sendingUser) {
11391            curUser++;
11392            if (curUser >= users.length) {
11393                curUser = 0;
11394                curRi++;
11395                if (curRi >= ris.size()) {
11396                    // All done sending broadcasts!
11397                    if (onFinishCallback != null) {
11398                        // The raw IIntentReceiver interface is called
11399                        // with the AM lock held, so redispatch to
11400                        // execute our code without the lock.
11401                        mHandler.post(onFinishCallback);
11402                    }
11403                    return;
11404                }
11405            }
11406            go();
11407        }
11408    }
11409
11410    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11411            ArrayList<ComponentName> doneReceivers, int userId) {
11412        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11413        List<ResolveInfo> ris = null;
11414        try {
11415            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11416                    intent, null, 0, userId);
11417        } catch (RemoteException e) {
11418        }
11419        if (ris == null) {
11420            return false;
11421        }
11422        for (int i=ris.size()-1; i>=0; i--) {
11423            if ((ris.get(i).activityInfo.applicationInfo.flags
11424                    &ApplicationInfo.FLAG_SYSTEM) == 0) {
11425                ris.remove(i);
11426            }
11427        }
11428        intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11429
11430        // For User 0, load the version number. When delivering to a new user, deliver
11431        // to all receivers.
11432        if (userId == UserHandle.USER_OWNER) {
11433            ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11434            for (int i=0; i<ris.size(); i++) {
11435                ActivityInfo ai = ris.get(i).activityInfo;
11436                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11437                if (false && lastDoneReceivers.contains(comp)) {
11438                    // We already did the pre boot receiver for this app with the current
11439                    // platform version, so don't do it again...
11440                    ris.remove(i);
11441                    i--;
11442                    // ...however, do keep it as one that has been done, so we don't
11443                    // forget about it when rewriting the file of last done receivers.
11444                    doneReceivers.add(comp);
11445                }
11446            }
11447        }
11448
11449        if (ris.size() <= 0) {
11450            return false;
11451        }
11452
11453        // If primary user, send broadcast to all available users, else just to userId
11454        final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11455                : new int[] { userId };
11456        if (users.length <= 0) {
11457            return false;
11458        }
11459
11460        PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
11461                ris, users);
11462        cont.go();
11463        return true;
11464    }
11465
11466    public void systemReady(final Runnable goingCallback) {
11467        synchronized(this) {
11468            if (mSystemReady) {
11469                // If we're done calling all the receivers, run the next "boot phase" passed in
11470                // by the SystemServer
11471                if (goingCallback != null) {
11472                    goingCallback.run();
11473                }
11474                return;
11475            }
11476
11477            // Make sure we have the current profile info, since it is needed for
11478            // security checks.
11479            updateCurrentProfileIdsLocked();
11480
11481            mRecentTasks.clear();
11482            mRecentTasks.addAll(mTaskPersister.restoreTasksLocked());
11483            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
11484            mTaskPersister.startPersisting();
11485
11486            // Check to see if there are any update receivers to run.
11487            if (!mDidUpdate) {
11488                if (mWaitingUpdate) {
11489                    return;
11490                }
11491                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11492                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11493                    public void run() {
11494                        synchronized (ActivityManagerService.this) {
11495                            mDidUpdate = true;
11496                        }
11497                        showBootMessage(mContext.getText(
11498                                R.string.android_upgrading_complete),
11499                                false);
11500                        writeLastDonePreBootReceivers(doneReceivers);
11501                        systemReady(goingCallback);
11502                    }
11503                }, doneReceivers, UserHandle.USER_OWNER);
11504
11505                if (mWaitingUpdate) {
11506                    return;
11507                }
11508                mDidUpdate = true;
11509            }
11510
11511            mAppOpsService.systemReady();
11512            mSystemReady = true;
11513        }
11514
11515        ArrayList<ProcessRecord> procsToKill = null;
11516        synchronized(mPidsSelfLocked) {
11517            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11518                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11519                if (!isAllowedWhileBooting(proc.info)){
11520                    if (procsToKill == null) {
11521                        procsToKill = new ArrayList<ProcessRecord>();
11522                    }
11523                    procsToKill.add(proc);
11524                }
11525            }
11526        }
11527
11528        synchronized(this) {
11529            if (procsToKill != null) {
11530                for (int i=procsToKill.size()-1; i>=0; i--) {
11531                    ProcessRecord proc = procsToKill.get(i);
11532                    Slog.i(TAG, "Removing system update proc: " + proc);
11533                    removeProcessLocked(proc, true, false, "system update done");
11534                }
11535            }
11536
11537            // Now that we have cleaned up any update processes, we
11538            // are ready to start launching real processes and know that
11539            // we won't trample on them any more.
11540            mProcessesReady = true;
11541        }
11542
11543        Slog.i(TAG, "System now ready");
11544        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11545            SystemClock.uptimeMillis());
11546
11547        synchronized(this) {
11548            // Make sure we have no pre-ready processes sitting around.
11549
11550            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11551                ResolveInfo ri = mContext.getPackageManager()
11552                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11553                                STOCK_PM_FLAGS);
11554                CharSequence errorMsg = null;
11555                if (ri != null) {
11556                    ActivityInfo ai = ri.activityInfo;
11557                    ApplicationInfo app = ai.applicationInfo;
11558                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11559                        mTopAction = Intent.ACTION_FACTORY_TEST;
11560                        mTopData = null;
11561                        mTopComponent = new ComponentName(app.packageName,
11562                                ai.name);
11563                    } else {
11564                        errorMsg = mContext.getResources().getText(
11565                                com.android.internal.R.string.factorytest_not_system);
11566                    }
11567                } else {
11568                    errorMsg = mContext.getResources().getText(
11569                            com.android.internal.R.string.factorytest_no_action);
11570                }
11571                if (errorMsg != null) {
11572                    mTopAction = null;
11573                    mTopData = null;
11574                    mTopComponent = null;
11575                    Message msg = Message.obtain();
11576                    msg.what = SHOW_FACTORY_ERROR_MSG;
11577                    msg.getData().putCharSequence("msg", errorMsg);
11578                    mUiHandler.sendMessage(msg);
11579                }
11580            }
11581        }
11582
11583        retrieveSettings();
11584        loadResourcesOnSystemReady();
11585
11586        synchronized (this) {
11587            readGrantedUriPermissionsLocked();
11588        }
11589
11590        if (goingCallback != null) goingCallback.run();
11591
11592        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11593                Integer.toString(mCurrentUserId), mCurrentUserId);
11594        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11595                Integer.toString(mCurrentUserId), mCurrentUserId);
11596        mSystemServiceManager.startUser(mCurrentUserId);
11597
11598        synchronized (this) {
11599            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11600                try {
11601                    List apps = AppGlobals.getPackageManager().
11602                        getPersistentApplications(STOCK_PM_FLAGS);
11603                    if (apps != null) {
11604                        int N = apps.size();
11605                        int i;
11606                        for (i=0; i<N; i++) {
11607                            ApplicationInfo info
11608                                = (ApplicationInfo)apps.get(i);
11609                            if (info != null &&
11610                                    !info.packageName.equals("android")) {
11611                                addAppLocked(info, false, null /* ABI override */);
11612                            }
11613                        }
11614                    }
11615                } catch (RemoteException ex) {
11616                    // pm is in same process, this will never happen.
11617                }
11618            }
11619
11620            // Start up initial activity.
11621            mBooting = true;
11622            startHomeActivityLocked(mCurrentUserId, "systemReady");
11623
11624            try {
11625                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11626                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11627                            + " data partition or your device will be unstable.");
11628                    mUiHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11629                }
11630            } catch (RemoteException e) {
11631            }
11632
11633            if (!Build.isBuildConsistent()) {
11634                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11635                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11636            }
11637
11638            long ident = Binder.clearCallingIdentity();
11639            try {
11640                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11641                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11642                        | Intent.FLAG_RECEIVER_FOREGROUND);
11643                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11644                broadcastIntentLocked(null, null, intent,
11645                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11646                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11647                intent = new Intent(Intent.ACTION_USER_STARTING);
11648                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11649                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11650                broadcastIntentLocked(null, null, intent,
11651                        null, new IIntentReceiver.Stub() {
11652                            @Override
11653                            public void performReceive(Intent intent, int resultCode, String data,
11654                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11655                                    throws RemoteException {
11656                            }
11657                        }, 0, null, null,
11658                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11659                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11660            } catch (Throwable t) {
11661                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11662            } finally {
11663                Binder.restoreCallingIdentity(ident);
11664            }
11665            mStackSupervisor.resumeTopActivitiesLocked();
11666            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11667        }
11668    }
11669
11670    private boolean makeAppCrashingLocked(ProcessRecord app,
11671            String shortMsg, String longMsg, String stackTrace) {
11672        app.crashing = true;
11673        app.crashingReport = generateProcessError(app,
11674                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11675        startAppProblemLocked(app);
11676        app.stopFreezingAllLocked();
11677        return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
11678    }
11679
11680    private void makeAppNotRespondingLocked(ProcessRecord app,
11681            String activity, String shortMsg, String longMsg) {
11682        app.notResponding = true;
11683        app.notRespondingReport = generateProcessError(app,
11684                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11685                activity, shortMsg, longMsg, null);
11686        startAppProblemLocked(app);
11687        app.stopFreezingAllLocked();
11688    }
11689
11690    /**
11691     * Generate a process error record, suitable for attachment to a ProcessRecord.
11692     *
11693     * @param app The ProcessRecord in which the error occurred.
11694     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11695     *                      ActivityManager.AppErrorStateInfo
11696     * @param activity The activity associated with the crash, if known.
11697     * @param shortMsg Short message describing the crash.
11698     * @param longMsg Long message describing the crash.
11699     * @param stackTrace Full crash stack trace, may be null.
11700     *
11701     * @return Returns a fully-formed AppErrorStateInfo record.
11702     */
11703    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11704            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11705        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11706
11707        report.condition = condition;
11708        report.processName = app.processName;
11709        report.pid = app.pid;
11710        report.uid = app.info.uid;
11711        report.tag = activity;
11712        report.shortMsg = shortMsg;
11713        report.longMsg = longMsg;
11714        report.stackTrace = stackTrace;
11715
11716        return report;
11717    }
11718
11719    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11720        synchronized (this) {
11721            app.crashing = false;
11722            app.crashingReport = null;
11723            app.notResponding = false;
11724            app.notRespondingReport = null;
11725            if (app.anrDialog == fromDialog) {
11726                app.anrDialog = null;
11727            }
11728            if (app.waitDialog == fromDialog) {
11729                app.waitDialog = null;
11730            }
11731            if (app.pid > 0 && app.pid != MY_PID) {
11732                handleAppCrashLocked(app, "user-terminated" /*reason*/,
11733                        null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
11734                app.kill("user request after error", true);
11735            }
11736        }
11737    }
11738
11739    private boolean handleAppCrashLocked(ProcessRecord app, String reason,
11740            String shortMsg, String longMsg, String stackTrace) {
11741        long now = SystemClock.uptimeMillis();
11742
11743        Long crashTime;
11744        if (!app.isolated) {
11745            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11746        } else {
11747            crashTime = null;
11748        }
11749        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11750            // This process loses!
11751            Slog.w(TAG, "Process " + app.info.processName
11752                    + " has crashed too many times: killing!");
11753            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11754                    app.userId, app.info.processName, app.uid);
11755            mStackSupervisor.handleAppCrashLocked(app);
11756            if (!app.persistent) {
11757                // We don't want to start this process again until the user
11758                // explicitly does so...  but for persistent process, we really
11759                // need to keep it running.  If a persistent process is actually
11760                // repeatedly crashing, then badness for everyone.
11761                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11762                        app.info.processName);
11763                if (!app.isolated) {
11764                    // XXX We don't have a way to mark isolated processes
11765                    // as bad, since they don't have a peristent identity.
11766                    mBadProcesses.put(app.info.processName, app.uid,
11767                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11768                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11769                }
11770                app.bad = true;
11771                app.removed = true;
11772                // Don't let services in this process be restarted and potentially
11773                // annoy the user repeatedly.  Unless it is persistent, since those
11774                // processes run critical code.
11775                removeProcessLocked(app, false, false, "crash");
11776                mStackSupervisor.resumeTopActivitiesLocked();
11777                return false;
11778            }
11779            mStackSupervisor.resumeTopActivitiesLocked();
11780        } else {
11781            mStackSupervisor.finishTopRunningActivityLocked(app, reason);
11782        }
11783
11784        // Bump up the crash count of any services currently running in the proc.
11785        for (int i=app.services.size()-1; i>=0; i--) {
11786            // Any services running in the application need to be placed
11787            // back in the pending list.
11788            ServiceRecord sr = app.services.valueAt(i);
11789            sr.crashCount++;
11790        }
11791
11792        // If the crashing process is what we consider to be the "home process" and it has been
11793        // replaced by a third-party app, clear the package preferred activities from packages
11794        // with a home activity running in the process to prevent a repeatedly crashing app
11795        // from blocking the user to manually clear the list.
11796        final ArrayList<ActivityRecord> activities = app.activities;
11797        if (app == mHomeProcess && activities.size() > 0
11798                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11799            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11800                final ActivityRecord r = activities.get(activityNdx);
11801                if (r.isHomeActivity()) {
11802                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11803                    try {
11804                        ActivityThread.getPackageManager()
11805                                .clearPackagePreferredActivities(r.packageName);
11806                    } catch (RemoteException c) {
11807                        // pm is in same process, this will never happen.
11808                    }
11809                }
11810            }
11811        }
11812
11813        if (!app.isolated) {
11814            // XXX Can't keep track of crash times for isolated processes,
11815            // because they don't have a perisistent identity.
11816            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11817        }
11818
11819        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11820        return true;
11821    }
11822
11823    void startAppProblemLocked(ProcessRecord app) {
11824        // If this app is not running under the current user, then we
11825        // can't give it a report button because that would require
11826        // launching the report UI under a different user.
11827        app.errorReportReceiver = null;
11828
11829        for (int userId : mCurrentProfileIds) {
11830            if (app.userId == userId) {
11831                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11832                        mContext, app.info.packageName, app.info.flags);
11833            }
11834        }
11835        skipCurrentReceiverLocked(app);
11836    }
11837
11838    void skipCurrentReceiverLocked(ProcessRecord app) {
11839        for (BroadcastQueue queue : mBroadcastQueues) {
11840            queue.skipCurrentReceiverLocked(app);
11841        }
11842    }
11843
11844    /**
11845     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11846     * The application process will exit immediately after this call returns.
11847     * @param app object of the crashing app, null for the system server
11848     * @param crashInfo describing the exception
11849     */
11850    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11851        ProcessRecord r = findAppProcess(app, "Crash");
11852        final String processName = app == null ? "system_server"
11853                : (r == null ? "unknown" : r.processName);
11854
11855        handleApplicationCrashInner("crash", r, processName, crashInfo);
11856    }
11857
11858    /* Native crash reporting uses this inner version because it needs to be somewhat
11859     * decoupled from the AM-managed cleanup lifecycle
11860     */
11861    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11862            ApplicationErrorReport.CrashInfo crashInfo) {
11863        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11864                UserHandle.getUserId(Binder.getCallingUid()), processName,
11865                r == null ? -1 : r.info.flags,
11866                crashInfo.exceptionClassName,
11867                crashInfo.exceptionMessage,
11868                crashInfo.throwFileName,
11869                crashInfo.throwLineNumber);
11870
11871        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11872
11873        crashApplication(r, crashInfo);
11874    }
11875
11876    public void handleApplicationStrictModeViolation(
11877            IBinder app,
11878            int violationMask,
11879            StrictMode.ViolationInfo info) {
11880        ProcessRecord r = findAppProcess(app, "StrictMode");
11881        if (r == null) {
11882            return;
11883        }
11884
11885        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11886            Integer stackFingerprint = info.hashCode();
11887            boolean logIt = true;
11888            synchronized (mAlreadyLoggedViolatedStacks) {
11889                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11890                    logIt = false;
11891                    // TODO: sub-sample into EventLog for these, with
11892                    // the info.durationMillis?  Then we'd get
11893                    // the relative pain numbers, without logging all
11894                    // the stack traces repeatedly.  We'd want to do
11895                    // likewise in the client code, which also does
11896                    // dup suppression, before the Binder call.
11897                } else {
11898                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11899                        mAlreadyLoggedViolatedStacks.clear();
11900                    }
11901                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11902                }
11903            }
11904            if (logIt) {
11905                logStrictModeViolationToDropBox(r, info);
11906            }
11907        }
11908
11909        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11910            AppErrorResult result = new AppErrorResult();
11911            synchronized (this) {
11912                final long origId = Binder.clearCallingIdentity();
11913
11914                Message msg = Message.obtain();
11915                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11916                HashMap<String, Object> data = new HashMap<String, Object>();
11917                data.put("result", result);
11918                data.put("app", r);
11919                data.put("violationMask", violationMask);
11920                data.put("info", info);
11921                msg.obj = data;
11922                mUiHandler.sendMessage(msg);
11923
11924                Binder.restoreCallingIdentity(origId);
11925            }
11926            int res = result.get();
11927            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11928        }
11929    }
11930
11931    // Depending on the policy in effect, there could be a bunch of
11932    // these in quick succession so we try to batch these together to
11933    // minimize disk writes, number of dropbox entries, and maximize
11934    // compression, by having more fewer, larger records.
11935    private void logStrictModeViolationToDropBox(
11936            ProcessRecord process,
11937            StrictMode.ViolationInfo info) {
11938        if (info == null) {
11939            return;
11940        }
11941        final boolean isSystemApp = process == null ||
11942                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11943                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11944        final String processName = process == null ? "unknown" : process.processName;
11945        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11946        final DropBoxManager dbox = (DropBoxManager)
11947                mContext.getSystemService(Context.DROPBOX_SERVICE);
11948
11949        // Exit early if the dropbox isn't configured to accept this report type.
11950        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11951
11952        boolean bufferWasEmpty;
11953        boolean needsFlush;
11954        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11955        synchronized (sb) {
11956            bufferWasEmpty = sb.length() == 0;
11957            appendDropBoxProcessHeaders(process, processName, sb);
11958            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11959            sb.append("System-App: ").append(isSystemApp).append("\n");
11960            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11961            if (info.violationNumThisLoop != 0) {
11962                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11963            }
11964            if (info.numAnimationsRunning != 0) {
11965                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11966            }
11967            if (info.broadcastIntentAction != null) {
11968                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11969            }
11970            if (info.durationMillis != -1) {
11971                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11972            }
11973            if (info.numInstances != -1) {
11974                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11975            }
11976            if (info.tags != null) {
11977                for (String tag : info.tags) {
11978                    sb.append("Span-Tag: ").append(tag).append("\n");
11979                }
11980            }
11981            sb.append("\n");
11982            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11983                sb.append(info.crashInfo.stackTrace);
11984                sb.append("\n");
11985            }
11986            if (info.message != null) {
11987                sb.append(info.message);
11988                sb.append("\n");
11989            }
11990
11991            // Only buffer up to ~64k.  Various logging bits truncate
11992            // things at 128k.
11993            needsFlush = (sb.length() > 64 * 1024);
11994        }
11995
11996        // Flush immediately if the buffer's grown too large, or this
11997        // is a non-system app.  Non-system apps are isolated with a
11998        // different tag & policy and not batched.
11999        //
12000        // Batching is useful during internal testing with
12001        // StrictMode settings turned up high.  Without batching,
12002        // thousands of separate files could be created on boot.
12003        if (!isSystemApp || needsFlush) {
12004            new Thread("Error dump: " + dropboxTag) {
12005                @Override
12006                public void run() {
12007                    String report;
12008                    synchronized (sb) {
12009                        report = sb.toString();
12010                        sb.delete(0, sb.length());
12011                        sb.trimToSize();
12012                    }
12013                    if (report.length() != 0) {
12014                        dbox.addText(dropboxTag, report);
12015                    }
12016                }
12017            }.start();
12018            return;
12019        }
12020
12021        // System app batching:
12022        if (!bufferWasEmpty) {
12023            // An existing dropbox-writing thread is outstanding, so
12024            // we don't need to start it up.  The existing thread will
12025            // catch the buffer appends we just did.
12026            return;
12027        }
12028
12029        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
12030        // (After this point, we shouldn't access AMS internal data structures.)
12031        new Thread("Error dump: " + dropboxTag) {
12032            @Override
12033            public void run() {
12034                // 5 second sleep to let stacks arrive and be batched together
12035                try {
12036                    Thread.sleep(5000);  // 5 seconds
12037                } catch (InterruptedException e) {}
12038
12039                String errorReport;
12040                synchronized (mStrictModeBuffer) {
12041                    errorReport = mStrictModeBuffer.toString();
12042                    if (errorReport.length() == 0) {
12043                        return;
12044                    }
12045                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
12046                    mStrictModeBuffer.trimToSize();
12047                }
12048                dbox.addText(dropboxTag, errorReport);
12049            }
12050        }.start();
12051    }
12052
12053    /**
12054     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
12055     * @param app object of the crashing app, null for the system server
12056     * @param tag reported by the caller
12057     * @param system whether this wtf is coming from the system
12058     * @param crashInfo describing the context of the error
12059     * @return true if the process should exit immediately (WTF is fatal)
12060     */
12061    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
12062            final ApplicationErrorReport.CrashInfo crashInfo) {
12063        final int callingUid = Binder.getCallingUid();
12064        final int callingPid = Binder.getCallingPid();
12065
12066        if (system) {
12067            // If this is coming from the system, we could very well have low-level
12068            // system locks held, so we want to do this all asynchronously.  And we
12069            // never want this to become fatal, so there is that too.
12070            mHandler.post(new Runnable() {
12071                @Override public void run() {
12072                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
12073                }
12074            });
12075            return false;
12076        }
12077
12078        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
12079                crashInfo);
12080
12081        if (r != null && r.pid != Process.myPid() &&
12082                Settings.Global.getInt(mContext.getContentResolver(),
12083                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
12084            crashApplication(r, crashInfo);
12085            return true;
12086        } else {
12087            return false;
12088        }
12089    }
12090
12091    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
12092            final ApplicationErrorReport.CrashInfo crashInfo) {
12093        final ProcessRecord r = findAppProcess(app, "WTF");
12094        final String processName = app == null ? "system_server"
12095                : (r == null ? "unknown" : r.processName);
12096
12097        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
12098                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
12099
12100        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
12101
12102        return r;
12103    }
12104
12105    /**
12106     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
12107     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
12108     */
12109    private ProcessRecord findAppProcess(IBinder app, String reason) {
12110        if (app == null) {
12111            return null;
12112        }
12113
12114        synchronized (this) {
12115            final int NP = mProcessNames.getMap().size();
12116            for (int ip=0; ip<NP; ip++) {
12117                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12118                final int NA = apps.size();
12119                for (int ia=0; ia<NA; ia++) {
12120                    ProcessRecord p = apps.valueAt(ia);
12121                    if (p.thread != null && p.thread.asBinder() == app) {
12122                        return p;
12123                    }
12124                }
12125            }
12126
12127            Slog.w(TAG, "Can't find mystery application for " + reason
12128                    + " from pid=" + Binder.getCallingPid()
12129                    + " uid=" + Binder.getCallingUid() + ": " + app);
12130            return null;
12131        }
12132    }
12133
12134    /**
12135     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
12136     * to append various headers to the dropbox log text.
12137     */
12138    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
12139            StringBuilder sb) {
12140        // Watchdog thread ends up invoking this function (with
12141        // a null ProcessRecord) to add the stack file to dropbox.
12142        // Do not acquire a lock on this (am) in such cases, as it
12143        // could cause a potential deadlock, if and when watchdog
12144        // is invoked due to unavailability of lock on am and it
12145        // would prevent watchdog from killing system_server.
12146        if (process == null) {
12147            sb.append("Process: ").append(processName).append("\n");
12148            return;
12149        }
12150        // Note: ProcessRecord 'process' is guarded by the service
12151        // instance.  (notably process.pkgList, which could otherwise change
12152        // concurrently during execution of this method)
12153        synchronized (this) {
12154            sb.append("Process: ").append(processName).append("\n");
12155            int flags = process.info.flags;
12156            IPackageManager pm = AppGlobals.getPackageManager();
12157            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
12158            for (int ip=0; ip<process.pkgList.size(); ip++) {
12159                String pkg = process.pkgList.keyAt(ip);
12160                sb.append("Package: ").append(pkg);
12161                try {
12162                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
12163                    if (pi != null) {
12164                        sb.append(" v").append(pi.versionCode);
12165                        if (pi.versionName != null) {
12166                            sb.append(" (").append(pi.versionName).append(")");
12167                        }
12168                    }
12169                } catch (RemoteException e) {
12170                    Slog.e(TAG, "Error getting package info: " + pkg, e);
12171                }
12172                sb.append("\n");
12173            }
12174        }
12175    }
12176
12177    private static String processClass(ProcessRecord process) {
12178        if (process == null || process.pid == MY_PID) {
12179            return "system_server";
12180        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
12181            return "system_app";
12182        } else {
12183            return "data_app";
12184        }
12185    }
12186
12187    /**
12188     * Write a description of an error (crash, WTF, ANR) to the drop box.
12189     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
12190     * @param process which caused the error, null means the system server
12191     * @param activity which triggered the error, null if unknown
12192     * @param parent activity related to the error, null if unknown
12193     * @param subject line related to the error, null if absent
12194     * @param report in long form describing the error, null if absent
12195     * @param logFile to include in the report, null if none
12196     * @param crashInfo giving an application stack trace, null if absent
12197     */
12198    public void addErrorToDropBox(String eventType,
12199            ProcessRecord process, String processName, ActivityRecord activity,
12200            ActivityRecord parent, String subject,
12201            final String report, final File logFile,
12202            final ApplicationErrorReport.CrashInfo crashInfo) {
12203        // NOTE -- this must never acquire the ActivityManagerService lock,
12204        // otherwise the watchdog may be prevented from resetting the system.
12205
12206        final String dropboxTag = processClass(process) + "_" + eventType;
12207        final DropBoxManager dbox = (DropBoxManager)
12208                mContext.getSystemService(Context.DROPBOX_SERVICE);
12209
12210        // Exit early if the dropbox isn't configured to accept this report type.
12211        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12212
12213        final StringBuilder sb = new StringBuilder(1024);
12214        appendDropBoxProcessHeaders(process, processName, sb);
12215        if (activity != null) {
12216            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
12217        }
12218        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
12219            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
12220        }
12221        if (parent != null && parent != activity) {
12222            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
12223        }
12224        if (subject != null) {
12225            sb.append("Subject: ").append(subject).append("\n");
12226        }
12227        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12228        if (Debug.isDebuggerConnected()) {
12229            sb.append("Debugger: Connected\n");
12230        }
12231        sb.append("\n");
12232
12233        // Do the rest in a worker thread to avoid blocking the caller on I/O
12234        // (After this point, we shouldn't access AMS internal data structures.)
12235        Thread worker = new Thread("Error dump: " + dropboxTag) {
12236            @Override
12237            public void run() {
12238                if (report != null) {
12239                    sb.append(report);
12240                }
12241                if (logFile != null) {
12242                    try {
12243                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
12244                                    "\n\n[[TRUNCATED]]"));
12245                    } catch (IOException e) {
12246                        Slog.e(TAG, "Error reading " + logFile, e);
12247                    }
12248                }
12249                if (crashInfo != null && crashInfo.stackTrace != null) {
12250                    sb.append(crashInfo.stackTrace);
12251                }
12252
12253                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
12254                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
12255                if (lines > 0) {
12256                    sb.append("\n");
12257
12258                    // Merge several logcat streams, and take the last N lines
12259                    InputStreamReader input = null;
12260                    try {
12261                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
12262                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
12263                                "-b", "crash",
12264                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
12265
12266                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
12267                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
12268                        input = new InputStreamReader(logcat.getInputStream());
12269
12270                        int num;
12271                        char[] buf = new char[8192];
12272                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
12273                    } catch (IOException e) {
12274                        Slog.e(TAG, "Error running logcat", e);
12275                    } finally {
12276                        if (input != null) try { input.close(); } catch (IOException e) {}
12277                    }
12278                }
12279
12280                dbox.addText(dropboxTag, sb.toString());
12281            }
12282        };
12283
12284        if (process == null) {
12285            // If process is null, we are being called from some internal code
12286            // and may be about to die -- run this synchronously.
12287            worker.run();
12288        } else {
12289            worker.start();
12290        }
12291    }
12292
12293    /**
12294     * Bring up the "unexpected error" dialog box for a crashing app.
12295     * Deal with edge cases (intercepts from instrumented applications,
12296     * ActivityController, error intent receivers, that sort of thing).
12297     * @param r the application crashing
12298     * @param crashInfo describing the failure
12299     */
12300    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12301        long timeMillis = System.currentTimeMillis();
12302        String shortMsg = crashInfo.exceptionClassName;
12303        String longMsg = crashInfo.exceptionMessage;
12304        String stackTrace = crashInfo.stackTrace;
12305        if (shortMsg != null && longMsg != null) {
12306            longMsg = shortMsg + ": " + longMsg;
12307        } else if (shortMsg != null) {
12308            longMsg = shortMsg;
12309        }
12310
12311        AppErrorResult result = new AppErrorResult();
12312        synchronized (this) {
12313            if (mController != null) {
12314                try {
12315                    String name = r != null ? r.processName : null;
12316                    int pid = r != null ? r.pid : Binder.getCallingPid();
12317                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
12318                    if (!mController.appCrashed(name, pid,
12319                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12320                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12321                                && "Native crash".equals(crashInfo.exceptionClassName)) {
12322                            Slog.w(TAG, "Skip killing native crashed app " + name
12323                                    + "(" + pid + ") during testing");
12324                        } else {
12325                            Slog.w(TAG, "Force-killing crashed app " + name
12326                                    + " at watcher's request");
12327                            if (r != null) {
12328                                r.kill("crash", true);
12329                            } else {
12330                                // Huh.
12331                                Process.killProcess(pid);
12332                                Process.killProcessGroup(uid, pid);
12333                            }
12334                        }
12335                        return;
12336                    }
12337                } catch (RemoteException e) {
12338                    mController = null;
12339                    Watchdog.getInstance().setActivityController(null);
12340                }
12341            }
12342
12343            final long origId = Binder.clearCallingIdentity();
12344
12345            // If this process is running instrumentation, finish it.
12346            if (r != null && r.instrumentationClass != null) {
12347                Slog.w(TAG, "Error in app " + r.processName
12348                      + " running instrumentation " + r.instrumentationClass + ":");
12349                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12350                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12351                Bundle info = new Bundle();
12352                info.putString("shortMsg", shortMsg);
12353                info.putString("longMsg", longMsg);
12354                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12355                Binder.restoreCallingIdentity(origId);
12356                return;
12357            }
12358
12359            // Log crash in battery stats.
12360            if (r != null) {
12361                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12362            }
12363
12364            // If we can't identify the process or it's already exceeded its crash quota,
12365            // quit right away without showing a crash dialog.
12366            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12367                Binder.restoreCallingIdentity(origId);
12368                return;
12369            }
12370
12371            Message msg = Message.obtain();
12372            msg.what = SHOW_ERROR_MSG;
12373            HashMap data = new HashMap();
12374            data.put("result", result);
12375            data.put("app", r);
12376            msg.obj = data;
12377            mUiHandler.sendMessage(msg);
12378
12379            Binder.restoreCallingIdentity(origId);
12380        }
12381
12382        int res = result.get();
12383
12384        Intent appErrorIntent = null;
12385        synchronized (this) {
12386            if (r != null && !r.isolated) {
12387                // XXX Can't keep track of crash time for isolated processes,
12388                // since they don't have a persistent identity.
12389                mProcessCrashTimes.put(r.info.processName, r.uid,
12390                        SystemClock.uptimeMillis());
12391            }
12392            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12393                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12394            }
12395        }
12396
12397        if (appErrorIntent != null) {
12398            try {
12399                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12400            } catch (ActivityNotFoundException e) {
12401                Slog.w(TAG, "bug report receiver dissappeared", e);
12402            }
12403        }
12404    }
12405
12406    Intent createAppErrorIntentLocked(ProcessRecord r,
12407            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12408        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12409        if (report == null) {
12410            return null;
12411        }
12412        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12413        result.setComponent(r.errorReportReceiver);
12414        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12415        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12416        return result;
12417    }
12418
12419    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12420            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12421        if (r.errorReportReceiver == null) {
12422            return null;
12423        }
12424
12425        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12426            return null;
12427        }
12428
12429        ApplicationErrorReport report = new ApplicationErrorReport();
12430        report.packageName = r.info.packageName;
12431        report.installerPackageName = r.errorReportReceiver.getPackageName();
12432        report.processName = r.processName;
12433        report.time = timeMillis;
12434        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12435
12436        if (r.crashing || r.forceCrashReport) {
12437            report.type = ApplicationErrorReport.TYPE_CRASH;
12438            report.crashInfo = crashInfo;
12439        } else if (r.notResponding) {
12440            report.type = ApplicationErrorReport.TYPE_ANR;
12441            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12442
12443            report.anrInfo.activity = r.notRespondingReport.tag;
12444            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12445            report.anrInfo.info = r.notRespondingReport.longMsg;
12446        }
12447
12448        return report;
12449    }
12450
12451    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12452        enforceNotIsolatedCaller("getProcessesInErrorState");
12453        // assume our apps are happy - lazy create the list
12454        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12455
12456        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12457                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12458        int userId = UserHandle.getUserId(Binder.getCallingUid());
12459
12460        synchronized (this) {
12461
12462            // iterate across all processes
12463            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12464                ProcessRecord app = mLruProcesses.get(i);
12465                if (!allUsers && app.userId != userId) {
12466                    continue;
12467                }
12468                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12469                    // This one's in trouble, so we'll generate a report for it
12470                    // crashes are higher priority (in case there's a crash *and* an anr)
12471                    ActivityManager.ProcessErrorStateInfo report = null;
12472                    if (app.crashing) {
12473                        report = app.crashingReport;
12474                    } else if (app.notResponding) {
12475                        report = app.notRespondingReport;
12476                    }
12477
12478                    if (report != null) {
12479                        if (errList == null) {
12480                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12481                        }
12482                        errList.add(report);
12483                    } else {
12484                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12485                                " crashing = " + app.crashing +
12486                                " notResponding = " + app.notResponding);
12487                    }
12488                }
12489            }
12490        }
12491
12492        return errList;
12493    }
12494
12495    static int procStateToImportance(int procState, int memAdj,
12496            ActivityManager.RunningAppProcessInfo currApp) {
12497        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12498        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12499            currApp.lru = memAdj;
12500        } else {
12501            currApp.lru = 0;
12502        }
12503        return imp;
12504    }
12505
12506    private void fillInProcMemInfo(ProcessRecord app,
12507            ActivityManager.RunningAppProcessInfo outInfo) {
12508        outInfo.pid = app.pid;
12509        outInfo.uid = app.info.uid;
12510        if (mHeavyWeightProcess == app) {
12511            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12512        }
12513        if (app.persistent) {
12514            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12515        }
12516        if (app.activities.size() > 0) {
12517            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12518        }
12519        outInfo.lastTrimLevel = app.trimMemoryLevel;
12520        int adj = app.curAdj;
12521        int procState = app.curProcState;
12522        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12523        outInfo.importanceReasonCode = app.adjTypeCode;
12524        outInfo.processState = app.curProcState;
12525    }
12526
12527    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12528        enforceNotIsolatedCaller("getRunningAppProcesses");
12529
12530        final int callingUid = Binder.getCallingUid();
12531
12532        // Lazy instantiation of list
12533        List<ActivityManager.RunningAppProcessInfo> runList = null;
12534        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12535                callingUid) == PackageManager.PERMISSION_GRANTED;
12536        final int userId = UserHandle.getUserId(callingUid);
12537        final boolean allUids = isGetTasksAllowed(
12538                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
12539
12540        synchronized (this) {
12541            // Iterate across all processes
12542            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
12543                ProcessRecord app = mLruProcesses.get(i);
12544                if ((!allUsers && app.userId != userId)
12545                        || (!allUids && app.uid != callingUid)) {
12546                    continue;
12547                }
12548                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12549                    // Generate process state info for running application
12550                    ActivityManager.RunningAppProcessInfo currApp =
12551                        new ActivityManager.RunningAppProcessInfo(app.processName,
12552                                app.pid, app.getPackageList());
12553                    fillInProcMemInfo(app, currApp);
12554                    if (app.adjSource instanceof ProcessRecord) {
12555                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12556                        currApp.importanceReasonImportance =
12557                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12558                                        app.adjSourceProcState);
12559                    } else if (app.adjSource instanceof ActivityRecord) {
12560                        ActivityRecord r = (ActivityRecord)app.adjSource;
12561                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12562                    }
12563                    if (app.adjTarget instanceof ComponentName) {
12564                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12565                    }
12566                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12567                    //        + " lru=" + currApp.lru);
12568                    if (runList == null) {
12569                        runList = new ArrayList<>();
12570                    }
12571                    runList.add(currApp);
12572                }
12573            }
12574        }
12575        return runList;
12576    }
12577
12578    public List<ApplicationInfo> getRunningExternalApplications() {
12579        enforceNotIsolatedCaller("getRunningExternalApplications");
12580        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12581        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12582        if (runningApps != null && runningApps.size() > 0) {
12583            Set<String> extList = new HashSet<String>();
12584            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12585                if (app.pkgList != null) {
12586                    for (String pkg : app.pkgList) {
12587                        extList.add(pkg);
12588                    }
12589                }
12590            }
12591            IPackageManager pm = AppGlobals.getPackageManager();
12592            for (String pkg : extList) {
12593                try {
12594                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12595                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12596                        retList.add(info);
12597                    }
12598                } catch (RemoteException e) {
12599                }
12600            }
12601        }
12602        return retList;
12603    }
12604
12605    @Override
12606    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12607        enforceNotIsolatedCaller("getMyMemoryState");
12608        synchronized (this) {
12609            ProcessRecord proc;
12610            synchronized (mPidsSelfLocked) {
12611                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12612            }
12613            fillInProcMemInfo(proc, outInfo);
12614        }
12615    }
12616
12617    @Override
12618    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12619        if (checkCallingPermission(android.Manifest.permission.DUMP)
12620                != PackageManager.PERMISSION_GRANTED) {
12621            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12622                    + Binder.getCallingPid()
12623                    + ", uid=" + Binder.getCallingUid()
12624                    + " without permission "
12625                    + android.Manifest.permission.DUMP);
12626            return;
12627        }
12628
12629        boolean dumpAll = false;
12630        boolean dumpClient = false;
12631        String dumpPackage = null;
12632
12633        int opti = 0;
12634        while (opti < args.length) {
12635            String opt = args[opti];
12636            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12637                break;
12638            }
12639            opti++;
12640            if ("-a".equals(opt)) {
12641                dumpAll = true;
12642            } else if ("-c".equals(opt)) {
12643                dumpClient = true;
12644            } else if ("-p".equals(opt)) {
12645                if (opti < args.length) {
12646                    dumpPackage = args[opti];
12647                    opti++;
12648                } else {
12649                    pw.println("Error: -p option requires package argument");
12650                    return;
12651                }
12652                dumpClient = true;
12653            } else if ("-h".equals(opt)) {
12654                pw.println("Activity manager dump options:");
12655                pw.println("  [-a] [-c] [-p package] [-h] [cmd] ...");
12656                pw.println("  cmd may be one of:");
12657                pw.println("    a[ctivities]: activity stack state");
12658                pw.println("    r[recents]: recent activities state");
12659                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12660                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12661                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12662                pw.println("    o[om]: out of memory management");
12663                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12664                pw.println("    provider [COMP_SPEC]: provider client-side state");
12665                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12666                pw.println("    as[sociations]: tracked app associations");
12667                pw.println("    service [COMP_SPEC]: service client-side state");
12668                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12669                pw.println("    all: dump all activities");
12670                pw.println("    top: dump the top activity");
12671                pw.println("    write: write all pending state to storage");
12672                pw.println("    track-associations: enable association tracking");
12673                pw.println("    untrack-associations: disable and clear association tracking");
12674                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12675                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12676                pw.println("    a partial substring in a component name, a");
12677                pw.println("    hex object identifier.");
12678                pw.println("  -a: include all available server state.");
12679                pw.println("  -c: include client state.");
12680                pw.println("  -p: limit output to given package.");
12681                return;
12682            } else {
12683                pw.println("Unknown argument: " + opt + "; use -h for help");
12684            }
12685        }
12686
12687        long origId = Binder.clearCallingIdentity();
12688        boolean more = false;
12689        // Is the caller requesting to dump a particular piece of data?
12690        if (opti < args.length) {
12691            String cmd = args[opti];
12692            opti++;
12693            if ("activities".equals(cmd) || "a".equals(cmd)) {
12694                synchronized (this) {
12695                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12696                }
12697            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12698                synchronized (this) {
12699                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
12700                }
12701            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12702                String[] newArgs;
12703                String name;
12704                if (opti >= args.length) {
12705                    name = null;
12706                    newArgs = EMPTY_STRING_ARRAY;
12707                } else {
12708                    dumpPackage = args[opti];
12709                    opti++;
12710                    newArgs = new String[args.length - opti];
12711                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12712                            args.length - opti);
12713                }
12714                synchronized (this) {
12715                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
12716                }
12717            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12718                String[] newArgs;
12719                String name;
12720                if (opti >= args.length) {
12721                    name = null;
12722                    newArgs = EMPTY_STRING_ARRAY;
12723                } else {
12724                    dumpPackage = args[opti];
12725                    opti++;
12726                    newArgs = new String[args.length - opti];
12727                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12728                            args.length - opti);
12729                }
12730                synchronized (this) {
12731                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
12732                }
12733            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12734                String[] newArgs;
12735                String name;
12736                if (opti >= args.length) {
12737                    name = null;
12738                    newArgs = EMPTY_STRING_ARRAY;
12739                } else {
12740                    dumpPackage = args[opti];
12741                    opti++;
12742                    newArgs = new String[args.length - opti];
12743                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12744                            args.length - opti);
12745                }
12746                synchronized (this) {
12747                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
12748                }
12749            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12750                synchronized (this) {
12751                    dumpOomLocked(fd, pw, args, opti, true);
12752                }
12753            } else if ("provider".equals(cmd)) {
12754                String[] newArgs;
12755                String name;
12756                if (opti >= args.length) {
12757                    name = null;
12758                    newArgs = EMPTY_STRING_ARRAY;
12759                } else {
12760                    name = args[opti];
12761                    opti++;
12762                    newArgs = new String[args.length - opti];
12763                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12764                }
12765                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12766                    pw.println("No providers match: " + name);
12767                    pw.println("Use -h for help.");
12768                }
12769            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12770                synchronized (this) {
12771                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12772                }
12773            } else if ("service".equals(cmd)) {
12774                String[] newArgs;
12775                String name;
12776                if (opti >= args.length) {
12777                    name = null;
12778                    newArgs = EMPTY_STRING_ARRAY;
12779                } else {
12780                    name = args[opti];
12781                    opti++;
12782                    newArgs = new String[args.length - opti];
12783                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12784                            args.length - opti);
12785                }
12786                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12787                    pw.println("No services match: " + name);
12788                    pw.println("Use -h for help.");
12789                }
12790            } else if ("package".equals(cmd)) {
12791                String[] newArgs;
12792                if (opti >= args.length) {
12793                    pw.println("package: no package name specified");
12794                    pw.println("Use -h for help.");
12795                } else {
12796                    dumpPackage = args[opti];
12797                    opti++;
12798                    newArgs = new String[args.length - opti];
12799                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12800                            args.length - opti);
12801                    args = newArgs;
12802                    opti = 0;
12803                    more = true;
12804                }
12805            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
12806                synchronized (this) {
12807                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12808                }
12809            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12810                synchronized (this) {
12811                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12812                }
12813            } else if ("write".equals(cmd)) {
12814                mTaskPersister.flush();
12815                pw.println("All tasks persisted.");
12816                return;
12817            } else if ("track-associations".equals(cmd)) {
12818                synchronized (this) {
12819                    if (!mTrackingAssociations) {
12820                        mTrackingAssociations = true;
12821                        pw.println("Association tracking started.");
12822                    } else {
12823                        pw.println("Association tracking already enabled.");
12824                    }
12825                }
12826                return;
12827            } else if ("untrack-associations".equals(cmd)) {
12828                synchronized (this) {
12829                    if (mTrackingAssociations) {
12830                        mTrackingAssociations = false;
12831                        mAssociations.clear();
12832                        pw.println("Association tracking stopped.");
12833                    } else {
12834                        pw.println("Association tracking not running.");
12835                    }
12836                }
12837                return;
12838            } else {
12839                // Dumping a single activity?
12840                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12841                    pw.println("Bad activity command, or no activities match: " + cmd);
12842                    pw.println("Use -h for help.");
12843                }
12844            }
12845            if (!more) {
12846                Binder.restoreCallingIdentity(origId);
12847                return;
12848            }
12849        }
12850
12851        // No piece of data specified, dump everything.
12852        synchronized (this) {
12853            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12854            pw.println();
12855            if (dumpAll) {
12856                pw.println("-------------------------------------------------------------------------------");
12857            }
12858            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12859            pw.println();
12860            if (dumpAll) {
12861                pw.println("-------------------------------------------------------------------------------");
12862            }
12863            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12864            pw.println();
12865            if (dumpAll) {
12866                pw.println("-------------------------------------------------------------------------------");
12867            }
12868            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12869            pw.println();
12870            if (dumpAll) {
12871                pw.println("-------------------------------------------------------------------------------");
12872            }
12873            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12874            pw.println();
12875            if (dumpAll) {
12876                pw.println("-------------------------------------------------------------------------------");
12877            }
12878            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12879            if (mAssociations.size() > 0) {
12880                pw.println();
12881                if (dumpAll) {
12882                    pw.println("-------------------------------------------------------------------------------");
12883                }
12884                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12885            }
12886            pw.println();
12887            if (dumpAll) {
12888                pw.println("-------------------------------------------------------------------------------");
12889            }
12890            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12891        }
12892        Binder.restoreCallingIdentity(origId);
12893    }
12894
12895    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12896            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12897        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12898
12899        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12900                dumpPackage);
12901        boolean needSep = printedAnything;
12902
12903        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12904                dumpPackage, needSep, "  mFocusedActivity: ");
12905        if (printed) {
12906            printedAnything = true;
12907            needSep = false;
12908        }
12909
12910        if (dumpPackage == null) {
12911            if (needSep) {
12912                pw.println();
12913            }
12914            needSep = true;
12915            printedAnything = true;
12916            mStackSupervisor.dump(pw, "  ");
12917        }
12918
12919        if (!printedAnything) {
12920            pw.println("  (nothing)");
12921        }
12922    }
12923
12924    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12925            int opti, boolean dumpAll, String dumpPackage) {
12926        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12927
12928        boolean printedAnything = false;
12929
12930        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12931            boolean printedHeader = false;
12932
12933            final int N = mRecentTasks.size();
12934            for (int i=0; i<N; i++) {
12935                TaskRecord tr = mRecentTasks.get(i);
12936                if (dumpPackage != null) {
12937                    if (tr.realActivity == null ||
12938                            !dumpPackage.equals(tr.realActivity)) {
12939                        continue;
12940                    }
12941                }
12942                if (!printedHeader) {
12943                    pw.println("  Recent tasks:");
12944                    printedHeader = true;
12945                    printedAnything = true;
12946                }
12947                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12948                        pw.println(tr);
12949                if (dumpAll) {
12950                    mRecentTasks.get(i).dump(pw, "    ");
12951                }
12952            }
12953        }
12954
12955        if (!printedAnything) {
12956            pw.println("  (nothing)");
12957        }
12958    }
12959
12960    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12961            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12962        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
12963
12964        int dumpUid = 0;
12965        if (dumpPackage != null) {
12966            IPackageManager pm = AppGlobals.getPackageManager();
12967            try {
12968                dumpUid = pm.getPackageUid(dumpPackage, 0);
12969            } catch (RemoteException e) {
12970            }
12971        }
12972
12973        boolean printedAnything = false;
12974
12975        final long now = SystemClock.uptimeMillis();
12976
12977        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
12978            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
12979                    = mAssociations.valueAt(i1);
12980            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
12981                SparseArray<ArrayMap<String, Association>> sourceUids
12982                        = targetComponents.valueAt(i2);
12983                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
12984                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
12985                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
12986                        Association ass = sourceProcesses.valueAt(i4);
12987                        if (dumpPackage != null) {
12988                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
12989                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
12990                                continue;
12991                            }
12992                        }
12993                        printedAnything = true;
12994                        pw.print("  ");
12995                        pw.print(ass.mTargetProcess);
12996                        pw.print("/");
12997                        UserHandle.formatUid(pw, ass.mTargetUid);
12998                        pw.print(" <- ");
12999                        pw.print(ass.mSourceProcess);
13000                        pw.print("/");
13001                        UserHandle.formatUid(pw, ass.mSourceUid);
13002                        pw.println();
13003                        pw.print("    via ");
13004                        pw.print(ass.mTargetComponent.flattenToShortString());
13005                        pw.println();
13006                        pw.print("    ");
13007                        long dur = ass.mTime;
13008                        if (ass.mNesting > 0) {
13009                            dur += now - ass.mStartTime;
13010                        }
13011                        TimeUtils.formatDuration(dur, pw);
13012                        pw.print(" (");
13013                        pw.print(ass.mCount);
13014                        pw.println(" times)");
13015                        if (ass.mNesting > 0) {
13016                            pw.print("    ");
13017                            pw.print(" Currently active: ");
13018                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13019                            pw.println();
13020                        }
13021                    }
13022                }
13023            }
13024
13025        }
13026
13027        if (!printedAnything) {
13028            pw.println("  (nothing)");
13029        }
13030    }
13031
13032    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13033            int opti, boolean dumpAll, String dumpPackage) {
13034        boolean needSep = false;
13035        boolean printedAnything = false;
13036        int numPers = 0;
13037
13038        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13039
13040        if (dumpAll) {
13041            final int NP = mProcessNames.getMap().size();
13042            for (int ip=0; ip<NP; ip++) {
13043                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13044                final int NA = procs.size();
13045                for (int ia=0; ia<NA; ia++) {
13046                    ProcessRecord r = procs.valueAt(ia);
13047                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13048                        continue;
13049                    }
13050                    if (!needSep) {
13051                        pw.println("  All known processes:");
13052                        needSep = true;
13053                        printedAnything = true;
13054                    }
13055                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13056                        pw.print(" UID "); pw.print(procs.keyAt(ia));
13057                        pw.print(" "); pw.println(r);
13058                    r.dump(pw, "    ");
13059                    if (r.persistent) {
13060                        numPers++;
13061                    }
13062                }
13063            }
13064        }
13065
13066        if (mIsolatedProcesses.size() > 0) {
13067            boolean printed = false;
13068            for (int i=0; i<mIsolatedProcesses.size(); i++) {
13069                ProcessRecord r = mIsolatedProcesses.valueAt(i);
13070                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13071                    continue;
13072                }
13073                if (!printed) {
13074                    if (needSep) {
13075                        pw.println();
13076                    }
13077                    pw.println("  Isolated process list (sorted by uid):");
13078                    printedAnything = true;
13079                    printed = true;
13080                    needSep = true;
13081                }
13082                pw.println(String.format("%sIsolated #%2d: %s",
13083                        "    ", i, r.toString()));
13084            }
13085        }
13086
13087        if (mActiveUids.size() > 0) {
13088            if (needSep) {
13089                pw.println();
13090            }
13091            pw.println("  UID states:");
13092            for (int i=0; i<mActiveUids.size(); i++) {
13093                UidRecord uidRec = mActiveUids.valueAt(i);
13094                pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13095                pw.print(": "); pw.println(uidRec);
13096            }
13097            needSep = true;
13098            printedAnything = true;
13099        }
13100
13101        if (mLruProcesses.size() > 0) {
13102            if (needSep) {
13103                pw.println();
13104            }
13105            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
13106                    pw.print(" total, non-act at ");
13107                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13108                    pw.print(", non-svc at ");
13109                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13110                    pw.println("):");
13111            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
13112            needSep = true;
13113            printedAnything = true;
13114        }
13115
13116        if (dumpAll || dumpPackage != null) {
13117            synchronized (mPidsSelfLocked) {
13118                boolean printed = false;
13119                for (int i=0; i<mPidsSelfLocked.size(); i++) {
13120                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
13121                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13122                        continue;
13123                    }
13124                    if (!printed) {
13125                        if (needSep) pw.println();
13126                        needSep = true;
13127                        pw.println("  PID mappings:");
13128                        printed = true;
13129                        printedAnything = true;
13130                    }
13131                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
13132                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
13133                }
13134            }
13135        }
13136
13137        if (mForegroundProcesses.size() > 0) {
13138            synchronized (mPidsSelfLocked) {
13139                boolean printed = false;
13140                for (int i=0; i<mForegroundProcesses.size(); i++) {
13141                    ProcessRecord r = mPidsSelfLocked.get(
13142                            mForegroundProcesses.valueAt(i).pid);
13143                    if (dumpPackage != null && (r == null
13144                            || !r.pkgList.containsKey(dumpPackage))) {
13145                        continue;
13146                    }
13147                    if (!printed) {
13148                        if (needSep) pw.println();
13149                        needSep = true;
13150                        pw.println("  Foreground Processes:");
13151                        printed = true;
13152                        printedAnything = true;
13153                    }
13154                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
13155                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
13156                }
13157            }
13158        }
13159
13160        if (mPersistentStartingProcesses.size() > 0) {
13161            if (needSep) pw.println();
13162            needSep = true;
13163            printedAnything = true;
13164            pw.println("  Persisent processes that are starting:");
13165            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
13166                    "Starting Norm", "Restarting PERS", dumpPackage);
13167        }
13168
13169        if (mRemovedProcesses.size() > 0) {
13170            if (needSep) pw.println();
13171            needSep = true;
13172            printedAnything = true;
13173            pw.println("  Processes that are being removed:");
13174            dumpProcessList(pw, this, mRemovedProcesses, "    ",
13175                    "Removed Norm", "Removed PERS", dumpPackage);
13176        }
13177
13178        if (mProcessesOnHold.size() > 0) {
13179            if (needSep) pw.println();
13180            needSep = true;
13181            printedAnything = true;
13182            pw.println("  Processes that are on old until the system is ready:");
13183            dumpProcessList(pw, this, mProcessesOnHold, "    ",
13184                    "OnHold Norm", "OnHold PERS", dumpPackage);
13185        }
13186
13187        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
13188
13189        if (mProcessCrashTimes.getMap().size() > 0) {
13190            boolean printed = false;
13191            long now = SystemClock.uptimeMillis();
13192            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
13193            final int NP = pmap.size();
13194            for (int ip=0; ip<NP; ip++) {
13195                String pname = pmap.keyAt(ip);
13196                SparseArray<Long> uids = pmap.valueAt(ip);
13197                final int N = uids.size();
13198                for (int i=0; i<N; i++) {
13199                    int puid = uids.keyAt(i);
13200                    ProcessRecord r = mProcessNames.get(pname, puid);
13201                    if (dumpPackage != null && (r == null
13202                            || !r.pkgList.containsKey(dumpPackage))) {
13203                        continue;
13204                    }
13205                    if (!printed) {
13206                        if (needSep) pw.println();
13207                        needSep = true;
13208                        pw.println("  Time since processes crashed:");
13209                        printed = true;
13210                        printedAnything = true;
13211                    }
13212                    pw.print("    Process "); pw.print(pname);
13213                            pw.print(" uid "); pw.print(puid);
13214                            pw.print(": last crashed ");
13215                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
13216                            pw.println(" ago");
13217                }
13218            }
13219        }
13220
13221        if (mBadProcesses.getMap().size() > 0) {
13222            boolean printed = false;
13223            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
13224            final int NP = pmap.size();
13225            for (int ip=0; ip<NP; ip++) {
13226                String pname = pmap.keyAt(ip);
13227                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
13228                final int N = uids.size();
13229                for (int i=0; i<N; i++) {
13230                    int puid = uids.keyAt(i);
13231                    ProcessRecord r = mProcessNames.get(pname, puid);
13232                    if (dumpPackage != null && (r == null
13233                            || !r.pkgList.containsKey(dumpPackage))) {
13234                        continue;
13235                    }
13236                    if (!printed) {
13237                        if (needSep) pw.println();
13238                        needSep = true;
13239                        pw.println("  Bad processes:");
13240                        printedAnything = true;
13241                    }
13242                    BadProcessInfo info = uids.valueAt(i);
13243                    pw.print("    Bad process "); pw.print(pname);
13244                            pw.print(" uid "); pw.print(puid);
13245                            pw.print(": crashed at time "); pw.println(info.time);
13246                    if (info.shortMsg != null) {
13247                        pw.print("      Short msg: "); pw.println(info.shortMsg);
13248                    }
13249                    if (info.longMsg != null) {
13250                        pw.print("      Long msg: "); pw.println(info.longMsg);
13251                    }
13252                    if (info.stack != null) {
13253                        pw.println("      Stack:");
13254                        int lastPos = 0;
13255                        for (int pos=0; pos<info.stack.length(); pos++) {
13256                            if (info.stack.charAt(pos) == '\n') {
13257                                pw.print("        ");
13258                                pw.write(info.stack, lastPos, pos-lastPos);
13259                                pw.println();
13260                                lastPos = pos+1;
13261                            }
13262                        }
13263                        if (lastPos < info.stack.length()) {
13264                            pw.print("        ");
13265                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
13266                            pw.println();
13267                        }
13268                    }
13269                }
13270            }
13271        }
13272
13273        if (dumpPackage == null) {
13274            pw.println();
13275            needSep = false;
13276            pw.println("  mStartedUsers:");
13277            for (int i=0; i<mStartedUsers.size(); i++) {
13278                UserStartedState uss = mStartedUsers.valueAt(i);
13279                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
13280                        pw.print(": "); uss.dump("", pw);
13281            }
13282            pw.print("  mStartedUserArray: [");
13283            for (int i=0; i<mStartedUserArray.length; i++) {
13284                if (i > 0) pw.print(", ");
13285                pw.print(mStartedUserArray[i]);
13286            }
13287            pw.println("]");
13288            pw.print("  mUserLru: [");
13289            for (int i=0; i<mUserLru.size(); i++) {
13290                if (i > 0) pw.print(", ");
13291                pw.print(mUserLru.get(i));
13292            }
13293            pw.println("]");
13294            if (dumpAll) {
13295                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
13296            }
13297            synchronized (mUserProfileGroupIdsSelfLocked) {
13298                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
13299                    pw.println("  mUserProfileGroupIds:");
13300                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
13301                        pw.print("    User #");
13302                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
13303                        pw.print(" -> profile #");
13304                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
13305                    }
13306                }
13307            }
13308        }
13309        if (mHomeProcess != null && (dumpPackage == null
13310                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13311            if (needSep) {
13312                pw.println();
13313                needSep = false;
13314            }
13315            pw.println("  mHomeProcess: " + mHomeProcess);
13316        }
13317        if (mPreviousProcess != null && (dumpPackage == null
13318                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13319            if (needSep) {
13320                pw.println();
13321                needSep = false;
13322            }
13323            pw.println("  mPreviousProcess: " + mPreviousProcess);
13324        }
13325        if (dumpAll) {
13326            StringBuilder sb = new StringBuilder(128);
13327            sb.append("  mPreviousProcessVisibleTime: ");
13328            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13329            pw.println(sb);
13330        }
13331        if (mHeavyWeightProcess != null && (dumpPackage == null
13332                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13333            if (needSep) {
13334                pw.println();
13335                needSep = false;
13336            }
13337            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13338        }
13339        if (dumpPackage == null) {
13340            pw.println("  mConfiguration: " + mConfiguration);
13341        }
13342        if (dumpAll) {
13343            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13344            if (mCompatModePackages.getPackages().size() > 0) {
13345                boolean printed = false;
13346                for (Map.Entry<String, Integer> entry
13347                        : mCompatModePackages.getPackages().entrySet()) {
13348                    String pkg = entry.getKey();
13349                    int mode = entry.getValue();
13350                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
13351                        continue;
13352                    }
13353                    if (!printed) {
13354                        pw.println("  mScreenCompatPackages:");
13355                        printed = true;
13356                    }
13357                    pw.print("    "); pw.print(pkg); pw.print(": ");
13358                            pw.print(mode); pw.println();
13359                }
13360            }
13361        }
13362        if (dumpPackage == null) {
13363            pw.println("  mWakefulness="
13364                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
13365            pw.println("  mSleepTokens=" + mSleepTokens);
13366            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
13367                    + lockScreenShownToString());
13368            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
13369            if (mRunningVoice != null) {
13370                pw.println("  mRunningVoice=" + mRunningVoice);
13371                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
13372            }
13373        }
13374        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
13375                || mOrigWaitForDebugger) {
13376            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
13377                    || dumpPackage.equals(mOrigDebugApp)) {
13378                if (needSep) {
13379                    pw.println();
13380                    needSep = false;
13381                }
13382                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
13383                        + " mDebugTransient=" + mDebugTransient
13384                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
13385            }
13386        }
13387        if (mCurAppTimeTracker != null) {
13388            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
13389        }
13390        if (mMemWatchProcesses.getMap().size() > 0) {
13391            pw.println("  Mem watch processes:");
13392            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
13393                    = mMemWatchProcesses.getMap();
13394            for (int i=0; i<procs.size(); i++) {
13395                final String proc = procs.keyAt(i);
13396                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
13397                for (int j=0; j<uids.size(); j++) {
13398                    if (needSep) {
13399                        pw.println();
13400                        needSep = false;
13401                    }
13402                    StringBuilder sb = new StringBuilder();
13403                    sb.append("    ").append(proc).append('/');
13404                    UserHandle.formatUid(sb, uids.keyAt(j));
13405                    Pair<Long, String> val = uids.valueAt(j);
13406                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
13407                    if (val.second != null) {
13408                        sb.append(", report to ").append(val.second);
13409                    }
13410                    pw.println(sb.toString());
13411                }
13412            }
13413            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
13414            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
13415            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
13416                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
13417        }
13418        if (mOpenGlTraceApp != null) {
13419            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
13420                if (needSep) {
13421                    pw.println();
13422                    needSep = false;
13423                }
13424                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
13425            }
13426        }
13427        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
13428                || mProfileFd != null) {
13429            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13430                if (needSep) {
13431                    pw.println();
13432                    needSep = false;
13433                }
13434                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13435                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13436                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13437                        + mAutoStopProfiler);
13438                pw.println("  mProfileType=" + mProfileType);
13439            }
13440        }
13441        if (dumpPackage == null) {
13442            if (mAlwaysFinishActivities || mController != null) {
13443                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
13444                        + " mController=" + mController);
13445            }
13446            if (dumpAll) {
13447                pw.println("  Total persistent processes: " + numPers);
13448                pw.println("  mProcessesReady=" + mProcessesReady
13449                        + " mSystemReady=" + mSystemReady
13450                        + " mBooted=" + mBooted
13451                        + " mFactoryTest=" + mFactoryTest);
13452                pw.println("  mBooting=" + mBooting
13453                        + " mCallFinishBooting=" + mCallFinishBooting
13454                        + " mBootAnimationComplete=" + mBootAnimationComplete);
13455                pw.print("  mLastPowerCheckRealtime=");
13456                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13457                        pw.println("");
13458                pw.print("  mLastPowerCheckUptime=");
13459                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13460                        pw.println("");
13461                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13462                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13463                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13464                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
13465                        + " (" + mLruProcesses.size() + " total)"
13466                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13467                        + " mNumServiceProcs=" + mNumServiceProcs
13468                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13469                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
13470                        + " mLastMemoryLevel" + mLastMemoryLevel
13471                        + " mLastNumProcesses" + mLastNumProcesses);
13472                long now = SystemClock.uptimeMillis();
13473                pw.print("  mLastIdleTime=");
13474                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
13475                        pw.print(" mLowRamSinceLastIdle=");
13476                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13477                        pw.println();
13478            }
13479        }
13480
13481        if (!printedAnything) {
13482            pw.println("  (nothing)");
13483        }
13484    }
13485
13486    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13487            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13488        if (mProcessesToGc.size() > 0) {
13489            boolean printed = false;
13490            long now = SystemClock.uptimeMillis();
13491            for (int i=0; i<mProcessesToGc.size(); i++) {
13492                ProcessRecord proc = mProcessesToGc.get(i);
13493                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13494                    continue;
13495                }
13496                if (!printed) {
13497                    if (needSep) pw.println();
13498                    needSep = true;
13499                    pw.println("  Processes that are waiting to GC:");
13500                    printed = true;
13501                }
13502                pw.print("    Process "); pw.println(proc);
13503                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13504                        pw.print(", last gced=");
13505                        pw.print(now-proc.lastRequestedGc);
13506                        pw.print(" ms ago, last lowMem=");
13507                        pw.print(now-proc.lastLowMemory);
13508                        pw.println(" ms ago");
13509
13510            }
13511        }
13512        return needSep;
13513    }
13514
13515    void printOomLevel(PrintWriter pw, String name, int adj) {
13516        pw.print("    ");
13517        if (adj >= 0) {
13518            pw.print(' ');
13519            if (adj < 10) pw.print(' ');
13520        } else {
13521            if (adj > -10) pw.print(' ');
13522        }
13523        pw.print(adj);
13524        pw.print(": ");
13525        pw.print(name);
13526        pw.print(" (");
13527        pw.print(mProcessList.getMemLevel(adj)/1024);
13528        pw.println(" kB)");
13529    }
13530
13531    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13532            int opti, boolean dumpAll) {
13533        boolean needSep = false;
13534
13535        if (mLruProcesses.size() > 0) {
13536            if (needSep) pw.println();
13537            needSep = true;
13538            pw.println("  OOM levels:");
13539            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13540            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13541            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13542            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13543            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13544            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13545            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13546            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13547            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13548            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13549            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13550            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13551            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13552            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13553
13554            if (needSep) pw.println();
13555            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13556                    pw.print(" total, non-act at ");
13557                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13558                    pw.print(", non-svc at ");
13559                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13560                    pw.println("):");
13561            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13562            needSep = true;
13563        }
13564
13565        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13566
13567        pw.println();
13568        pw.println("  mHomeProcess: " + mHomeProcess);
13569        pw.println("  mPreviousProcess: " + mPreviousProcess);
13570        if (mHeavyWeightProcess != null) {
13571            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13572        }
13573
13574        return true;
13575    }
13576
13577    /**
13578     * There are three ways to call this:
13579     *  - no provider specified: dump all the providers
13580     *  - a flattened component name that matched an existing provider was specified as the
13581     *    first arg: dump that one provider
13582     *  - the first arg isn't the flattened component name of an existing provider:
13583     *    dump all providers whose component contains the first arg as a substring
13584     */
13585    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13586            int opti, boolean dumpAll) {
13587        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13588    }
13589
13590    static class ItemMatcher {
13591        ArrayList<ComponentName> components;
13592        ArrayList<String> strings;
13593        ArrayList<Integer> objects;
13594        boolean all;
13595
13596        ItemMatcher() {
13597            all = true;
13598        }
13599
13600        void build(String name) {
13601            ComponentName componentName = ComponentName.unflattenFromString(name);
13602            if (componentName != null) {
13603                if (components == null) {
13604                    components = new ArrayList<ComponentName>();
13605                }
13606                components.add(componentName);
13607                all = false;
13608            } else {
13609                int objectId = 0;
13610                // Not a '/' separated full component name; maybe an object ID?
13611                try {
13612                    objectId = Integer.parseInt(name, 16);
13613                    if (objects == null) {
13614                        objects = new ArrayList<Integer>();
13615                    }
13616                    objects.add(objectId);
13617                    all = false;
13618                } catch (RuntimeException e) {
13619                    // Not an integer; just do string match.
13620                    if (strings == null) {
13621                        strings = new ArrayList<String>();
13622                    }
13623                    strings.add(name);
13624                    all = false;
13625                }
13626            }
13627        }
13628
13629        int build(String[] args, int opti) {
13630            for (; opti<args.length; opti++) {
13631                String name = args[opti];
13632                if ("--".equals(name)) {
13633                    return opti+1;
13634                }
13635                build(name);
13636            }
13637            return opti;
13638        }
13639
13640        boolean match(Object object, ComponentName comp) {
13641            if (all) {
13642                return true;
13643            }
13644            if (components != null) {
13645                for (int i=0; i<components.size(); i++) {
13646                    if (components.get(i).equals(comp)) {
13647                        return true;
13648                    }
13649                }
13650            }
13651            if (objects != null) {
13652                for (int i=0; i<objects.size(); i++) {
13653                    if (System.identityHashCode(object) == objects.get(i)) {
13654                        return true;
13655                    }
13656                }
13657            }
13658            if (strings != null) {
13659                String flat = comp.flattenToString();
13660                for (int i=0; i<strings.size(); i++) {
13661                    if (flat.contains(strings.get(i))) {
13662                        return true;
13663                    }
13664                }
13665            }
13666            return false;
13667        }
13668    }
13669
13670    /**
13671     * There are three things that cmd can be:
13672     *  - a flattened component name that matches an existing activity
13673     *  - the cmd arg isn't the flattened component name of an existing activity:
13674     *    dump all activity whose component contains the cmd as a substring
13675     *  - A hex number of the ActivityRecord object instance.
13676     */
13677    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13678            int opti, boolean dumpAll) {
13679        ArrayList<ActivityRecord> activities;
13680
13681        synchronized (this) {
13682            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13683        }
13684
13685        if (activities.size() <= 0) {
13686            return false;
13687        }
13688
13689        String[] newArgs = new String[args.length - opti];
13690        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13691
13692        TaskRecord lastTask = null;
13693        boolean needSep = false;
13694        for (int i=activities.size()-1; i>=0; i--) {
13695            ActivityRecord r = activities.get(i);
13696            if (needSep) {
13697                pw.println();
13698            }
13699            needSep = true;
13700            synchronized (this) {
13701                if (lastTask != r.task) {
13702                    lastTask = r.task;
13703                    pw.print("TASK "); pw.print(lastTask.affinity);
13704                            pw.print(" id="); pw.println(lastTask.taskId);
13705                    if (dumpAll) {
13706                        lastTask.dump(pw, "  ");
13707                    }
13708                }
13709            }
13710            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13711        }
13712        return true;
13713    }
13714
13715    /**
13716     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13717     * there is a thread associated with the activity.
13718     */
13719    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13720            final ActivityRecord r, String[] args, boolean dumpAll) {
13721        String innerPrefix = prefix + "  ";
13722        synchronized (this) {
13723            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13724                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13725                    pw.print(" pid=");
13726                    if (r.app != null) pw.println(r.app.pid);
13727                    else pw.println("(not running)");
13728            if (dumpAll) {
13729                r.dump(pw, innerPrefix);
13730            }
13731        }
13732        if (r.app != null && r.app.thread != null) {
13733            // flush anything that is already in the PrintWriter since the thread is going
13734            // to write to the file descriptor directly
13735            pw.flush();
13736            try {
13737                TransferPipe tp = new TransferPipe();
13738                try {
13739                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13740                            r.appToken, innerPrefix, args);
13741                    tp.go(fd);
13742                } finally {
13743                    tp.kill();
13744                }
13745            } catch (IOException e) {
13746                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13747            } catch (RemoteException e) {
13748                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13749            }
13750        }
13751    }
13752
13753    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13754            int opti, boolean dumpAll, String dumpPackage) {
13755        boolean needSep = false;
13756        boolean onlyHistory = false;
13757        boolean printedAnything = false;
13758
13759        if ("history".equals(dumpPackage)) {
13760            if (opti < args.length && "-s".equals(args[opti])) {
13761                dumpAll = false;
13762            }
13763            onlyHistory = true;
13764            dumpPackage = null;
13765        }
13766
13767        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13768        if (!onlyHistory && dumpAll) {
13769            if (mRegisteredReceivers.size() > 0) {
13770                boolean printed = false;
13771                Iterator it = mRegisteredReceivers.values().iterator();
13772                while (it.hasNext()) {
13773                    ReceiverList r = (ReceiverList)it.next();
13774                    if (dumpPackage != null && (r.app == null ||
13775                            !dumpPackage.equals(r.app.info.packageName))) {
13776                        continue;
13777                    }
13778                    if (!printed) {
13779                        pw.println("  Registered Receivers:");
13780                        needSep = true;
13781                        printed = true;
13782                        printedAnything = true;
13783                    }
13784                    pw.print("  * "); pw.println(r);
13785                    r.dump(pw, "    ");
13786                }
13787            }
13788
13789            if (mReceiverResolver.dump(pw, needSep ?
13790                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13791                    "    ", dumpPackage, false, false)) {
13792                needSep = true;
13793                printedAnything = true;
13794            }
13795        }
13796
13797        for (BroadcastQueue q : mBroadcastQueues) {
13798            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13799            printedAnything |= needSep;
13800        }
13801
13802        needSep = true;
13803
13804        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13805            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13806                if (needSep) {
13807                    pw.println();
13808                }
13809                needSep = true;
13810                printedAnything = true;
13811                pw.print("  Sticky broadcasts for user ");
13812                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13813                StringBuilder sb = new StringBuilder(128);
13814                for (Map.Entry<String, ArrayList<Intent>> ent
13815                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13816                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13817                    if (dumpAll) {
13818                        pw.println(":");
13819                        ArrayList<Intent> intents = ent.getValue();
13820                        final int N = intents.size();
13821                        for (int i=0; i<N; i++) {
13822                            sb.setLength(0);
13823                            sb.append("    Intent: ");
13824                            intents.get(i).toShortString(sb, false, true, false, false);
13825                            pw.println(sb.toString());
13826                            Bundle bundle = intents.get(i).getExtras();
13827                            if (bundle != null) {
13828                                pw.print("      ");
13829                                pw.println(bundle.toString());
13830                            }
13831                        }
13832                    } else {
13833                        pw.println("");
13834                    }
13835                }
13836            }
13837        }
13838
13839        if (!onlyHistory && dumpAll) {
13840            pw.println();
13841            for (BroadcastQueue queue : mBroadcastQueues) {
13842                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13843                        + queue.mBroadcastsScheduled);
13844            }
13845            pw.println("  mHandler:");
13846            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13847            needSep = true;
13848            printedAnything = true;
13849        }
13850
13851        if (!printedAnything) {
13852            pw.println("  (nothing)");
13853        }
13854    }
13855
13856    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13857            int opti, boolean dumpAll, String dumpPackage) {
13858        boolean needSep;
13859        boolean printedAnything = false;
13860
13861        ItemMatcher matcher = new ItemMatcher();
13862        matcher.build(args, opti);
13863
13864        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13865
13866        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13867        printedAnything |= needSep;
13868
13869        if (mLaunchingProviders.size() > 0) {
13870            boolean printed = false;
13871            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13872                ContentProviderRecord r = mLaunchingProviders.get(i);
13873                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13874                    continue;
13875                }
13876                if (!printed) {
13877                    if (needSep) pw.println();
13878                    needSep = true;
13879                    pw.println("  Launching content providers:");
13880                    printed = true;
13881                    printedAnything = true;
13882                }
13883                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13884                        pw.println(r);
13885            }
13886        }
13887
13888        if (mGrantedUriPermissions.size() > 0) {
13889            boolean printed = false;
13890            int dumpUid = -2;
13891            if (dumpPackage != null) {
13892                try {
13893                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13894                } catch (NameNotFoundException e) {
13895                    dumpUid = -1;
13896                }
13897            }
13898            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13899                int uid = mGrantedUriPermissions.keyAt(i);
13900                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13901                    continue;
13902                }
13903                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13904                if (!printed) {
13905                    if (needSep) pw.println();
13906                    needSep = true;
13907                    pw.println("  Granted Uri Permissions:");
13908                    printed = true;
13909                    printedAnything = true;
13910                }
13911                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13912                for (UriPermission perm : perms.values()) {
13913                    pw.print("    "); pw.println(perm);
13914                    if (dumpAll) {
13915                        perm.dump(pw, "      ");
13916                    }
13917                }
13918            }
13919        }
13920
13921        if (!printedAnything) {
13922            pw.println("  (nothing)");
13923        }
13924    }
13925
13926    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13927            int opti, boolean dumpAll, String dumpPackage) {
13928        boolean printed = false;
13929
13930        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13931
13932        if (mIntentSenderRecords.size() > 0) {
13933            Iterator<WeakReference<PendingIntentRecord>> it
13934                    = mIntentSenderRecords.values().iterator();
13935            while (it.hasNext()) {
13936                WeakReference<PendingIntentRecord> ref = it.next();
13937                PendingIntentRecord rec = ref != null ? ref.get(): null;
13938                if (dumpPackage != null && (rec == null
13939                        || !dumpPackage.equals(rec.key.packageName))) {
13940                    continue;
13941                }
13942                printed = true;
13943                if (rec != null) {
13944                    pw.print("  * "); pw.println(rec);
13945                    if (dumpAll) {
13946                        rec.dump(pw, "    ");
13947                    }
13948                } else {
13949                    pw.print("  * "); pw.println(ref);
13950                }
13951            }
13952        }
13953
13954        if (!printed) {
13955            pw.println("  (nothing)");
13956        }
13957    }
13958
13959    private static final int dumpProcessList(PrintWriter pw,
13960            ActivityManagerService service, List list,
13961            String prefix, String normalLabel, String persistentLabel,
13962            String dumpPackage) {
13963        int numPers = 0;
13964        final int N = list.size()-1;
13965        for (int i=N; i>=0; i--) {
13966            ProcessRecord r = (ProcessRecord)list.get(i);
13967            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13968                continue;
13969            }
13970            pw.println(String.format("%s%s #%2d: %s",
13971                    prefix, (r.persistent ? persistentLabel : normalLabel),
13972                    i, r.toString()));
13973            if (r.persistent) {
13974                numPers++;
13975            }
13976        }
13977        return numPers;
13978    }
13979
13980    private static final boolean dumpProcessOomList(PrintWriter pw,
13981            ActivityManagerService service, List<ProcessRecord> origList,
13982            String prefix, String normalLabel, String persistentLabel,
13983            boolean inclDetails, String dumpPackage) {
13984
13985        ArrayList<Pair<ProcessRecord, Integer>> list
13986                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13987        for (int i=0; i<origList.size(); i++) {
13988            ProcessRecord r = origList.get(i);
13989            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13990                continue;
13991            }
13992            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13993        }
13994
13995        if (list.size() <= 0) {
13996            return false;
13997        }
13998
13999        Comparator<Pair<ProcessRecord, Integer>> comparator
14000                = new Comparator<Pair<ProcessRecord, Integer>>() {
14001            @Override
14002            public int compare(Pair<ProcessRecord, Integer> object1,
14003                    Pair<ProcessRecord, Integer> object2) {
14004                if (object1.first.setAdj != object2.first.setAdj) {
14005                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14006                }
14007                if (object1.second.intValue() != object2.second.intValue()) {
14008                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14009                }
14010                return 0;
14011            }
14012        };
14013
14014        Collections.sort(list, comparator);
14015
14016        final long curRealtime = SystemClock.elapsedRealtime();
14017        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14018        final long curUptime = SystemClock.uptimeMillis();
14019        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14020
14021        for (int i=list.size()-1; i>=0; i--) {
14022            ProcessRecord r = list.get(i).first;
14023            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14024            char schedGroup;
14025            switch (r.setSchedGroup) {
14026                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
14027                    schedGroup = 'B';
14028                    break;
14029                case Process.THREAD_GROUP_DEFAULT:
14030                    schedGroup = 'F';
14031                    break;
14032                default:
14033                    schedGroup = '?';
14034                    break;
14035            }
14036            char foreground;
14037            if (r.foregroundActivities) {
14038                foreground = 'A';
14039            } else if (r.foregroundServices) {
14040                foreground = 'S';
14041            } else {
14042                foreground = ' ';
14043            }
14044            String procState = ProcessList.makeProcStateString(r.curProcState);
14045            pw.print(prefix);
14046            pw.print(r.persistent ? persistentLabel : normalLabel);
14047            pw.print(" #");
14048            int num = (origList.size()-1)-list.get(i).second;
14049            if (num < 10) pw.print(' ');
14050            pw.print(num);
14051            pw.print(": ");
14052            pw.print(oomAdj);
14053            pw.print(' ');
14054            pw.print(schedGroup);
14055            pw.print('/');
14056            pw.print(foreground);
14057            pw.print('/');
14058            pw.print(procState);
14059            pw.print(" trm:");
14060            if (r.trimMemoryLevel < 10) pw.print(' ');
14061            pw.print(r.trimMemoryLevel);
14062            pw.print(' ');
14063            pw.print(r.toShortString());
14064            pw.print(" (");
14065            pw.print(r.adjType);
14066            pw.println(')');
14067            if (r.adjSource != null || r.adjTarget != null) {
14068                pw.print(prefix);
14069                pw.print("    ");
14070                if (r.adjTarget instanceof ComponentName) {
14071                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14072                } else if (r.adjTarget != null) {
14073                    pw.print(r.adjTarget.toString());
14074                } else {
14075                    pw.print("{null}");
14076                }
14077                pw.print("<=");
14078                if (r.adjSource instanceof ProcessRecord) {
14079                    pw.print("Proc{");
14080                    pw.print(((ProcessRecord)r.adjSource).toShortString());
14081                    pw.println("}");
14082                } else if (r.adjSource != null) {
14083                    pw.println(r.adjSource.toString());
14084                } else {
14085                    pw.println("{null}");
14086                }
14087            }
14088            if (inclDetails) {
14089                pw.print(prefix);
14090                pw.print("    ");
14091                pw.print("oom: max="); pw.print(r.maxAdj);
14092                pw.print(" curRaw="); pw.print(r.curRawAdj);
14093                pw.print(" setRaw="); pw.print(r.setRawAdj);
14094                pw.print(" cur="); pw.print(r.curAdj);
14095                pw.print(" set="); pw.println(r.setAdj);
14096                pw.print(prefix);
14097                pw.print("    ");
14098                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14099                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14100                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14101                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14102                pw.println();
14103                pw.print(prefix);
14104                pw.print("    ");
14105                pw.print("cached="); pw.print(r.cached);
14106                pw.print(" empty="); pw.print(r.empty);
14107                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14108
14109                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14110                    if (r.lastWakeTime != 0) {
14111                        long wtime;
14112                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14113                        synchronized (stats) {
14114                            wtime = stats.getProcessWakeTime(r.info.uid,
14115                                    r.pid, curRealtime);
14116                        }
14117                        long timeUsed = wtime - r.lastWakeTime;
14118                        pw.print(prefix);
14119                        pw.print("    ");
14120                        pw.print("keep awake over ");
14121                        TimeUtils.formatDuration(realtimeSince, pw);
14122                        pw.print(" used ");
14123                        TimeUtils.formatDuration(timeUsed, pw);
14124                        pw.print(" (");
14125                        pw.print((timeUsed*100)/realtimeSince);
14126                        pw.println("%)");
14127                    }
14128                    if (r.lastCpuTime != 0) {
14129                        long timeUsed = r.curCpuTime - r.lastCpuTime;
14130                        pw.print(prefix);
14131                        pw.print("    ");
14132                        pw.print("run cpu over ");
14133                        TimeUtils.formatDuration(uptimeSince, pw);
14134                        pw.print(" used ");
14135                        TimeUtils.formatDuration(timeUsed, pw);
14136                        pw.print(" (");
14137                        pw.print((timeUsed*100)/uptimeSince);
14138                        pw.println("%)");
14139                    }
14140                }
14141            }
14142        }
14143        return true;
14144    }
14145
14146    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14147            String[] args) {
14148        ArrayList<ProcessRecord> procs;
14149        synchronized (this) {
14150            if (args != null && args.length > start
14151                    && args[start].charAt(0) != '-') {
14152                procs = new ArrayList<ProcessRecord>();
14153                int pid = -1;
14154                try {
14155                    pid = Integer.parseInt(args[start]);
14156                } catch (NumberFormatException e) {
14157                }
14158                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14159                    ProcessRecord proc = mLruProcesses.get(i);
14160                    if (proc.pid == pid) {
14161                        procs.add(proc);
14162                    } else if (allPkgs && proc.pkgList != null
14163                            && proc.pkgList.containsKey(args[start])) {
14164                        procs.add(proc);
14165                    } else if (proc.processName.equals(args[start])) {
14166                        procs.add(proc);
14167                    }
14168                }
14169                if (procs.size() <= 0) {
14170                    return null;
14171                }
14172            } else {
14173                procs = new ArrayList<ProcessRecord>(mLruProcesses);
14174            }
14175        }
14176        return procs;
14177    }
14178
14179    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
14180            PrintWriter pw, String[] args) {
14181        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14182        if (procs == null) {
14183            pw.println("No process found for: " + args[0]);
14184            return;
14185        }
14186
14187        long uptime = SystemClock.uptimeMillis();
14188        long realtime = SystemClock.elapsedRealtime();
14189        pw.println("Applications Graphics Acceleration Info:");
14190        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14191
14192        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14193            ProcessRecord r = procs.get(i);
14194            if (r.thread != null) {
14195                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
14196                pw.flush();
14197                try {
14198                    TransferPipe tp = new TransferPipe();
14199                    try {
14200                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
14201                        tp.go(fd);
14202                    } finally {
14203                        tp.kill();
14204                    }
14205                } catch (IOException e) {
14206                    pw.println("Failure while dumping the app: " + r);
14207                    pw.flush();
14208                } catch (RemoteException e) {
14209                    pw.println("Got a RemoteException while dumping the app " + r);
14210                    pw.flush();
14211                }
14212            }
14213        }
14214    }
14215
14216    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
14217        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14218        if (procs == null) {
14219            pw.println("No process found for: " + args[0]);
14220            return;
14221        }
14222
14223        pw.println("Applications Database Info:");
14224
14225        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14226            ProcessRecord r = procs.get(i);
14227            if (r.thread != null) {
14228                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
14229                pw.flush();
14230                try {
14231                    TransferPipe tp = new TransferPipe();
14232                    try {
14233                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
14234                        tp.go(fd);
14235                    } finally {
14236                        tp.kill();
14237                    }
14238                } catch (IOException e) {
14239                    pw.println("Failure while dumping the app: " + r);
14240                    pw.flush();
14241                } catch (RemoteException e) {
14242                    pw.println("Got a RemoteException while dumping the app " + r);
14243                    pw.flush();
14244                }
14245            }
14246        }
14247    }
14248
14249    final static class MemItem {
14250        final boolean isProc;
14251        final String label;
14252        final String shortLabel;
14253        final long pss;
14254        final int id;
14255        final boolean hasActivities;
14256        ArrayList<MemItem> subitems;
14257
14258        public MemItem(String _label, String _shortLabel, long _pss, int _id,
14259                boolean _hasActivities) {
14260            isProc = true;
14261            label = _label;
14262            shortLabel = _shortLabel;
14263            pss = _pss;
14264            id = _id;
14265            hasActivities = _hasActivities;
14266        }
14267
14268        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
14269            isProc = false;
14270            label = _label;
14271            shortLabel = _shortLabel;
14272            pss = _pss;
14273            id = _id;
14274            hasActivities = false;
14275        }
14276    }
14277
14278    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
14279            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
14280        if (sort && !isCompact) {
14281            Collections.sort(items, new Comparator<MemItem>() {
14282                @Override
14283                public int compare(MemItem lhs, MemItem rhs) {
14284                    if (lhs.pss < rhs.pss) {
14285                        return 1;
14286                    } else if (lhs.pss > rhs.pss) {
14287                        return -1;
14288                    }
14289                    return 0;
14290                }
14291            });
14292        }
14293
14294        for (int i=0; i<items.size(); i++) {
14295            MemItem mi = items.get(i);
14296            if (!isCompact) {
14297                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
14298            } else if (mi.isProc) {
14299                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
14300                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
14301                pw.println(mi.hasActivities ? ",a" : ",e");
14302            } else {
14303                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
14304                pw.println(mi.pss);
14305            }
14306            if (mi.subitems != null) {
14307                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
14308                        true, isCompact);
14309            }
14310        }
14311    }
14312
14313    // These are in KB.
14314    static final long[] DUMP_MEM_BUCKETS = new long[] {
14315        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
14316        120*1024, 160*1024, 200*1024,
14317        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
14318        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
14319    };
14320
14321    static final void appendMemBucket(StringBuilder out, long memKB, String label,
14322            boolean stackLike) {
14323        int start = label.lastIndexOf('.');
14324        if (start >= 0) start++;
14325        else start = 0;
14326        int end = label.length();
14327        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
14328            if (DUMP_MEM_BUCKETS[i] >= memKB) {
14329                long bucket = DUMP_MEM_BUCKETS[i]/1024;
14330                out.append(bucket);
14331                out.append(stackLike ? "MB." : "MB ");
14332                out.append(label, start, end);
14333                return;
14334            }
14335        }
14336        out.append(memKB/1024);
14337        out.append(stackLike ? "MB." : "MB ");
14338        out.append(label, start, end);
14339    }
14340
14341    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
14342            ProcessList.NATIVE_ADJ,
14343            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
14344            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
14345            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
14346            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
14347            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
14348            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
14349    };
14350    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
14351            "Native",
14352            "System", "Persistent", "Persistent Service", "Foreground",
14353            "Visible", "Perceptible",
14354            "Heavy Weight", "Backup",
14355            "A Services", "Home",
14356            "Previous", "B Services", "Cached"
14357    };
14358    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
14359            "native",
14360            "sys", "pers", "persvc", "fore",
14361            "vis", "percept",
14362            "heavy", "backup",
14363            "servicea", "home",
14364            "prev", "serviceb", "cached"
14365    };
14366
14367    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
14368            long realtime, boolean isCheckinRequest, boolean isCompact) {
14369        if (isCheckinRequest || isCompact) {
14370            // short checkin version
14371            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
14372        } else {
14373            pw.println("Applications Memory Usage (kB):");
14374            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14375        }
14376    }
14377
14378    private static final int KSM_SHARED = 0;
14379    private static final int KSM_SHARING = 1;
14380    private static final int KSM_UNSHARED = 2;
14381    private static final int KSM_VOLATILE = 3;
14382
14383    private final long[] getKsmInfo() {
14384        long[] longOut = new long[4];
14385        final int[] SINGLE_LONG_FORMAT = new int[] {
14386            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14387        };
14388        long[] longTmp = new long[1];
14389        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14390                SINGLE_LONG_FORMAT, null, longTmp, null);
14391        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14392        longTmp[0] = 0;
14393        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14394                SINGLE_LONG_FORMAT, null, longTmp, null);
14395        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14396        longTmp[0] = 0;
14397        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14398                SINGLE_LONG_FORMAT, null, longTmp, null);
14399        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14400        longTmp[0] = 0;
14401        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14402                SINGLE_LONG_FORMAT, null, longTmp, null);
14403        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14404        return longOut;
14405    }
14406
14407    final void dumpApplicationMemoryUsage(FileDescriptor fd,
14408            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
14409        boolean dumpDetails = false;
14410        boolean dumpFullDetails = false;
14411        boolean dumpDalvik = false;
14412        boolean dumpSummaryOnly = false;
14413        boolean oomOnly = false;
14414        boolean isCompact = false;
14415        boolean localOnly = false;
14416        boolean packages = false;
14417
14418        int opti = 0;
14419        while (opti < args.length) {
14420            String opt = args[opti];
14421            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14422                break;
14423            }
14424            opti++;
14425            if ("-a".equals(opt)) {
14426                dumpDetails = true;
14427                dumpFullDetails = true;
14428                dumpDalvik = true;
14429            } else if ("-d".equals(opt)) {
14430                dumpDalvik = true;
14431            } else if ("-c".equals(opt)) {
14432                isCompact = true;
14433            } else if ("-s".equals(opt)) {
14434                dumpDetails = true;
14435                dumpSummaryOnly = true;
14436            } else if ("--oom".equals(opt)) {
14437                oomOnly = true;
14438            } else if ("--local".equals(opt)) {
14439                localOnly = true;
14440            } else if ("--package".equals(opt)) {
14441                packages = true;
14442            } else if ("-h".equals(opt)) {
14443                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
14444                pw.println("  -a: include all available information for each process.");
14445                pw.println("  -d: include dalvik details.");
14446                pw.println("  -c: dump in a compact machine-parseable representation.");
14447                pw.println("  -s: dump only summary of application memory usage.");
14448                pw.println("  --oom: only show processes organized by oom adj.");
14449                pw.println("  --local: only collect details locally, don't call process.");
14450                pw.println("  --package: interpret process arg as package, dumping all");
14451                pw.println("             processes that have loaded that package.");
14452                pw.println("If [process] is specified it can be the name or ");
14453                pw.println("pid of a specific process to dump.");
14454                return;
14455            } else {
14456                pw.println("Unknown argument: " + opt + "; use -h for help");
14457            }
14458        }
14459
14460        final boolean isCheckinRequest = scanArgs(args, "--checkin");
14461        long uptime = SystemClock.uptimeMillis();
14462        long realtime = SystemClock.elapsedRealtime();
14463        final long[] tmpLong = new long[1];
14464
14465        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
14466        if (procs == null) {
14467            // No Java processes.  Maybe they want to print a native process.
14468            if (args != null && args.length > opti
14469                    && args[opti].charAt(0) != '-') {
14470                ArrayList<ProcessCpuTracker.Stats> nativeProcs
14471                        = new ArrayList<ProcessCpuTracker.Stats>();
14472                updateCpuStatsNow();
14473                int findPid = -1;
14474                try {
14475                    findPid = Integer.parseInt(args[opti]);
14476                } catch (NumberFormatException e) {
14477                }
14478                synchronized (mProcessCpuTracker) {
14479                    final int N = mProcessCpuTracker.countStats();
14480                    for (int i=0; i<N; i++) {
14481                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14482                        if (st.pid == findPid || (st.baseName != null
14483                                && st.baseName.equals(args[opti]))) {
14484                            nativeProcs.add(st);
14485                        }
14486                    }
14487                }
14488                if (nativeProcs.size() > 0) {
14489                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14490                            isCompact);
14491                    Debug.MemoryInfo mi = null;
14492                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14493                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14494                        final int pid = r.pid;
14495                        if (!isCheckinRequest && dumpDetails) {
14496                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14497                        }
14498                        if (mi == null) {
14499                            mi = new Debug.MemoryInfo();
14500                        }
14501                        if (dumpDetails || (!brief && !oomOnly)) {
14502                            Debug.getMemoryInfo(pid, mi);
14503                        } else {
14504                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14505                            mi.dalvikPrivateDirty = (int)tmpLong[0];
14506                        }
14507                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14508                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14509                        if (isCheckinRequest) {
14510                            pw.println();
14511                        }
14512                    }
14513                    return;
14514                }
14515            }
14516            pw.println("No process found for: " + args[opti]);
14517            return;
14518        }
14519
14520        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14521            dumpDetails = true;
14522        }
14523
14524        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14525
14526        String[] innerArgs = new String[args.length-opti];
14527        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14528
14529        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14530        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14531        long nativePss = 0;
14532        long dalvikPss = 0;
14533        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
14534                EmptyArray.LONG;
14535        long otherPss = 0;
14536        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14537
14538        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14539        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14540                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14541
14542        long totalPss = 0;
14543        long cachedPss = 0;
14544
14545        Debug.MemoryInfo mi = null;
14546        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14547            final ProcessRecord r = procs.get(i);
14548            final IApplicationThread thread;
14549            final int pid;
14550            final int oomAdj;
14551            final boolean hasActivities;
14552            synchronized (this) {
14553                thread = r.thread;
14554                pid = r.pid;
14555                oomAdj = r.getSetAdjWithServices();
14556                hasActivities = r.activities.size() > 0;
14557            }
14558            if (thread != null) {
14559                if (!isCheckinRequest && dumpDetails) {
14560                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14561                }
14562                if (mi == null) {
14563                    mi = new Debug.MemoryInfo();
14564                }
14565                if (dumpDetails || (!brief && !oomOnly)) {
14566                    Debug.getMemoryInfo(pid, mi);
14567                } else {
14568                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14569                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14570                }
14571                if (dumpDetails) {
14572                    if (localOnly) {
14573                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14574                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
14575                        if (isCheckinRequest) {
14576                            pw.println();
14577                        }
14578                    } else {
14579                        try {
14580                            pw.flush();
14581                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14582                                    dumpDalvik, dumpSummaryOnly, innerArgs);
14583                        } catch (RemoteException e) {
14584                            if (!isCheckinRequest) {
14585                                pw.println("Got RemoteException!");
14586                                pw.flush();
14587                            }
14588                        }
14589                    }
14590                }
14591
14592                final long myTotalPss = mi.getTotalPss();
14593                final long myTotalUss = mi.getTotalUss();
14594
14595                synchronized (this) {
14596                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14597                        // Record this for posterity if the process has been stable.
14598                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14599                    }
14600                }
14601
14602                if (!isCheckinRequest && mi != null) {
14603                    totalPss += myTotalPss;
14604                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14605                            (hasActivities ? " / activities)" : ")"),
14606                            r.processName, myTotalPss, pid, hasActivities);
14607                    procMems.add(pssItem);
14608                    procMemsMap.put(pid, pssItem);
14609
14610                    nativePss += mi.nativePss;
14611                    dalvikPss += mi.dalvikPss;
14612                    for (int j=0; j<dalvikSubitemPss.length; j++) {
14613                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
14614                    }
14615                    otherPss += mi.otherPss;
14616                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14617                        long mem = mi.getOtherPss(j);
14618                        miscPss[j] += mem;
14619                        otherPss -= mem;
14620                    }
14621
14622                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14623                        cachedPss += myTotalPss;
14624                    }
14625
14626                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14627                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14628                                || oomIndex == (oomPss.length-1)) {
14629                            oomPss[oomIndex] += myTotalPss;
14630                            if (oomProcs[oomIndex] == null) {
14631                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14632                            }
14633                            oomProcs[oomIndex].add(pssItem);
14634                            break;
14635                        }
14636                    }
14637                }
14638            }
14639        }
14640
14641        long nativeProcTotalPss = 0;
14642
14643        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14644            // If we are showing aggregations, also look for native processes to
14645            // include so that our aggregations are more accurate.
14646            updateCpuStatsNow();
14647            mi = null;
14648            synchronized (mProcessCpuTracker) {
14649                final int N = mProcessCpuTracker.countStats();
14650                for (int i=0; i<N; i++) {
14651                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14652                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14653                        if (mi == null) {
14654                            mi = new Debug.MemoryInfo();
14655                        }
14656                        if (!brief && !oomOnly) {
14657                            Debug.getMemoryInfo(st.pid, mi);
14658                        } else {
14659                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14660                            mi.nativePrivateDirty = (int)tmpLong[0];
14661                        }
14662
14663                        final long myTotalPss = mi.getTotalPss();
14664                        totalPss += myTotalPss;
14665                        nativeProcTotalPss += myTotalPss;
14666
14667                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14668                                st.name, myTotalPss, st.pid, false);
14669                        procMems.add(pssItem);
14670
14671                        nativePss += mi.nativePss;
14672                        dalvikPss += mi.dalvikPss;
14673                        for (int j=0; j<dalvikSubitemPss.length; j++) {
14674                            dalvikSubitemPss[j] += mi.getOtherPss(
14675                                    Debug.MemoryInfo.NUM_OTHER_STATS + j);
14676                        }
14677                        otherPss += mi.otherPss;
14678                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14679                            long mem = mi.getOtherPss(j);
14680                            miscPss[j] += mem;
14681                            otherPss -= mem;
14682                        }
14683                        oomPss[0] += myTotalPss;
14684                        if (oomProcs[0] == null) {
14685                            oomProcs[0] = new ArrayList<MemItem>();
14686                        }
14687                        oomProcs[0].add(pssItem);
14688                    }
14689                }
14690            }
14691
14692            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14693
14694            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14695            final MemItem dalvikItem = new MemItem("Dalvik", "Dalvik", dalvikPss, -2);
14696            if (dalvikSubitemPss.length > 0) {
14697                dalvikItem.subitems = new ArrayList<MemItem>();
14698                for (int j=0; j<dalvikSubitemPss.length; j++) {
14699                    final String name = Debug.MemoryInfo.getOtherLabel(
14700                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
14701                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j], j));
14702                }
14703            }
14704            catMems.add(dalvikItem);
14705            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14706            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14707                String label = Debug.MemoryInfo.getOtherLabel(j);
14708                catMems.add(new MemItem(label, label, miscPss[j], j));
14709            }
14710
14711            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14712            for (int j=0; j<oomPss.length; j++) {
14713                if (oomPss[j] != 0) {
14714                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14715                            : DUMP_MEM_OOM_LABEL[j];
14716                    MemItem item = new MemItem(label, label, oomPss[j],
14717                            DUMP_MEM_OOM_ADJ[j]);
14718                    item.subitems = oomProcs[j];
14719                    oomMems.add(item);
14720                }
14721            }
14722
14723            if (!brief && !oomOnly && !isCompact) {
14724                pw.println();
14725                pw.println("Total PSS by process:");
14726                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14727                pw.println();
14728            }
14729            if (!isCompact) {
14730                pw.println("Total PSS by OOM adjustment:");
14731            }
14732            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14733            if (!brief && !oomOnly) {
14734                PrintWriter out = categoryPw != null ? categoryPw : pw;
14735                if (!isCompact) {
14736                    out.println();
14737                    out.println("Total PSS by category:");
14738                }
14739                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14740            }
14741            if (!isCompact) {
14742                pw.println();
14743            }
14744            MemInfoReader memInfo = new MemInfoReader();
14745            memInfo.readMemInfo();
14746            if (nativeProcTotalPss > 0) {
14747                synchronized (this) {
14748                    final long cachedKb = memInfo.getCachedSizeKb();
14749                    final long freeKb = memInfo.getFreeSizeKb();
14750                    final long zramKb = memInfo.getZramTotalSizeKb();
14751                    final long kernelKb = memInfo.getKernelUsedSizeKb();
14752                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
14753                            kernelKb*1024, nativeProcTotalPss*1024);
14754                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
14755                            nativeProcTotalPss);
14756                }
14757            }
14758            if (!brief) {
14759                if (!isCompact) {
14760                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14761                    pw.print(" kB (status ");
14762                    switch (mLastMemoryLevel) {
14763                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14764                            pw.println("normal)");
14765                            break;
14766                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14767                            pw.println("moderate)");
14768                            break;
14769                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14770                            pw.println("low)");
14771                            break;
14772                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14773                            pw.println("critical)");
14774                            break;
14775                        default:
14776                            pw.print(mLastMemoryLevel);
14777                            pw.println(")");
14778                            break;
14779                    }
14780                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14781                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14782                            pw.print(cachedPss); pw.print(" cached pss + ");
14783                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14784                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14785                } else {
14786                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14787                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14788                            + memInfo.getFreeSizeKb()); pw.print(",");
14789                    pw.println(totalPss - cachedPss);
14790                }
14791            }
14792            if (!isCompact) {
14793                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14794                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14795                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14796                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14797                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14798                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14799                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14800            }
14801            if (!brief) {
14802                if (memInfo.getZramTotalSizeKb() != 0) {
14803                    if (!isCompact) {
14804                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14805                                pw.print(" kB physical used for ");
14806                                pw.print(memInfo.getSwapTotalSizeKb()
14807                                        - memInfo.getSwapFreeSizeKb());
14808                                pw.print(" kB in swap (");
14809                                pw.print(memInfo.getSwapTotalSizeKb());
14810                                pw.println(" kB total swap)");
14811                    } else {
14812                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14813                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14814                                pw.println(memInfo.getSwapFreeSizeKb());
14815                    }
14816                }
14817                final long[] ksm = getKsmInfo();
14818                if (!isCompact) {
14819                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14820                            || ksm[KSM_VOLATILE] != 0) {
14821                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14822                                pw.print(" kB saved from shared ");
14823                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14824                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14825                                pw.print(" kB unshared; ");
14826                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14827                    }
14828                    pw.print("   Tuning: ");
14829                    pw.print(ActivityManager.staticGetMemoryClass());
14830                    pw.print(" (large ");
14831                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14832                    pw.print("), oom ");
14833                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14834                    pw.print(" kB");
14835                    pw.print(", restore limit ");
14836                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14837                    pw.print(" kB");
14838                    if (ActivityManager.isLowRamDeviceStatic()) {
14839                        pw.print(" (low-ram)");
14840                    }
14841                    if (ActivityManager.isHighEndGfx()) {
14842                        pw.print(" (high-end-gfx)");
14843                    }
14844                    pw.println();
14845                } else {
14846                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14847                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14848                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14849                    pw.print("tuning,");
14850                    pw.print(ActivityManager.staticGetMemoryClass());
14851                    pw.print(',');
14852                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14853                    pw.print(',');
14854                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14855                    if (ActivityManager.isLowRamDeviceStatic()) {
14856                        pw.print(",low-ram");
14857                    }
14858                    if (ActivityManager.isHighEndGfx()) {
14859                        pw.print(",high-end-gfx");
14860                    }
14861                    pw.println();
14862                }
14863            }
14864        }
14865    }
14866
14867    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14868            long memtrack, String name) {
14869        sb.append("  ");
14870        sb.append(ProcessList.makeOomAdjString(oomAdj));
14871        sb.append(' ');
14872        sb.append(ProcessList.makeProcStateString(procState));
14873        sb.append(' ');
14874        ProcessList.appendRamKb(sb, pss);
14875        sb.append(" kB: ");
14876        sb.append(name);
14877        if (memtrack > 0) {
14878            sb.append(" (");
14879            sb.append(memtrack);
14880            sb.append(" kB memtrack)");
14881        }
14882    }
14883
14884    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14885        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
14886        sb.append(" (pid ");
14887        sb.append(mi.pid);
14888        sb.append(") ");
14889        sb.append(mi.adjType);
14890        sb.append('\n');
14891        if (mi.adjReason != null) {
14892            sb.append("                      ");
14893            sb.append(mi.adjReason);
14894            sb.append('\n');
14895        }
14896    }
14897
14898    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14899        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14900        for (int i=0, N=memInfos.size(); i<N; i++) {
14901            ProcessMemInfo mi = memInfos.get(i);
14902            infoMap.put(mi.pid, mi);
14903        }
14904        updateCpuStatsNow();
14905        long[] memtrackTmp = new long[1];
14906        synchronized (mProcessCpuTracker) {
14907            final int N = mProcessCpuTracker.countStats();
14908            for (int i=0; i<N; i++) {
14909                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14910                if (st.vsize > 0) {
14911                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
14912                    if (pss > 0) {
14913                        if (infoMap.indexOfKey(st.pid) < 0) {
14914                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14915                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14916                            mi.pss = pss;
14917                            mi.memtrack = memtrackTmp[0];
14918                            memInfos.add(mi);
14919                        }
14920                    }
14921                }
14922            }
14923        }
14924
14925        long totalPss = 0;
14926        long totalMemtrack = 0;
14927        for (int i=0, N=memInfos.size(); i<N; i++) {
14928            ProcessMemInfo mi = memInfos.get(i);
14929            if (mi.pss == 0) {
14930                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
14931                mi.memtrack = memtrackTmp[0];
14932            }
14933            totalPss += mi.pss;
14934            totalMemtrack += mi.memtrack;
14935        }
14936        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14937            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14938                if (lhs.oomAdj != rhs.oomAdj) {
14939                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14940                }
14941                if (lhs.pss != rhs.pss) {
14942                    return lhs.pss < rhs.pss ? 1 : -1;
14943                }
14944                return 0;
14945            }
14946        });
14947
14948        StringBuilder tag = new StringBuilder(128);
14949        StringBuilder stack = new StringBuilder(128);
14950        tag.append("Low on memory -- ");
14951        appendMemBucket(tag, totalPss, "total", false);
14952        appendMemBucket(stack, totalPss, "total", true);
14953
14954        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14955        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14956        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14957
14958        boolean firstLine = true;
14959        int lastOomAdj = Integer.MIN_VALUE;
14960        long extraNativeRam = 0;
14961        long extraNativeMemtrack = 0;
14962        long cachedPss = 0;
14963        for (int i=0, N=memInfos.size(); i<N; i++) {
14964            ProcessMemInfo mi = memInfos.get(i);
14965
14966            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14967                cachedPss += mi.pss;
14968            }
14969
14970            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14971                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14972                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14973                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14974                if (lastOomAdj != mi.oomAdj) {
14975                    lastOomAdj = mi.oomAdj;
14976                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14977                        tag.append(" / ");
14978                    }
14979                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14980                        if (firstLine) {
14981                            stack.append(":");
14982                            firstLine = false;
14983                        }
14984                        stack.append("\n\t at ");
14985                    } else {
14986                        stack.append("$");
14987                    }
14988                } else {
14989                    tag.append(" ");
14990                    stack.append("$");
14991                }
14992                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14993                    appendMemBucket(tag, mi.pss, mi.name, false);
14994                }
14995                appendMemBucket(stack, mi.pss, mi.name, true);
14996                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14997                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14998                    stack.append("(");
14999                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15000                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15001                            stack.append(DUMP_MEM_OOM_LABEL[k]);
15002                            stack.append(":");
15003                            stack.append(DUMP_MEM_OOM_ADJ[k]);
15004                        }
15005                    }
15006                    stack.append(")");
15007                }
15008            }
15009
15010            appendMemInfo(fullNativeBuilder, mi);
15011            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15012                // The short form only has native processes that are >= 512K.
15013                if (mi.pss >= 512) {
15014                    appendMemInfo(shortNativeBuilder, mi);
15015                } else {
15016                    extraNativeRam += mi.pss;
15017                    extraNativeMemtrack += mi.memtrack;
15018                }
15019            } else {
15020                // Short form has all other details, but if we have collected RAM
15021                // from smaller native processes let's dump a summary of that.
15022                if (extraNativeRam > 0) {
15023                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15024                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15025                    shortNativeBuilder.append('\n');
15026                    extraNativeRam = 0;
15027                }
15028                appendMemInfo(fullJavaBuilder, mi);
15029            }
15030        }
15031
15032        fullJavaBuilder.append("           ");
15033        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15034        fullJavaBuilder.append(" kB: TOTAL");
15035        if (totalMemtrack > 0) {
15036            fullJavaBuilder.append(" (");
15037            fullJavaBuilder.append(totalMemtrack);
15038            fullJavaBuilder.append(" kB memtrack)");
15039        } else {
15040        }
15041        fullJavaBuilder.append("\n");
15042
15043        MemInfoReader memInfo = new MemInfoReader();
15044        memInfo.readMemInfo();
15045        final long[] infos = memInfo.getRawInfo();
15046
15047        StringBuilder memInfoBuilder = new StringBuilder(1024);
15048        Debug.getMemInfo(infos);
15049        memInfoBuilder.append("  MemInfo: ");
15050        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
15051        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
15052        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
15053        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
15054        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
15055        memInfoBuilder.append("           ");
15056        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
15057        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
15058        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
15059        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
15060        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15061            memInfoBuilder.append("  ZRAM: ");
15062            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
15063            memInfoBuilder.append(" kB RAM, ");
15064            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
15065            memInfoBuilder.append(" kB swap total, ");
15066            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
15067            memInfoBuilder.append(" kB swap free\n");
15068        }
15069        final long[] ksm = getKsmInfo();
15070        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15071                || ksm[KSM_VOLATILE] != 0) {
15072            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
15073            memInfoBuilder.append(" kB saved from shared ");
15074            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
15075            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
15076            memInfoBuilder.append(" kB unshared; ");
15077            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
15078        }
15079        memInfoBuilder.append("  Free RAM: ");
15080        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
15081                + memInfo.getFreeSizeKb());
15082        memInfoBuilder.append(" kB\n");
15083        memInfoBuilder.append("  Used RAM: ");
15084        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
15085        memInfoBuilder.append(" kB\n");
15086        memInfoBuilder.append("  Lost RAM: ");
15087        memInfoBuilder.append(memInfo.getTotalSizeKb()
15088                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15089                - memInfo.getKernelUsedSizeKb());
15090        memInfoBuilder.append(" kB\n");
15091        Slog.i(TAG, "Low on memory:");
15092        Slog.i(TAG, shortNativeBuilder.toString());
15093        Slog.i(TAG, fullJavaBuilder.toString());
15094        Slog.i(TAG, memInfoBuilder.toString());
15095
15096        StringBuilder dropBuilder = new StringBuilder(1024);
15097        /*
15098        StringWriter oomSw = new StringWriter();
15099        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
15100        StringWriter catSw = new StringWriter();
15101        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15102        String[] emptyArgs = new String[] { };
15103        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
15104        oomPw.flush();
15105        String oomString = oomSw.toString();
15106        */
15107        dropBuilder.append("Low on memory:");
15108        dropBuilder.append(stack);
15109        dropBuilder.append('\n');
15110        dropBuilder.append(fullNativeBuilder);
15111        dropBuilder.append(fullJavaBuilder);
15112        dropBuilder.append('\n');
15113        dropBuilder.append(memInfoBuilder);
15114        dropBuilder.append('\n');
15115        /*
15116        dropBuilder.append(oomString);
15117        dropBuilder.append('\n');
15118        */
15119        StringWriter catSw = new StringWriter();
15120        synchronized (ActivityManagerService.this) {
15121            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15122            String[] emptyArgs = new String[] { };
15123            catPw.println();
15124            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
15125            catPw.println();
15126            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
15127                    false, false, null);
15128            catPw.println();
15129            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
15130            catPw.flush();
15131        }
15132        dropBuilder.append(catSw.toString());
15133        addErrorToDropBox("lowmem", null, "system_server", null,
15134                null, tag.toString(), dropBuilder.toString(), null, null);
15135        //Slog.i(TAG, "Sent to dropbox:");
15136        //Slog.i(TAG, dropBuilder.toString());
15137        synchronized (ActivityManagerService.this) {
15138            long now = SystemClock.uptimeMillis();
15139            if (mLastMemUsageReportTime < now) {
15140                mLastMemUsageReportTime = now;
15141            }
15142        }
15143    }
15144
15145    /**
15146     * Searches array of arguments for the specified string
15147     * @param args array of argument strings
15148     * @param value value to search for
15149     * @return true if the value is contained in the array
15150     */
15151    private static boolean scanArgs(String[] args, String value) {
15152        if (args != null) {
15153            for (String arg : args) {
15154                if (value.equals(arg)) {
15155                    return true;
15156                }
15157            }
15158        }
15159        return false;
15160    }
15161
15162    private final boolean removeDyingProviderLocked(ProcessRecord proc,
15163            ContentProviderRecord cpr, boolean always) {
15164        final boolean inLaunching = mLaunchingProviders.contains(cpr);
15165
15166        if (!inLaunching || always) {
15167            synchronized (cpr) {
15168                cpr.launchingApp = null;
15169                cpr.notifyAll();
15170            }
15171            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
15172            String names[] = cpr.info.authority.split(";");
15173            for (int j = 0; j < names.length; j++) {
15174                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
15175            }
15176        }
15177
15178        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
15179            ContentProviderConnection conn = cpr.connections.get(i);
15180            if (conn.waiting) {
15181                // If this connection is waiting for the provider, then we don't
15182                // need to mess with its process unless we are always removing
15183                // or for some reason the provider is not currently launching.
15184                if (inLaunching && !always) {
15185                    continue;
15186                }
15187            }
15188            ProcessRecord capp = conn.client;
15189            conn.dead = true;
15190            if (conn.stableCount > 0) {
15191                if (!capp.persistent && capp.thread != null
15192                        && capp.pid != 0
15193                        && capp.pid != MY_PID) {
15194                    capp.kill("depends on provider "
15195                            + cpr.name.flattenToShortString()
15196                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
15197                }
15198            } else if (capp.thread != null && conn.provider.provider != null) {
15199                try {
15200                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
15201                } catch (RemoteException e) {
15202                }
15203                // In the protocol here, we don't expect the client to correctly
15204                // clean up this connection, we'll just remove it.
15205                cpr.connections.remove(i);
15206                if (conn.client.conProviders.remove(conn)) {
15207                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
15208                }
15209            }
15210        }
15211
15212        if (inLaunching && always) {
15213            mLaunchingProviders.remove(cpr);
15214        }
15215        return inLaunching;
15216    }
15217
15218    /**
15219     * Main code for cleaning up a process when it has gone away.  This is
15220     * called both as a result of the process dying, or directly when stopping
15221     * a process when running in single process mode.
15222     *
15223     * @return Returns true if the given process has been restarted, so the
15224     * app that was passed in must remain on the process lists.
15225     */
15226    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
15227            boolean restarting, boolean allowRestart, int index) {
15228        if (index >= 0) {
15229            removeLruProcessLocked(app);
15230            ProcessList.remove(app.pid);
15231        }
15232
15233        mProcessesToGc.remove(app);
15234        mPendingPssProcesses.remove(app);
15235
15236        // Dismiss any open dialogs.
15237        if (app.crashDialog != null && !app.forceCrashReport) {
15238            app.crashDialog.dismiss();
15239            app.crashDialog = null;
15240        }
15241        if (app.anrDialog != null) {
15242            app.anrDialog.dismiss();
15243            app.anrDialog = null;
15244        }
15245        if (app.waitDialog != null) {
15246            app.waitDialog.dismiss();
15247            app.waitDialog = null;
15248        }
15249
15250        app.crashing = false;
15251        app.notResponding = false;
15252
15253        app.resetPackageList(mProcessStats);
15254        app.unlinkDeathRecipient();
15255        app.makeInactive(mProcessStats);
15256        app.waitingToKill = null;
15257        app.forcingToForeground = null;
15258        updateProcessForegroundLocked(app, false, false);
15259        app.foregroundActivities = false;
15260        app.hasShownUi = false;
15261        app.treatLikeActivity = false;
15262        app.hasAboveClient = false;
15263        app.hasClientActivities = false;
15264
15265        mServices.killServicesLocked(app, allowRestart);
15266
15267        boolean restart = false;
15268
15269        // Remove published content providers.
15270        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
15271            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
15272            final boolean always = app.bad || !allowRestart;
15273            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
15274            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
15275                // We left the provider in the launching list, need to
15276                // restart it.
15277                restart = true;
15278            }
15279
15280            cpr.provider = null;
15281            cpr.proc = null;
15282        }
15283        app.pubProviders.clear();
15284
15285        // Take care of any launching providers waiting for this process.
15286        if (checkAppInLaunchingProvidersLocked(app, false)) {
15287            restart = true;
15288        }
15289
15290        // Unregister from connected content providers.
15291        if (!app.conProviders.isEmpty()) {
15292            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
15293                ContentProviderConnection conn = app.conProviders.get(i);
15294                conn.provider.connections.remove(conn);
15295                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
15296                        conn.provider.name);
15297            }
15298            app.conProviders.clear();
15299        }
15300
15301        // At this point there may be remaining entries in mLaunchingProviders
15302        // where we were the only one waiting, so they are no longer of use.
15303        // Look for these and clean up if found.
15304        // XXX Commented out for now.  Trying to figure out a way to reproduce
15305        // the actual situation to identify what is actually going on.
15306        if (false) {
15307            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15308                ContentProviderRecord cpr = mLaunchingProviders.get(i);
15309                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
15310                    synchronized (cpr) {
15311                        cpr.launchingApp = null;
15312                        cpr.notifyAll();
15313                    }
15314                }
15315            }
15316        }
15317
15318        skipCurrentReceiverLocked(app);
15319
15320        // Unregister any receivers.
15321        for (int i = app.receivers.size() - 1; i >= 0; i--) {
15322            removeReceiverLocked(app.receivers.valueAt(i));
15323        }
15324        app.receivers.clear();
15325
15326        // If the app is undergoing backup, tell the backup manager about it
15327        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
15328            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
15329                    + mBackupTarget.appInfo + " died during backup");
15330            try {
15331                IBackupManager bm = IBackupManager.Stub.asInterface(
15332                        ServiceManager.getService(Context.BACKUP_SERVICE));
15333                bm.agentDisconnected(app.info.packageName);
15334            } catch (RemoteException e) {
15335                // can't happen; backup manager is local
15336            }
15337        }
15338
15339        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
15340            ProcessChangeItem item = mPendingProcessChanges.get(i);
15341            if (item.pid == app.pid) {
15342                mPendingProcessChanges.remove(i);
15343                mAvailProcessChanges.add(item);
15344            }
15345        }
15346        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
15347
15348        // If the caller is restarting this app, then leave it in its
15349        // current lists and let the caller take care of it.
15350        if (restarting) {
15351            return false;
15352        }
15353
15354        if (!app.persistent || app.isolated) {
15355            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
15356                    "Removing non-persistent process during cleanup: " + app);
15357            removeProcessNameLocked(app.processName, app.uid);
15358            if (mHeavyWeightProcess == app) {
15359                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
15360                        mHeavyWeightProcess.userId, 0));
15361                mHeavyWeightProcess = null;
15362            }
15363        } else if (!app.removed) {
15364            // This app is persistent, so we need to keep its record around.
15365            // If it is not already on the pending app list, add it there
15366            // and start a new process for it.
15367            if (mPersistentStartingProcesses.indexOf(app) < 0) {
15368                mPersistentStartingProcesses.add(app);
15369                restart = true;
15370            }
15371        }
15372        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
15373                TAG_CLEANUP, "Clean-up removing on hold: " + app);
15374        mProcessesOnHold.remove(app);
15375
15376        if (app == mHomeProcess) {
15377            mHomeProcess = null;
15378        }
15379        if (app == mPreviousProcess) {
15380            mPreviousProcess = null;
15381        }
15382
15383        if (restart && !app.isolated) {
15384            // We have components that still need to be running in the
15385            // process, so re-launch it.
15386            if (index < 0) {
15387                ProcessList.remove(app.pid);
15388            }
15389            addProcessNameLocked(app);
15390            startProcessLocked(app, "restart", app.processName);
15391            return true;
15392        } else if (app.pid > 0 && app.pid != MY_PID) {
15393            // Goodbye!
15394            boolean removed;
15395            synchronized (mPidsSelfLocked) {
15396                mPidsSelfLocked.remove(app.pid);
15397                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
15398            }
15399            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
15400            if (app.isolated) {
15401                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
15402            }
15403            app.setPid(0);
15404        }
15405        return false;
15406    }
15407
15408    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
15409        // Look through the content providers we are waiting to have launched,
15410        // and if any run in this process then either schedule a restart of
15411        // the process or kill the client waiting for it if this process has
15412        // gone bad.
15413        boolean restart = false;
15414        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15415            ContentProviderRecord cpr = mLaunchingProviders.get(i);
15416            if (cpr.launchingApp == app) {
15417                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
15418                    restart = true;
15419                } else {
15420                    removeDyingProviderLocked(app, cpr, true);
15421                }
15422            }
15423        }
15424        return restart;
15425    }
15426
15427    // =========================================================
15428    // SERVICES
15429    // =========================================================
15430
15431    @Override
15432    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
15433            int flags) {
15434        enforceNotIsolatedCaller("getServices");
15435        synchronized (this) {
15436            return mServices.getRunningServiceInfoLocked(maxNum, flags);
15437        }
15438    }
15439
15440    @Override
15441    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
15442        enforceNotIsolatedCaller("getRunningServiceControlPanel");
15443        synchronized (this) {
15444            return mServices.getRunningServiceControlPanelLocked(name);
15445        }
15446    }
15447
15448    @Override
15449    public ComponentName startService(IApplicationThread caller, Intent service,
15450            String resolvedType, int userId) throws TransactionTooLargeException {
15451        enforceNotIsolatedCaller("startService");
15452        // Refuse possible leaked file descriptors
15453        if (service != null && service.hasFileDescriptors() == true) {
15454            throw new IllegalArgumentException("File descriptors passed in Intent");
15455        }
15456
15457        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15458                "startService: " + service + " type=" + resolvedType);
15459        synchronized(this) {
15460            final int callingPid = Binder.getCallingPid();
15461            final int callingUid = Binder.getCallingUid();
15462            final long origId = Binder.clearCallingIdentity();
15463            ComponentName res = mServices.startServiceLocked(caller, service,
15464                    resolvedType, callingPid, callingUid, userId);
15465            Binder.restoreCallingIdentity(origId);
15466            return res;
15467        }
15468    }
15469
15470    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType, int userId)
15471            throws TransactionTooLargeException {
15472        synchronized(this) {
15473            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15474                    "startServiceInPackage: " + service + " type=" + resolvedType);
15475            final long origId = Binder.clearCallingIdentity();
15476            ComponentName res = mServices.startServiceLocked(null, service,
15477                    resolvedType, -1, uid, userId);
15478            Binder.restoreCallingIdentity(origId);
15479            return res;
15480        }
15481    }
15482
15483    @Override
15484    public int stopService(IApplicationThread caller, Intent service,
15485            String resolvedType, int userId) {
15486        enforceNotIsolatedCaller("stopService");
15487        // Refuse possible leaked file descriptors
15488        if (service != null && service.hasFileDescriptors() == true) {
15489            throw new IllegalArgumentException("File descriptors passed in Intent");
15490        }
15491
15492        synchronized(this) {
15493            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
15494        }
15495    }
15496
15497    @Override
15498    public IBinder peekService(Intent service, String resolvedType) {
15499        enforceNotIsolatedCaller("peekService");
15500        // Refuse possible leaked file descriptors
15501        if (service != null && service.hasFileDescriptors() == true) {
15502            throw new IllegalArgumentException("File descriptors passed in Intent");
15503        }
15504        synchronized(this) {
15505            return mServices.peekServiceLocked(service, resolvedType);
15506        }
15507    }
15508
15509    @Override
15510    public boolean stopServiceToken(ComponentName className, IBinder token,
15511            int startId) {
15512        synchronized(this) {
15513            return mServices.stopServiceTokenLocked(className, token, startId);
15514        }
15515    }
15516
15517    @Override
15518    public void setServiceForeground(ComponentName className, IBinder token,
15519            int id, Notification notification, boolean removeNotification) {
15520        synchronized(this) {
15521            mServices.setServiceForegroundLocked(className, token, id, notification,
15522                    removeNotification);
15523        }
15524    }
15525
15526    @Override
15527    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15528            boolean requireFull, String name, String callerPackage) {
15529        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15530                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15531    }
15532
15533    int unsafeConvertIncomingUser(int userId) {
15534        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15535                ? mCurrentUserId : userId;
15536    }
15537
15538    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15539            int allowMode, String name, String callerPackage) {
15540        final int callingUserId = UserHandle.getUserId(callingUid);
15541        if (callingUserId == userId) {
15542            return userId;
15543        }
15544
15545        // Note that we may be accessing mCurrentUserId outside of a lock...
15546        // shouldn't be a big deal, if this is being called outside
15547        // of a locked context there is intrinsically a race with
15548        // the value the caller will receive and someone else changing it.
15549        // We assume that USER_CURRENT_OR_SELF will use the current user; later
15550        // we will switch to the calling user if access to the current user fails.
15551        int targetUserId = unsafeConvertIncomingUser(userId);
15552
15553        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15554            final boolean allow;
15555            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15556                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15557                // If the caller has this permission, they always pass go.  And collect $200.
15558                allow = true;
15559            } else if (allowMode == ALLOW_FULL_ONLY) {
15560                // We require full access, sucks to be you.
15561                allow = false;
15562            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15563                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15564                // If the caller does not have either permission, they are always doomed.
15565                allow = false;
15566            } else if (allowMode == ALLOW_NON_FULL) {
15567                // We are blanket allowing non-full access, you lucky caller!
15568                allow = true;
15569            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15570                // We may or may not allow this depending on whether the two users are
15571                // in the same profile.
15572                synchronized (mUserProfileGroupIdsSelfLocked) {
15573                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15574                            UserInfo.NO_PROFILE_GROUP_ID);
15575                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15576                            UserInfo.NO_PROFILE_GROUP_ID);
15577                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15578                            && callingProfile == targetProfile;
15579                }
15580            } else {
15581                throw new IllegalArgumentException("Unknown mode: " + allowMode);
15582            }
15583            if (!allow) {
15584                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15585                    // In this case, they would like to just execute as their
15586                    // owner user instead of failing.
15587                    targetUserId = callingUserId;
15588                } else {
15589                    StringBuilder builder = new StringBuilder(128);
15590                    builder.append("Permission Denial: ");
15591                    builder.append(name);
15592                    if (callerPackage != null) {
15593                        builder.append(" from ");
15594                        builder.append(callerPackage);
15595                    }
15596                    builder.append(" asks to run as user ");
15597                    builder.append(userId);
15598                    builder.append(" but is calling from user ");
15599                    builder.append(UserHandle.getUserId(callingUid));
15600                    builder.append("; this requires ");
15601                    builder.append(INTERACT_ACROSS_USERS_FULL);
15602                    if (allowMode != ALLOW_FULL_ONLY) {
15603                        builder.append(" or ");
15604                        builder.append(INTERACT_ACROSS_USERS);
15605                    }
15606                    String msg = builder.toString();
15607                    Slog.w(TAG, msg);
15608                    throw new SecurityException(msg);
15609                }
15610            }
15611        }
15612        if (!allowAll && targetUserId < 0) {
15613            throw new IllegalArgumentException(
15614                    "Call does not support special user #" + targetUserId);
15615        }
15616        // Check shell permission
15617        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15618            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15619                    targetUserId)) {
15620                throw new SecurityException("Shell does not have permission to access user "
15621                        + targetUserId + "\n " + Debug.getCallers(3));
15622            }
15623        }
15624        return targetUserId;
15625    }
15626
15627    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15628            String className, int flags) {
15629        boolean result = false;
15630        // For apps that don't have pre-defined UIDs, check for permission
15631        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15632            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15633                if (ActivityManager.checkUidPermission(
15634                        INTERACT_ACROSS_USERS,
15635                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15636                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15637                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15638                            + " requests FLAG_SINGLE_USER, but app does not hold "
15639                            + INTERACT_ACROSS_USERS;
15640                    Slog.w(TAG, msg);
15641                    throw new SecurityException(msg);
15642                }
15643                // Permission passed
15644                result = true;
15645            }
15646        } else if ("system".equals(componentProcessName)) {
15647            result = true;
15648        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15649            // Phone app and persistent apps are allowed to export singleuser providers.
15650            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15651                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15652        }
15653        if (DEBUG_MU) Slog.v(TAG_MU,
15654                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
15655                + Integer.toHexString(flags) + ") = " + result);
15656        return result;
15657    }
15658
15659    /**
15660     * Checks to see if the caller is in the same app as the singleton
15661     * component, or the component is in a special app. It allows special apps
15662     * to export singleton components but prevents exporting singleton
15663     * components for regular apps.
15664     */
15665    boolean isValidSingletonCall(int callingUid, int componentUid) {
15666        int componentAppId = UserHandle.getAppId(componentUid);
15667        return UserHandle.isSameApp(callingUid, componentUid)
15668                || componentAppId == Process.SYSTEM_UID
15669                || componentAppId == Process.PHONE_UID
15670                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15671                        == PackageManager.PERMISSION_GRANTED;
15672    }
15673
15674    public int bindService(IApplicationThread caller, IBinder token, Intent service,
15675            String resolvedType, IServiceConnection connection, int flags, int userId)
15676            throws TransactionTooLargeException {
15677        enforceNotIsolatedCaller("bindService");
15678
15679        // Refuse possible leaked file descriptors
15680        if (service != null && service.hasFileDescriptors() == true) {
15681            throw new IllegalArgumentException("File descriptors passed in Intent");
15682        }
15683
15684        synchronized(this) {
15685            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15686                    connection, flags, userId);
15687        }
15688    }
15689
15690    public boolean unbindService(IServiceConnection connection) {
15691        synchronized (this) {
15692            return mServices.unbindServiceLocked(connection);
15693        }
15694    }
15695
15696    public void publishService(IBinder token, Intent intent, IBinder service) {
15697        // Refuse possible leaked file descriptors
15698        if (intent != null && intent.hasFileDescriptors() == true) {
15699            throw new IllegalArgumentException("File descriptors passed in Intent");
15700        }
15701
15702        synchronized(this) {
15703            if (!(token instanceof ServiceRecord)) {
15704                throw new IllegalArgumentException("Invalid service token");
15705            }
15706            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15707        }
15708    }
15709
15710    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15711        // Refuse possible leaked file descriptors
15712        if (intent != null && intent.hasFileDescriptors() == true) {
15713            throw new IllegalArgumentException("File descriptors passed in Intent");
15714        }
15715
15716        synchronized(this) {
15717            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15718        }
15719    }
15720
15721    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15722        synchronized(this) {
15723            if (!(token instanceof ServiceRecord)) {
15724                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
15725                throw new IllegalArgumentException("Invalid service token");
15726            }
15727            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15728        }
15729    }
15730
15731    // =========================================================
15732    // BACKUP AND RESTORE
15733    // =========================================================
15734
15735    // Cause the target app to be launched if necessary and its backup agent
15736    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15737    // activity manager to announce its creation.
15738    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15739        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
15740                "bindBackupAgent: app=" + app + " mode=" + backupMode);
15741        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15742
15743        synchronized(this) {
15744            // !!! TODO: currently no check here that we're already bound
15745            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15746            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15747            synchronized (stats) {
15748                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15749            }
15750
15751            // Backup agent is now in use, its package can't be stopped.
15752            try {
15753                AppGlobals.getPackageManager().setPackageStoppedState(
15754                        app.packageName, false, UserHandle.getUserId(app.uid));
15755            } catch (RemoteException e) {
15756            } catch (IllegalArgumentException e) {
15757                Slog.w(TAG, "Failed trying to unstop package "
15758                        + app.packageName + ": " + e);
15759            }
15760
15761            BackupRecord r = new BackupRecord(ss, app, backupMode);
15762            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15763                    ? new ComponentName(app.packageName, app.backupAgentName)
15764                    : new ComponentName("android", "FullBackupAgent");
15765            // startProcessLocked() returns existing proc's record if it's already running
15766            ProcessRecord proc = startProcessLocked(app.processName, app,
15767                    false, 0, "backup", hostingName, false, false, false);
15768            if (proc == null) {
15769                Slog.e(TAG, "Unable to start backup agent process " + r);
15770                return false;
15771            }
15772
15773            r.app = proc;
15774            mBackupTarget = r;
15775            mBackupAppName = app.packageName;
15776
15777            // Try not to kill the process during backup
15778            updateOomAdjLocked(proc);
15779
15780            // If the process is already attached, schedule the creation of the backup agent now.
15781            // If it is not yet live, this will be done when it attaches to the framework.
15782            if (proc.thread != null) {
15783                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
15784                try {
15785                    proc.thread.scheduleCreateBackupAgent(app,
15786                            compatibilityInfoForPackageLocked(app), backupMode);
15787                } catch (RemoteException e) {
15788                    // Will time out on the backup manager side
15789                }
15790            } else {
15791                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
15792            }
15793            // Invariants: at this point, the target app process exists and the application
15794            // is either already running or in the process of coming up.  mBackupTarget and
15795            // mBackupAppName describe the app, so that when it binds back to the AM we
15796            // know that it's scheduled for a backup-agent operation.
15797        }
15798
15799        return true;
15800    }
15801
15802    @Override
15803    public void clearPendingBackup() {
15804        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
15805        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15806
15807        synchronized (this) {
15808            mBackupTarget = null;
15809            mBackupAppName = null;
15810        }
15811    }
15812
15813    // A backup agent has just come up
15814    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15815        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
15816                + " = " + agent);
15817
15818        synchronized(this) {
15819            if (!agentPackageName.equals(mBackupAppName)) {
15820                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15821                return;
15822            }
15823        }
15824
15825        long oldIdent = Binder.clearCallingIdentity();
15826        try {
15827            IBackupManager bm = IBackupManager.Stub.asInterface(
15828                    ServiceManager.getService(Context.BACKUP_SERVICE));
15829            bm.agentConnected(agentPackageName, agent);
15830        } catch (RemoteException e) {
15831            // can't happen; the backup manager service is local
15832        } catch (Exception e) {
15833            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15834            e.printStackTrace();
15835        } finally {
15836            Binder.restoreCallingIdentity(oldIdent);
15837        }
15838    }
15839
15840    // done with this agent
15841    public void unbindBackupAgent(ApplicationInfo appInfo) {
15842        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
15843        if (appInfo == null) {
15844            Slog.w(TAG, "unbind backup agent for null app");
15845            return;
15846        }
15847
15848        synchronized(this) {
15849            try {
15850                if (mBackupAppName == null) {
15851                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15852                    return;
15853                }
15854
15855                if (!mBackupAppName.equals(appInfo.packageName)) {
15856                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15857                    return;
15858                }
15859
15860                // Not backing this app up any more; reset its OOM adjustment
15861                final ProcessRecord proc = mBackupTarget.app;
15862                updateOomAdjLocked(proc);
15863
15864                // If the app crashed during backup, 'thread' will be null here
15865                if (proc.thread != null) {
15866                    try {
15867                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15868                                compatibilityInfoForPackageLocked(appInfo));
15869                    } catch (Exception e) {
15870                        Slog.e(TAG, "Exception when unbinding backup agent:");
15871                        e.printStackTrace();
15872                    }
15873                }
15874            } finally {
15875                mBackupTarget = null;
15876                mBackupAppName = null;
15877            }
15878        }
15879    }
15880    // =========================================================
15881    // BROADCASTS
15882    // =========================================================
15883
15884    boolean isPendingBroadcastProcessLocked(int pid) {
15885        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15886                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15887    }
15888
15889    void skipPendingBroadcastLocked(int pid) {
15890            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15891            for (BroadcastQueue queue : mBroadcastQueues) {
15892                queue.skipPendingBroadcastLocked(pid);
15893            }
15894    }
15895
15896    // The app just attached; send any pending broadcasts that it should receive
15897    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15898        boolean didSomething = false;
15899        for (BroadcastQueue queue : mBroadcastQueues) {
15900            didSomething |= queue.sendPendingBroadcastsLocked(app);
15901        }
15902        return didSomething;
15903    }
15904
15905    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15906            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15907        enforceNotIsolatedCaller("registerReceiver");
15908        ArrayList<Intent> stickyIntents = null;
15909        ProcessRecord callerApp = null;
15910        int callingUid;
15911        int callingPid;
15912        synchronized(this) {
15913            if (caller != null) {
15914                callerApp = getRecordForAppLocked(caller);
15915                if (callerApp == null) {
15916                    throw new SecurityException(
15917                            "Unable to find app for caller " + caller
15918                            + " (pid=" + Binder.getCallingPid()
15919                            + ") when registering receiver " + receiver);
15920                }
15921                if (callerApp.info.uid != Process.SYSTEM_UID &&
15922                        !callerApp.pkgList.containsKey(callerPackage) &&
15923                        !"android".equals(callerPackage)) {
15924                    throw new SecurityException("Given caller package " + callerPackage
15925                            + " is not running in process " + callerApp);
15926                }
15927                callingUid = callerApp.info.uid;
15928                callingPid = callerApp.pid;
15929            } else {
15930                callerPackage = null;
15931                callingUid = Binder.getCallingUid();
15932                callingPid = Binder.getCallingPid();
15933            }
15934
15935            userId = handleIncomingUser(callingPid, callingUid, userId,
15936                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15937
15938            Iterator<String> actions = filter.actionsIterator();
15939            if (actions == null) {
15940                ArrayList<String> noAction = new ArrayList<String>(1);
15941                noAction.add(null);
15942                actions = noAction.iterator();
15943            }
15944
15945            // Collect stickies of users
15946            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
15947            while (actions.hasNext()) {
15948                String action = actions.next();
15949                for (int id : userIds) {
15950                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
15951                    if (stickies != null) {
15952                        ArrayList<Intent> intents = stickies.get(action);
15953                        if (intents != null) {
15954                            if (stickyIntents == null) {
15955                                stickyIntents = new ArrayList<Intent>();
15956                            }
15957                            stickyIntents.addAll(intents);
15958                        }
15959                    }
15960                }
15961            }
15962        }
15963
15964        ArrayList<Intent> allSticky = null;
15965        if (stickyIntents != null) {
15966            final ContentResolver resolver = mContext.getContentResolver();
15967            // Look for any matching sticky broadcasts...
15968            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
15969                Intent intent = stickyIntents.get(i);
15970                // If intent has scheme "content", it will need to acccess
15971                // provider that needs to lock mProviderMap in ActivityThread
15972                // and also it may need to wait application response, so we
15973                // cannot lock ActivityManagerService here.
15974                if (filter.match(resolver, intent, true, TAG) >= 0) {
15975                    if (allSticky == null) {
15976                        allSticky = new ArrayList<Intent>();
15977                    }
15978                    allSticky.add(intent);
15979                }
15980            }
15981        }
15982
15983        // The first sticky in the list is returned directly back to the client.
15984        Intent sticky = allSticky != null ? allSticky.get(0) : null;
15985        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
15986        if (receiver == null) {
15987            return sticky;
15988        }
15989
15990        synchronized (this) {
15991            if (callerApp != null && (callerApp.thread == null
15992                    || callerApp.thread.asBinder() != caller.asBinder())) {
15993                // Original caller already died
15994                return null;
15995            }
15996            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15997            if (rl == null) {
15998                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15999                        userId, receiver);
16000                if (rl.app != null) {
16001                    rl.app.receivers.add(rl);
16002                } else {
16003                    try {
16004                        receiver.asBinder().linkToDeath(rl, 0);
16005                    } catch (RemoteException e) {
16006                        return sticky;
16007                    }
16008                    rl.linkedToDeath = true;
16009                }
16010                mRegisteredReceivers.put(receiver.asBinder(), rl);
16011            } else if (rl.uid != callingUid) {
16012                throw new IllegalArgumentException(
16013                        "Receiver requested to register for uid " + callingUid
16014                        + " was previously registered for uid " + rl.uid);
16015            } else if (rl.pid != callingPid) {
16016                throw new IllegalArgumentException(
16017                        "Receiver requested to register for pid " + callingPid
16018                        + " was previously registered for pid " + rl.pid);
16019            } else if (rl.userId != userId) {
16020                throw new IllegalArgumentException(
16021                        "Receiver requested to register for user " + userId
16022                        + " was previously registered for user " + rl.userId);
16023            }
16024            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16025                    permission, callingUid, userId);
16026            rl.add(bf);
16027            if (!bf.debugCheck()) {
16028                Slog.w(TAG, "==> For Dynamic broadcast");
16029            }
16030            mReceiverResolver.addFilter(bf);
16031
16032            // Enqueue broadcasts for all existing stickies that match
16033            // this filter.
16034            if (allSticky != null) {
16035                ArrayList receivers = new ArrayList();
16036                receivers.add(bf);
16037
16038                final int stickyCount = allSticky.size();
16039                for (int i = 0; i < stickyCount; i++) {
16040                    Intent intent = allSticky.get(i);
16041                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16042                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16043                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
16044                            null, null, false, true, true, -1);
16045                    queue.enqueueParallelBroadcastLocked(r);
16046                    queue.scheduleBroadcastsLocked();
16047                }
16048            }
16049
16050            return sticky;
16051        }
16052    }
16053
16054    public void unregisterReceiver(IIntentReceiver receiver) {
16055        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16056
16057        final long origId = Binder.clearCallingIdentity();
16058        try {
16059            boolean doTrim = false;
16060
16061            synchronized(this) {
16062                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16063                if (rl != null) {
16064                    final BroadcastRecord r = rl.curBroadcast;
16065                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16066                        final boolean doNext = r.queue.finishReceiverLocked(
16067                                r, r.resultCode, r.resultData, r.resultExtras,
16068                                r.resultAbort, false);
16069                        if (doNext) {
16070                            doTrim = true;
16071                            r.queue.processNextBroadcast(false);
16072                        }
16073                    }
16074
16075                    if (rl.app != null) {
16076                        rl.app.receivers.remove(rl);
16077                    }
16078                    removeReceiverLocked(rl);
16079                    if (rl.linkedToDeath) {
16080                        rl.linkedToDeath = false;
16081                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
16082                    }
16083                }
16084            }
16085
16086            // If we actually concluded any broadcasts, we might now be able
16087            // to trim the recipients' apps from our working set
16088            if (doTrim) {
16089                trimApplications();
16090                return;
16091            }
16092
16093        } finally {
16094            Binder.restoreCallingIdentity(origId);
16095        }
16096    }
16097
16098    void removeReceiverLocked(ReceiverList rl) {
16099        mRegisteredReceivers.remove(rl.receiver.asBinder());
16100        for (int i = rl.size() - 1; i >= 0; i--) {
16101            mReceiverResolver.removeFilter(rl.get(i));
16102        }
16103    }
16104
16105    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16106        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16107            ProcessRecord r = mLruProcesses.get(i);
16108            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16109                try {
16110                    r.thread.dispatchPackageBroadcast(cmd, packages);
16111                } catch (RemoteException ex) {
16112                }
16113            }
16114        }
16115    }
16116
16117    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16118            int callingUid, int[] users) {
16119        List<ResolveInfo> receivers = null;
16120        try {
16121            HashSet<ComponentName> singleUserReceivers = null;
16122            boolean scannedFirstReceivers = false;
16123            for (int user : users) {
16124                // Skip users that have Shell restrictions
16125                if (callingUid == Process.SHELL_UID
16126                        && getUserManagerLocked().hasUserRestriction(
16127                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
16128                    continue;
16129                }
16130                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16131                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
16132                if (user != UserHandle.USER_OWNER && newReceivers != null) {
16133                    // If this is not the primary user, we need to check for
16134                    // any receivers that should be filtered out.
16135                    for (int i=0; i<newReceivers.size(); i++) {
16136                        ResolveInfo ri = newReceivers.get(i);
16137                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
16138                            newReceivers.remove(i);
16139                            i--;
16140                        }
16141                    }
16142                }
16143                if (newReceivers != null && newReceivers.size() == 0) {
16144                    newReceivers = null;
16145                }
16146                if (receivers == null) {
16147                    receivers = newReceivers;
16148                } else if (newReceivers != null) {
16149                    // We need to concatenate the additional receivers
16150                    // found with what we have do far.  This would be easy,
16151                    // but we also need to de-dup any receivers that are
16152                    // singleUser.
16153                    if (!scannedFirstReceivers) {
16154                        // Collect any single user receivers we had already retrieved.
16155                        scannedFirstReceivers = true;
16156                        for (int i=0; i<receivers.size(); i++) {
16157                            ResolveInfo ri = receivers.get(i);
16158                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16159                                ComponentName cn = new ComponentName(
16160                                        ri.activityInfo.packageName, ri.activityInfo.name);
16161                                if (singleUserReceivers == null) {
16162                                    singleUserReceivers = new HashSet<ComponentName>();
16163                                }
16164                                singleUserReceivers.add(cn);
16165                            }
16166                        }
16167                    }
16168                    // Add the new results to the existing results, tracking
16169                    // and de-dupping single user receivers.
16170                    for (int i=0; i<newReceivers.size(); i++) {
16171                        ResolveInfo ri = newReceivers.get(i);
16172                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16173                            ComponentName cn = new ComponentName(
16174                                    ri.activityInfo.packageName, ri.activityInfo.name);
16175                            if (singleUserReceivers == null) {
16176                                singleUserReceivers = new HashSet<ComponentName>();
16177                            }
16178                            if (!singleUserReceivers.contains(cn)) {
16179                                singleUserReceivers.add(cn);
16180                                receivers.add(ri);
16181                            }
16182                        } else {
16183                            receivers.add(ri);
16184                        }
16185                    }
16186                }
16187            }
16188        } catch (RemoteException ex) {
16189            // pm is in same process, this will never happen.
16190        }
16191        return receivers;
16192    }
16193
16194    private final int broadcastIntentLocked(ProcessRecord callerApp,
16195            String callerPackage, Intent intent, String resolvedType,
16196            IIntentReceiver resultTo, int resultCode, String resultData,
16197            Bundle map, String requiredPermission, int appOp,
16198            boolean ordered, boolean sticky, int callingPid, int callingUid,
16199            int userId) {
16200        intent = new Intent(intent);
16201
16202        // By default broadcasts do not go to stopped apps.
16203        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
16204
16205        // If we have not finished booting, don't allow this to launch new processes.
16206        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
16207            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16208        }
16209
16210        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
16211                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
16212                + " ordered=" + ordered + " userid=" + userId);
16213        if ((resultTo != null) && !ordered) {
16214            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
16215        }
16216
16217        userId = handleIncomingUser(callingPid, callingUid, userId,
16218                true, ALLOW_NON_FULL, "broadcast", callerPackage);
16219
16220        // Make sure that the user who is receiving this broadcast is running.
16221        // If not, we will just skip it. Make an exception for shutdown broadcasts
16222        // and upgrade steps.
16223
16224        if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
16225            if ((callingUid != Process.SYSTEM_UID
16226                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
16227                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
16228                Slog.w(TAG, "Skipping broadcast of " + intent
16229                        + ": user " + userId + " is stopped");
16230                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
16231            }
16232        }
16233
16234        /*
16235         * Prevent non-system code (defined here to be non-persistent
16236         * processes) from sending protected broadcasts.
16237         */
16238        int callingAppId = UserHandle.getAppId(callingUid);
16239        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
16240            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
16241            || callingAppId == Process.NFC_UID || callingUid == 0) {
16242            // Always okay.
16243        } else if (callerApp == null || !callerApp.persistent) {
16244            try {
16245                if (AppGlobals.getPackageManager().isProtectedBroadcast(
16246                        intent.getAction())) {
16247                    String msg = "Permission Denial: not allowed to send broadcast "
16248                            + intent.getAction() + " from pid="
16249                            + callingPid + ", uid=" + callingUid;
16250                    Slog.w(TAG, msg);
16251                    throw new SecurityException(msg);
16252                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
16253                    // Special case for compatibility: we don't want apps to send this,
16254                    // but historically it has not been protected and apps may be using it
16255                    // to poke their own app widget.  So, instead of making it protected,
16256                    // just limit it to the caller.
16257                    if (callerApp == null) {
16258                        String msg = "Permission Denial: not allowed to send broadcast "
16259                                + intent.getAction() + " from unknown caller.";
16260                        Slog.w(TAG, msg);
16261                        throw new SecurityException(msg);
16262                    } else if (intent.getComponent() != null) {
16263                        // They are good enough to send to an explicit component...  verify
16264                        // it is being sent to the calling app.
16265                        if (!intent.getComponent().getPackageName().equals(
16266                                callerApp.info.packageName)) {
16267                            String msg = "Permission Denial: not allowed to send broadcast "
16268                                    + intent.getAction() + " to "
16269                                    + intent.getComponent().getPackageName() + " from "
16270                                    + callerApp.info.packageName;
16271                            Slog.w(TAG, msg);
16272                            throw new SecurityException(msg);
16273                        }
16274                    } else {
16275                        // Limit broadcast to their own package.
16276                        intent.setPackage(callerApp.info.packageName);
16277                    }
16278                }
16279            } catch (RemoteException e) {
16280                Slog.w(TAG, "Remote exception", e);
16281                return ActivityManager.BROADCAST_SUCCESS;
16282            }
16283        }
16284
16285        final String action = intent.getAction();
16286        if (action != null) {
16287            switch (action) {
16288                case Intent.ACTION_UID_REMOVED:
16289                case Intent.ACTION_PACKAGE_REMOVED:
16290                case Intent.ACTION_PACKAGE_CHANGED:
16291                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16292                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16293                    // Handle special intents: if this broadcast is from the package
16294                    // manager about a package being removed, we need to remove all of
16295                    // its activities from the history stack.
16296                    if (checkComponentPermission(
16297                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
16298                            callingPid, callingUid, -1, true)
16299                            != PackageManager.PERMISSION_GRANTED) {
16300                        String msg = "Permission Denial: " + intent.getAction()
16301                                + " broadcast from " + callerPackage + " (pid=" + callingPid
16302                                + ", uid=" + callingUid + ")"
16303                                + " requires "
16304                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
16305                        Slog.w(TAG, msg);
16306                        throw new SecurityException(msg);
16307                    }
16308                    switch (action) {
16309                        case Intent.ACTION_UID_REMOVED:
16310                            final Bundle intentExtras = intent.getExtras();
16311                            final int uid = intentExtras != null
16312                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
16313                            if (uid >= 0) {
16314                                mBatteryStatsService.removeUid(uid);
16315                                mAppOpsService.uidRemoved(uid);
16316                            }
16317                            break;
16318                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16319                            // If resources are unavailable just force stop all those packages
16320                            // and flush the attribute cache as well.
16321                            String list[] =
16322                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16323                            if (list != null && list.length > 0) {
16324                                for (int i = 0; i < list.length; i++) {
16325                                    forceStopPackageLocked(list[i], -1, false, true, true,
16326                                            false, false, userId, "storage unmount");
16327                                }
16328                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16329                                sendPackageBroadcastLocked(
16330                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
16331                                        userId);
16332                            }
16333                            break;
16334                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16335                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16336                            break;
16337                        case Intent.ACTION_PACKAGE_REMOVED:
16338                        case Intent.ACTION_PACKAGE_CHANGED:
16339                            Uri data = intent.getData();
16340                            String ssp;
16341                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
16342                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
16343                                boolean fullUninstall = removed &&
16344                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16345                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
16346                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
16347                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
16348                                            false, true, true, false, fullUninstall, userId,
16349                                            removed ? "pkg removed" : "pkg changed");
16350                                }
16351                                if (removed) {
16352                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
16353                                            new String[] {ssp}, userId);
16354                                    if (fullUninstall) {
16355                                        mAppOpsService.packageRemoved(
16356                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
16357
16358                                        // Remove all permissions granted from/to this package
16359                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
16360
16361                                        removeTasksByPackageNameLocked(ssp, userId);
16362                                        mBatteryStatsService.notePackageUninstalled(ssp);
16363                                    }
16364                                } else {
16365                                    cleanupDisabledPackageComponentsLocked(ssp, userId,
16366                                            intent.getStringArrayExtra(
16367                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
16368                                }
16369                            }
16370                            break;
16371                    }
16372                    break;
16373                case Intent.ACTION_PACKAGE_ADDED:
16374                    // Special case for adding a package: by default turn on compatibility mode.
16375                    Uri data = intent.getData();
16376                    String ssp;
16377                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
16378                        final boolean replacing =
16379                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16380                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
16381
16382                        try {
16383                            ApplicationInfo ai = AppGlobals.getPackageManager().
16384                                    getApplicationInfo(ssp, 0, 0);
16385                            mBatteryStatsService.notePackageInstalled(ssp,
16386                                    ai != null ? ai.versionCode : 0);
16387                        } catch (RemoteException e) {
16388                        }
16389                    }
16390                    break;
16391                case Intent.ACTION_TIMEZONE_CHANGED:
16392                    // If this is the time zone changed action, queue up a message that will reset
16393                    // the timezone of all currently running processes. This message will get
16394                    // queued up before the broadcast happens.
16395                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
16396                    break;
16397                case Intent.ACTION_TIME_CHANGED:
16398                    // If the user set the time, let all running processes know.
16399                    final int is24Hour =
16400                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
16401                                    : 0;
16402                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
16403                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16404                    synchronized (stats) {
16405                        stats.noteCurrentTimeChangedLocked();
16406                    }
16407                    break;
16408                case Intent.ACTION_CLEAR_DNS_CACHE:
16409                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
16410                    break;
16411                case Proxy.PROXY_CHANGE_ACTION:
16412                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
16413                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
16414                    break;
16415            }
16416        }
16417
16418        // Add to the sticky list if requested.
16419        if (sticky) {
16420            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
16421                    callingPid, callingUid)
16422                    != PackageManager.PERMISSION_GRANTED) {
16423                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
16424                        + callingPid + ", uid=" + callingUid
16425                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16426                Slog.w(TAG, msg);
16427                throw new SecurityException(msg);
16428            }
16429            if (requiredPermission != null) {
16430                Slog.w(TAG, "Can't broadcast sticky intent " + intent
16431                        + " and enforce permission " + requiredPermission);
16432                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
16433            }
16434            if (intent.getComponent() != null) {
16435                throw new SecurityException(
16436                        "Sticky broadcasts can't target a specific component");
16437            }
16438            // We use userId directly here, since the "all" target is maintained
16439            // as a separate set of sticky broadcasts.
16440            if (userId != UserHandle.USER_ALL) {
16441                // But first, if this is not a broadcast to all users, then
16442                // make sure it doesn't conflict with an existing broadcast to
16443                // all users.
16444                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
16445                        UserHandle.USER_ALL);
16446                if (stickies != null) {
16447                    ArrayList<Intent> list = stickies.get(intent.getAction());
16448                    if (list != null) {
16449                        int N = list.size();
16450                        int i;
16451                        for (i=0; i<N; i++) {
16452                            if (intent.filterEquals(list.get(i))) {
16453                                throw new IllegalArgumentException(
16454                                        "Sticky broadcast " + intent + " for user "
16455                                        + userId + " conflicts with existing global broadcast");
16456                            }
16457                        }
16458                    }
16459                }
16460            }
16461            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16462            if (stickies == null) {
16463                stickies = new ArrayMap<>();
16464                mStickyBroadcasts.put(userId, stickies);
16465            }
16466            ArrayList<Intent> list = stickies.get(intent.getAction());
16467            if (list == null) {
16468                list = new ArrayList<>();
16469                stickies.put(intent.getAction(), list);
16470            }
16471            final int stickiesCount = list.size();
16472            int i;
16473            for (i = 0; i < stickiesCount; i++) {
16474                if (intent.filterEquals(list.get(i))) {
16475                    // This sticky already exists, replace it.
16476                    list.set(i, new Intent(intent));
16477                    break;
16478                }
16479            }
16480            if (i >= stickiesCount) {
16481                list.add(new Intent(intent));
16482            }
16483        }
16484
16485        int[] users;
16486        if (userId == UserHandle.USER_ALL) {
16487            // Caller wants broadcast to go to all started users.
16488            users = mStartedUserArray;
16489        } else {
16490            // Caller wants broadcast to go to one specific user.
16491            users = new int[] {userId};
16492        }
16493
16494        // Figure out who all will receive this broadcast.
16495        List receivers = null;
16496        List<BroadcastFilter> registeredReceivers = null;
16497        // Need to resolve the intent to interested receivers...
16498        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
16499                 == 0) {
16500            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
16501        }
16502        if (intent.getComponent() == null) {
16503            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
16504                // Query one target user at a time, excluding shell-restricted users
16505                UserManagerService ums = getUserManagerLocked();
16506                for (int i = 0; i < users.length; i++) {
16507                    if (ums.hasUserRestriction(
16508                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
16509                        continue;
16510                    }
16511                    List<BroadcastFilter> registeredReceiversForUser =
16512                            mReceiverResolver.queryIntent(intent,
16513                                    resolvedType, false, users[i]);
16514                    if (registeredReceivers == null) {
16515                        registeredReceivers = registeredReceiversForUser;
16516                    } else if (registeredReceiversForUser != null) {
16517                        registeredReceivers.addAll(registeredReceiversForUser);
16518                    }
16519                }
16520            } else {
16521                registeredReceivers = mReceiverResolver.queryIntent(intent,
16522                        resolvedType, false, userId);
16523            }
16524        }
16525
16526        final boolean replacePending =
16527                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16528
16529        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
16530                + " replacePending=" + replacePending);
16531
16532        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16533        if (!ordered && NR > 0) {
16534            // If we are not serializing this broadcast, then send the
16535            // registered receivers separately so they don't wait for the
16536            // components to be launched.
16537            final BroadcastQueue queue = broadcastQueueForIntent(intent);
16538            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16539                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
16540                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
16541                    ordered, sticky, false, userId);
16542            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
16543            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16544            if (!replaced) {
16545                queue.enqueueParallelBroadcastLocked(r);
16546                queue.scheduleBroadcastsLocked();
16547            }
16548            registeredReceivers = null;
16549            NR = 0;
16550        }
16551
16552        // Merge into one list.
16553        int ir = 0;
16554        if (receivers != null) {
16555            // A special case for PACKAGE_ADDED: do not allow the package
16556            // being added to see this broadcast.  This prevents them from
16557            // using this as a back door to get run as soon as they are
16558            // installed.  Maybe in the future we want to have a special install
16559            // broadcast or such for apps, but we'd like to deliberately make
16560            // this decision.
16561            String skipPackages[] = null;
16562            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16563                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16564                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16565                Uri data = intent.getData();
16566                if (data != null) {
16567                    String pkgName = data.getSchemeSpecificPart();
16568                    if (pkgName != null) {
16569                        skipPackages = new String[] { pkgName };
16570                    }
16571                }
16572            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16573                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16574            }
16575            if (skipPackages != null && (skipPackages.length > 0)) {
16576                for (String skipPackage : skipPackages) {
16577                    if (skipPackage != null) {
16578                        int NT = receivers.size();
16579                        for (int it=0; it<NT; it++) {
16580                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
16581                            if (curt.activityInfo.packageName.equals(skipPackage)) {
16582                                receivers.remove(it);
16583                                it--;
16584                                NT--;
16585                            }
16586                        }
16587                    }
16588                }
16589            }
16590
16591            int NT = receivers != null ? receivers.size() : 0;
16592            int it = 0;
16593            ResolveInfo curt = null;
16594            BroadcastFilter curr = null;
16595            while (it < NT && ir < NR) {
16596                if (curt == null) {
16597                    curt = (ResolveInfo)receivers.get(it);
16598                }
16599                if (curr == null) {
16600                    curr = registeredReceivers.get(ir);
16601                }
16602                if (curr.getPriority() >= curt.priority) {
16603                    // Insert this broadcast record into the final list.
16604                    receivers.add(it, curr);
16605                    ir++;
16606                    curr = null;
16607                    it++;
16608                    NT++;
16609                } else {
16610                    // Skip to the next ResolveInfo in the final list.
16611                    it++;
16612                    curt = null;
16613                }
16614            }
16615        }
16616        while (ir < NR) {
16617            if (receivers == null) {
16618                receivers = new ArrayList();
16619            }
16620            receivers.add(registeredReceivers.get(ir));
16621            ir++;
16622        }
16623
16624        if ((receivers != null && receivers.size() > 0)
16625                || resultTo != null) {
16626            BroadcastQueue queue = broadcastQueueForIntent(intent);
16627            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16628                    callerPackage, callingPid, callingUid, resolvedType,
16629                    requiredPermission, appOp, receivers, resultTo, resultCode,
16630                    resultData, map, ordered, sticky, false, userId);
16631
16632            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
16633                    + ": prev had " + queue.mOrderedBroadcasts.size());
16634            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
16635                    "Enqueueing broadcast " + r.intent.getAction());
16636
16637            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16638            if (!replaced) {
16639                queue.enqueueOrderedBroadcastLocked(r);
16640                queue.scheduleBroadcastsLocked();
16641            }
16642        }
16643
16644        return ActivityManager.BROADCAST_SUCCESS;
16645    }
16646
16647    final Intent verifyBroadcastLocked(Intent intent) {
16648        // Refuse possible leaked file descriptors
16649        if (intent != null && intent.hasFileDescriptors() == true) {
16650            throw new IllegalArgumentException("File descriptors passed in Intent");
16651        }
16652
16653        int flags = intent.getFlags();
16654
16655        if (!mProcessesReady) {
16656            // if the caller really truly claims to know what they're doing, go
16657            // ahead and allow the broadcast without launching any receivers
16658            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16659                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
16660            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16661                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16662                        + " before boot completion");
16663                throw new IllegalStateException("Cannot broadcast before boot completed");
16664            }
16665        }
16666
16667        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16668            throw new IllegalArgumentException(
16669                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16670        }
16671
16672        return intent;
16673    }
16674
16675    public final int broadcastIntent(IApplicationThread caller,
16676            Intent intent, String resolvedType, IIntentReceiver resultTo,
16677            int resultCode, String resultData, Bundle map,
16678            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16679        enforceNotIsolatedCaller("broadcastIntent");
16680        synchronized(this) {
16681            intent = verifyBroadcastLocked(intent);
16682
16683            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16684            final int callingPid = Binder.getCallingPid();
16685            final int callingUid = Binder.getCallingUid();
16686            final long origId = Binder.clearCallingIdentity();
16687            int res = broadcastIntentLocked(callerApp,
16688                    callerApp != null ? callerApp.info.packageName : null,
16689                    intent, resolvedType, resultTo,
16690                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16691                    callingPid, callingUid, userId);
16692            Binder.restoreCallingIdentity(origId);
16693            return res;
16694        }
16695    }
16696
16697    int broadcastIntentInPackage(String packageName, int uid,
16698            Intent intent, String resolvedType, IIntentReceiver resultTo,
16699            int resultCode, String resultData, Bundle map,
16700            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16701        synchronized(this) {
16702            intent = verifyBroadcastLocked(intent);
16703
16704            final long origId = Binder.clearCallingIdentity();
16705            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16706                    resultTo, resultCode, resultData, map, requiredPermission,
16707                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16708            Binder.restoreCallingIdentity(origId);
16709            return res;
16710        }
16711    }
16712
16713    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16714        // Refuse possible leaked file descriptors
16715        if (intent != null && intent.hasFileDescriptors() == true) {
16716            throw new IllegalArgumentException("File descriptors passed in Intent");
16717        }
16718
16719        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16720                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16721
16722        synchronized(this) {
16723            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16724                    != PackageManager.PERMISSION_GRANTED) {
16725                String msg = "Permission Denial: unbroadcastIntent() from pid="
16726                        + Binder.getCallingPid()
16727                        + ", uid=" + Binder.getCallingUid()
16728                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16729                Slog.w(TAG, msg);
16730                throw new SecurityException(msg);
16731            }
16732            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16733            if (stickies != null) {
16734                ArrayList<Intent> list = stickies.get(intent.getAction());
16735                if (list != null) {
16736                    int N = list.size();
16737                    int i;
16738                    for (i=0; i<N; i++) {
16739                        if (intent.filterEquals(list.get(i))) {
16740                            list.remove(i);
16741                            break;
16742                        }
16743                    }
16744                    if (list.size() <= 0) {
16745                        stickies.remove(intent.getAction());
16746                    }
16747                }
16748                if (stickies.size() <= 0) {
16749                    mStickyBroadcasts.remove(userId);
16750                }
16751            }
16752        }
16753    }
16754
16755    void backgroundServicesFinishedLocked(int userId) {
16756        for (BroadcastQueue queue : mBroadcastQueues) {
16757            queue.backgroundServicesFinishedLocked(userId);
16758        }
16759    }
16760
16761    public void finishReceiver(IBinder who, int resultCode, String resultData,
16762            Bundle resultExtras, boolean resultAbort, int flags) {
16763        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
16764
16765        // Refuse possible leaked file descriptors
16766        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16767            throw new IllegalArgumentException("File descriptors passed in Bundle");
16768        }
16769
16770        final long origId = Binder.clearCallingIdentity();
16771        try {
16772            boolean doNext = false;
16773            BroadcastRecord r;
16774
16775            synchronized(this) {
16776                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
16777                        ? mFgBroadcastQueue : mBgBroadcastQueue;
16778                r = queue.getMatchingOrderedReceiver(who);
16779                if (r != null) {
16780                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16781                        resultData, resultExtras, resultAbort, true);
16782                }
16783            }
16784
16785            if (doNext) {
16786                r.queue.processNextBroadcast(false);
16787            }
16788            trimApplications();
16789        } finally {
16790            Binder.restoreCallingIdentity(origId);
16791        }
16792    }
16793
16794    // =========================================================
16795    // INSTRUMENTATION
16796    // =========================================================
16797
16798    public boolean startInstrumentation(ComponentName className,
16799            String profileFile, int flags, Bundle arguments,
16800            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16801            int userId, String abiOverride) {
16802        enforceNotIsolatedCaller("startInstrumentation");
16803        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16804                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16805        // Refuse possible leaked file descriptors
16806        if (arguments != null && arguments.hasFileDescriptors()) {
16807            throw new IllegalArgumentException("File descriptors passed in Bundle");
16808        }
16809
16810        synchronized(this) {
16811            InstrumentationInfo ii = null;
16812            ApplicationInfo ai = null;
16813            try {
16814                ii = mContext.getPackageManager().getInstrumentationInfo(
16815                    className, STOCK_PM_FLAGS);
16816                ai = AppGlobals.getPackageManager().getApplicationInfo(
16817                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16818            } catch (PackageManager.NameNotFoundException e) {
16819            } catch (RemoteException e) {
16820            }
16821            if (ii == null) {
16822                reportStartInstrumentationFailure(watcher, className,
16823                        "Unable to find instrumentation info for: " + className);
16824                return false;
16825            }
16826            if (ai == null) {
16827                reportStartInstrumentationFailure(watcher, className,
16828                        "Unable to find instrumentation target package: " + ii.targetPackage);
16829                return false;
16830            }
16831
16832            int match = mContext.getPackageManager().checkSignatures(
16833                    ii.targetPackage, ii.packageName);
16834            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16835                String msg = "Permission Denial: starting instrumentation "
16836                        + className + " from pid="
16837                        + Binder.getCallingPid()
16838                        + ", uid=" + Binder.getCallingPid()
16839                        + " not allowed because package " + ii.packageName
16840                        + " does not have a signature matching the target "
16841                        + ii.targetPackage;
16842                reportStartInstrumentationFailure(watcher, className, msg);
16843                throw new SecurityException(msg);
16844            }
16845
16846            final long origId = Binder.clearCallingIdentity();
16847            // Instrumentation can kill and relaunch even persistent processes
16848            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16849                    "start instr");
16850            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16851            app.instrumentationClass = className;
16852            app.instrumentationInfo = ai;
16853            app.instrumentationProfileFile = profileFile;
16854            app.instrumentationArguments = arguments;
16855            app.instrumentationWatcher = watcher;
16856            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16857            app.instrumentationResultClass = className;
16858            Binder.restoreCallingIdentity(origId);
16859        }
16860
16861        return true;
16862    }
16863
16864    /**
16865     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16866     * error to the logs, but if somebody is watching, send the report there too.  This enables
16867     * the "am" command to report errors with more information.
16868     *
16869     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16870     * @param cn The component name of the instrumentation.
16871     * @param report The error report.
16872     */
16873    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16874            ComponentName cn, String report) {
16875        Slog.w(TAG, report);
16876        try {
16877            if (watcher != null) {
16878                Bundle results = new Bundle();
16879                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16880                results.putString("Error", report);
16881                watcher.instrumentationStatus(cn, -1, results);
16882            }
16883        } catch (RemoteException e) {
16884            Slog.w(TAG, e);
16885        }
16886    }
16887
16888    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16889        if (app.instrumentationWatcher != null) {
16890            try {
16891                // NOTE:  IInstrumentationWatcher *must* be oneway here
16892                app.instrumentationWatcher.instrumentationFinished(
16893                    app.instrumentationClass,
16894                    resultCode,
16895                    results);
16896            } catch (RemoteException e) {
16897            }
16898        }
16899        if (app.instrumentationUiAutomationConnection != null) {
16900            try {
16901                app.instrumentationUiAutomationConnection.shutdown();
16902            } catch (RemoteException re) {
16903                /* ignore */
16904            }
16905            // Only a UiAutomation can set this flag and now that
16906            // it is finished we make sure it is reset to its default.
16907            mUserIsMonkey = false;
16908        }
16909        app.instrumentationWatcher = null;
16910        app.instrumentationUiAutomationConnection = null;
16911        app.instrumentationClass = null;
16912        app.instrumentationInfo = null;
16913        app.instrumentationProfileFile = null;
16914        app.instrumentationArguments = null;
16915
16916        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16917                "finished inst");
16918    }
16919
16920    public void finishInstrumentation(IApplicationThread target,
16921            int resultCode, Bundle results) {
16922        int userId = UserHandle.getCallingUserId();
16923        // Refuse possible leaked file descriptors
16924        if (results != null && results.hasFileDescriptors()) {
16925            throw new IllegalArgumentException("File descriptors passed in Intent");
16926        }
16927
16928        synchronized(this) {
16929            ProcessRecord app = getRecordForAppLocked(target);
16930            if (app == null) {
16931                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16932                return;
16933            }
16934            final long origId = Binder.clearCallingIdentity();
16935            finishInstrumentationLocked(app, resultCode, results);
16936            Binder.restoreCallingIdentity(origId);
16937        }
16938    }
16939
16940    // =========================================================
16941    // CONFIGURATION
16942    // =========================================================
16943
16944    public ConfigurationInfo getDeviceConfigurationInfo() {
16945        ConfigurationInfo config = new ConfigurationInfo();
16946        synchronized (this) {
16947            config.reqTouchScreen = mConfiguration.touchscreen;
16948            config.reqKeyboardType = mConfiguration.keyboard;
16949            config.reqNavigation = mConfiguration.navigation;
16950            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16951                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16952                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16953            }
16954            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16955                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16956                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16957            }
16958            config.reqGlEsVersion = GL_ES_VERSION;
16959        }
16960        return config;
16961    }
16962
16963    ActivityStack getFocusedStack() {
16964        return mStackSupervisor.getFocusedStack();
16965    }
16966
16967    @Override
16968    public int getFocusedStackId() throws RemoteException {
16969        ActivityStack focusedStack = getFocusedStack();
16970        if (focusedStack != null) {
16971            return focusedStack.getStackId();
16972        }
16973        return -1;
16974    }
16975
16976    public Configuration getConfiguration() {
16977        Configuration ci;
16978        synchronized(this) {
16979            ci = new Configuration(mConfiguration);
16980            ci.userSetLocale = false;
16981        }
16982        return ci;
16983    }
16984
16985    @Override
16986    public void updatePersistentConfiguration(Configuration values) {
16987        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16988                "updateConfiguration()");
16989        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16990                "updateConfiguration()");
16991        if (values == null) {
16992            throw new NullPointerException("Configuration must not be null");
16993        }
16994
16995        int userId = UserHandle.getCallingUserId();
16996
16997        synchronized(this) {
16998            final long origId = Binder.clearCallingIdentity();
16999            updateConfigurationLocked(values, null, false, true, userId);
17000            Binder.restoreCallingIdentity(origId);
17001        }
17002    }
17003
17004    public void updateConfiguration(Configuration values) {
17005        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17006                "updateConfiguration()");
17007
17008        synchronized(this) {
17009            if (values == null && mWindowManager != null) {
17010                // sentinel: fetch the current configuration from the window manager
17011                values = mWindowManager.computeNewConfiguration();
17012            }
17013
17014            if (mWindowManager != null) {
17015                mProcessList.applyDisplaySize(mWindowManager);
17016            }
17017
17018            final long origId = Binder.clearCallingIdentity();
17019            if (values != null) {
17020                Settings.System.clearConfiguration(values);
17021            }
17022            updateConfigurationLocked(values, null, false);
17023            Binder.restoreCallingIdentity(origId);
17024        }
17025    }
17026
17027    boolean updateConfigurationLocked(Configuration values,
17028            ActivityRecord starting, boolean initLocale) {
17029        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
17030        return updateConfigurationLocked(values, starting, initLocale, false,
17031                UserHandle.USER_NULL);
17032    }
17033
17034    /**
17035     * Do either or both things: (1) change the current configuration, and (2)
17036     * make sure the given activity is running with the (now) current
17037     * configuration.  Returns true if the activity has been left running, or
17038     * false if <var>starting</var> is being destroyed to match the new
17039     * configuration.
17040     *
17041     * @param userId is only used when persistent parameter is set to true to persist configuration
17042     *               for that particular user
17043     */
17044    boolean updateConfigurationLocked(Configuration values,
17045            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
17046        int changes = 0;
17047
17048        if (values != null) {
17049            Configuration newConfig = new Configuration(mConfiguration);
17050            changes = newConfig.updateFrom(values);
17051            if (changes != 0) {
17052                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
17053                        "Updating configuration to: " + values);
17054
17055                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
17056
17057                if (!initLocale && values.locale != null && values.userSetLocale) {
17058                    final String languageTag = values.locale.toLanguageTag();
17059                    SystemProperties.set("persist.sys.locale", languageTag);
17060                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
17061                            values.locale));
17062                }
17063
17064                mConfigurationSeq++;
17065                if (mConfigurationSeq <= 0) {
17066                    mConfigurationSeq = 1;
17067                }
17068                newConfig.seq = mConfigurationSeq;
17069                mConfiguration = newConfig;
17070                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
17071                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
17072                //mUsageStatsService.noteStartConfig(newConfig);
17073
17074                final Configuration configCopy = new Configuration(mConfiguration);
17075
17076                // TODO: If our config changes, should we auto dismiss any currently
17077                // showing dialogs?
17078                mShowDialogs = shouldShowDialogs(newConfig);
17079
17080                AttributeCache ac = AttributeCache.instance();
17081                if (ac != null) {
17082                    ac.updateConfiguration(configCopy);
17083                }
17084
17085                // Make sure all resources in our process are updated
17086                // right now, so that anyone who is going to retrieve
17087                // resource values after we return will be sure to get
17088                // the new ones.  This is especially important during
17089                // boot, where the first config change needs to guarantee
17090                // all resources have that config before following boot
17091                // code is executed.
17092                mSystemThread.applyConfigurationToResources(configCopy);
17093
17094                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
17095                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
17096                    msg.obj = new Configuration(configCopy);
17097                    msg.arg1 = userId;
17098                    mHandler.sendMessage(msg);
17099                }
17100
17101                for (int i=mLruProcesses.size()-1; i>=0; i--) {
17102                    ProcessRecord app = mLruProcesses.get(i);
17103                    try {
17104                        if (app.thread != null) {
17105                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
17106                                    + app.processName + " new config " + mConfiguration);
17107                            app.thread.scheduleConfigurationChanged(configCopy);
17108                        }
17109                    } catch (Exception e) {
17110                    }
17111                }
17112                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
17113                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17114                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
17115                        | Intent.FLAG_RECEIVER_FOREGROUND);
17116                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
17117                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
17118                        Process.SYSTEM_UID, UserHandle.USER_ALL);
17119                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
17120                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
17121                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17122                    if (!mProcessesReady) {
17123                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17124                    }
17125                    broadcastIntentLocked(null, null, intent,
17126                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17127                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17128                }
17129            }
17130        }
17131
17132        boolean kept = true;
17133        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
17134        // mainStack is null during startup.
17135        if (mainStack != null) {
17136            if (changes != 0 && starting == null) {
17137                // If the configuration changed, and the caller is not already
17138                // in the process of starting an activity, then find the top
17139                // activity to check if its configuration needs to change.
17140                starting = mainStack.topRunningActivityLocked(null);
17141            }
17142
17143            if (starting != null) {
17144                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
17145                // And we need to make sure at this point that all other activities
17146                // are made visible with the correct configuration.
17147                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
17148            }
17149        }
17150
17151        if (values != null && mWindowManager != null) {
17152            mWindowManager.setNewConfiguration(mConfiguration);
17153        }
17154
17155        return kept;
17156    }
17157
17158    /**
17159     * Decide based on the configuration whether we should shouw the ANR,
17160     * crash, etc dialogs.  The idea is that if there is no affordnace to
17161     * press the on-screen buttons, we shouldn't show the dialog.
17162     *
17163     * A thought: SystemUI might also want to get told about this, the Power
17164     * dialog / global actions also might want different behaviors.
17165     */
17166    private static final boolean shouldShowDialogs(Configuration config) {
17167        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
17168                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
17169                && config.navigation == Configuration.NAVIGATION_NONAV);
17170    }
17171
17172    @Override
17173    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
17174        synchronized (this) {
17175            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
17176            if (srec != null) {
17177                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
17178            }
17179        }
17180        return false;
17181    }
17182
17183    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
17184            Intent resultData) {
17185
17186        synchronized (this) {
17187            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
17188            if (r != null) {
17189                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
17190            }
17191            return false;
17192        }
17193    }
17194
17195    public int getLaunchedFromUid(IBinder activityToken) {
17196        ActivityRecord srec;
17197        synchronized (this) {
17198            srec = ActivityRecord.forTokenLocked(activityToken);
17199        }
17200        if (srec == null) {
17201            return -1;
17202        }
17203        return srec.launchedFromUid;
17204    }
17205
17206    public String getLaunchedFromPackage(IBinder activityToken) {
17207        ActivityRecord srec;
17208        synchronized (this) {
17209            srec = ActivityRecord.forTokenLocked(activityToken);
17210        }
17211        if (srec == null) {
17212            return null;
17213        }
17214        return srec.launchedFromPackage;
17215    }
17216
17217    // =========================================================
17218    // LIFETIME MANAGEMENT
17219    // =========================================================
17220
17221    // Returns which broadcast queue the app is the current [or imminent] receiver
17222    // on, or 'null' if the app is not an active broadcast recipient.
17223    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
17224        BroadcastRecord r = app.curReceiver;
17225        if (r != null) {
17226            return r.queue;
17227        }
17228
17229        // It's not the current receiver, but it might be starting up to become one
17230        synchronized (this) {
17231            for (BroadcastQueue queue : mBroadcastQueues) {
17232                r = queue.mPendingBroadcast;
17233                if (r != null && r.curApp == app) {
17234                    // found it; report which queue it's in
17235                    return queue;
17236                }
17237            }
17238        }
17239
17240        return null;
17241    }
17242
17243    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17244            ComponentName targetComponent, String targetProcess) {
17245        if (!mTrackingAssociations) {
17246            return null;
17247        }
17248        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17249                = mAssociations.get(targetUid);
17250        if (components == null) {
17251            components = new ArrayMap<>();
17252            mAssociations.put(targetUid, components);
17253        }
17254        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17255        if (sourceUids == null) {
17256            sourceUids = new SparseArray<>();
17257            components.put(targetComponent, sourceUids);
17258        }
17259        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17260        if (sourceProcesses == null) {
17261            sourceProcesses = new ArrayMap<>();
17262            sourceUids.put(sourceUid, sourceProcesses);
17263        }
17264        Association ass = sourceProcesses.get(sourceProcess);
17265        if (ass == null) {
17266            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
17267                    targetProcess);
17268            sourceProcesses.put(sourceProcess, ass);
17269        }
17270        ass.mCount++;
17271        ass.mNesting++;
17272        if (ass.mNesting == 1) {
17273            ass.mStartTime = SystemClock.uptimeMillis();
17274        }
17275        return ass;
17276    }
17277
17278    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17279            ComponentName targetComponent) {
17280        if (!mTrackingAssociations) {
17281            return;
17282        }
17283        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17284                = mAssociations.get(targetUid);
17285        if (components == null) {
17286            return;
17287        }
17288        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17289        if (sourceUids == null) {
17290            return;
17291        }
17292        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17293        if (sourceProcesses == null) {
17294            return;
17295        }
17296        Association ass = sourceProcesses.get(sourceProcess);
17297        if (ass == null || ass.mNesting <= 0) {
17298            return;
17299        }
17300        ass.mNesting--;
17301        if (ass.mNesting == 0) {
17302            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
17303        }
17304    }
17305
17306    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
17307            boolean doingAll, long now) {
17308        if (mAdjSeq == app.adjSeq) {
17309            // This adjustment has already been computed.
17310            return app.curRawAdj;
17311        }
17312
17313        if (app.thread == null) {
17314            app.adjSeq = mAdjSeq;
17315            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17316            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17317            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
17318        }
17319
17320        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
17321        app.adjSource = null;
17322        app.adjTarget = null;
17323        app.empty = false;
17324        app.cached = false;
17325
17326        final int activitiesSize = app.activities.size();
17327
17328        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17329            // The max adjustment doesn't allow this app to be anything
17330            // below foreground, so it is not worth doing work for it.
17331            app.adjType = "fixed";
17332            app.adjSeq = mAdjSeq;
17333            app.curRawAdj = app.maxAdj;
17334            app.foregroundActivities = false;
17335            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
17336            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
17337            // System processes can do UI, and when they do we want to have
17338            // them trim their memory after the user leaves the UI.  To
17339            // facilitate this, here we need to determine whether or not it
17340            // is currently showing UI.
17341            app.systemNoUi = true;
17342            if (app == TOP_APP) {
17343                app.systemNoUi = false;
17344            } else if (activitiesSize > 0) {
17345                for (int j = 0; j < activitiesSize; j++) {
17346                    final ActivityRecord r = app.activities.get(j);
17347                    if (r.visible) {
17348                        app.systemNoUi = false;
17349                    }
17350                }
17351            }
17352            if (!app.systemNoUi) {
17353                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
17354            }
17355            return (app.curAdj=app.maxAdj);
17356        }
17357
17358        app.systemNoUi = false;
17359
17360        final int PROCESS_STATE_TOP = mTopProcessState;
17361
17362        // Determine the importance of the process, starting with most
17363        // important to least, and assign an appropriate OOM adjustment.
17364        int adj;
17365        int schedGroup;
17366        int procState;
17367        boolean foregroundActivities = false;
17368        BroadcastQueue queue;
17369        if (app == TOP_APP) {
17370            // The last app on the list is the foreground app.
17371            adj = ProcessList.FOREGROUND_APP_ADJ;
17372            schedGroup = Process.THREAD_GROUP_DEFAULT;
17373            app.adjType = "top-activity";
17374            foregroundActivities = true;
17375            procState = PROCESS_STATE_TOP;
17376        } else if (app.instrumentationClass != null) {
17377            // Don't want to kill running instrumentation.
17378            adj = ProcessList.FOREGROUND_APP_ADJ;
17379            schedGroup = Process.THREAD_GROUP_DEFAULT;
17380            app.adjType = "instrumentation";
17381            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17382        } else if ((queue = isReceivingBroadcast(app)) != null) {
17383            // An app that is currently receiving a broadcast also
17384            // counts as being in the foreground for OOM killer purposes.
17385            // It's placed in a sched group based on the nature of the
17386            // broadcast as reflected by which queue it's active in.
17387            adj = ProcessList.FOREGROUND_APP_ADJ;
17388            schedGroup = (queue == mFgBroadcastQueue)
17389                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17390            app.adjType = "broadcast";
17391            procState = ActivityManager.PROCESS_STATE_RECEIVER;
17392        } else if (app.executingServices.size() > 0) {
17393            // An app that is currently executing a service callback also
17394            // counts as being in the foreground.
17395            adj = ProcessList.FOREGROUND_APP_ADJ;
17396            schedGroup = app.execServicesFg ?
17397                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17398            app.adjType = "exec-service";
17399            procState = ActivityManager.PROCESS_STATE_SERVICE;
17400            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
17401        } else {
17402            // As far as we know the process is empty.  We may change our mind later.
17403            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17404            // At this point we don't actually know the adjustment.  Use the cached adj
17405            // value that the caller wants us to.
17406            adj = cachedAdj;
17407            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17408            app.cached = true;
17409            app.empty = true;
17410            app.adjType = "cch-empty";
17411        }
17412
17413        // Examine all activities if not already foreground.
17414        if (!foregroundActivities && activitiesSize > 0) {
17415            for (int j = 0; j < activitiesSize; j++) {
17416                final ActivityRecord r = app.activities.get(j);
17417                if (r.app != app) {
17418                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
17419                            + app + "?!? Using " + r.app + " instead.");
17420                    continue;
17421                }
17422                if (r.visible) {
17423                    // App has a visible activity; only upgrade adjustment.
17424                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17425                        adj = ProcessList.VISIBLE_APP_ADJ;
17426                        app.adjType = "visible";
17427                    }
17428                    if (procState > PROCESS_STATE_TOP) {
17429                        procState = PROCESS_STATE_TOP;
17430                    }
17431                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17432                    app.cached = false;
17433                    app.empty = false;
17434                    foregroundActivities = true;
17435                    break;
17436                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
17437                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17438                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17439                        app.adjType = "pausing";
17440                    }
17441                    if (procState > PROCESS_STATE_TOP) {
17442                        procState = PROCESS_STATE_TOP;
17443                    }
17444                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17445                    app.cached = false;
17446                    app.empty = false;
17447                    foregroundActivities = true;
17448                } else if (r.state == ActivityState.STOPPING) {
17449                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17450                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17451                        app.adjType = "stopping";
17452                    }
17453                    // For the process state, we will at this point consider the
17454                    // process to be cached.  It will be cached either as an activity
17455                    // or empty depending on whether the activity is finishing.  We do
17456                    // this so that we can treat the process as cached for purposes of
17457                    // memory trimming (determing current memory level, trim command to
17458                    // send to process) since there can be an arbitrary number of stopping
17459                    // processes and they should soon all go into the cached state.
17460                    if (!r.finishing) {
17461                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17462                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17463                        }
17464                    }
17465                    app.cached = false;
17466                    app.empty = false;
17467                    foregroundActivities = true;
17468                } else {
17469                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17470                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17471                        app.adjType = "cch-act";
17472                    }
17473                }
17474            }
17475        }
17476
17477        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17478            if (app.foregroundServices) {
17479                // The user is aware of this app, so make it visible.
17480                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17481                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17482                app.cached = false;
17483                app.adjType = "fg-service";
17484                schedGroup = Process.THREAD_GROUP_DEFAULT;
17485            } else if (app.forcingToForeground != null) {
17486                // The user is aware of this app, so make it visible.
17487                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17488                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17489                app.cached = false;
17490                app.adjType = "force-fg";
17491                app.adjSource = app.forcingToForeground;
17492                schedGroup = Process.THREAD_GROUP_DEFAULT;
17493            }
17494        }
17495
17496        if (app == mHeavyWeightProcess) {
17497            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
17498                // We don't want to kill the current heavy-weight process.
17499                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
17500                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17501                app.cached = false;
17502                app.adjType = "heavy";
17503            }
17504            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17505                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
17506            }
17507        }
17508
17509        if (app == mHomeProcess) {
17510            if (adj > ProcessList.HOME_APP_ADJ) {
17511                // This process is hosting what we currently consider to be the
17512                // home app, so we don't want to let it go into the background.
17513                adj = ProcessList.HOME_APP_ADJ;
17514                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17515                app.cached = false;
17516                app.adjType = "home";
17517            }
17518            if (procState > ActivityManager.PROCESS_STATE_HOME) {
17519                procState = ActivityManager.PROCESS_STATE_HOME;
17520            }
17521        }
17522
17523        if (app == mPreviousProcess && app.activities.size() > 0) {
17524            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
17525                // This was the previous process that showed UI to the user.
17526                // We want to try to keep it around more aggressively, to give
17527                // a good experience around switching between two apps.
17528                adj = ProcessList.PREVIOUS_APP_ADJ;
17529                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17530                app.cached = false;
17531                app.adjType = "previous";
17532            }
17533            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17534                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17535            }
17536        }
17537
17538        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
17539                + " reason=" + app.adjType);
17540
17541        // By default, we use the computed adjustment.  It may be changed if
17542        // there are applications dependent on our services or providers, but
17543        // this gives us a baseline and makes sure we don't get into an
17544        // infinite recursion.
17545        app.adjSeq = mAdjSeq;
17546        app.curRawAdj = adj;
17547        app.hasStartedServices = false;
17548
17549        if (mBackupTarget != null && app == mBackupTarget.app) {
17550            // If possible we want to avoid killing apps while they're being backed up
17551            if (adj > ProcessList.BACKUP_APP_ADJ) {
17552                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
17553                adj = ProcessList.BACKUP_APP_ADJ;
17554                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17555                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17556                }
17557                app.adjType = "backup";
17558                app.cached = false;
17559            }
17560            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
17561                procState = ActivityManager.PROCESS_STATE_BACKUP;
17562            }
17563        }
17564
17565        boolean mayBeTop = false;
17566
17567        for (int is = app.services.size()-1;
17568                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17569                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17570                        || procState > ActivityManager.PROCESS_STATE_TOP);
17571                is--) {
17572            ServiceRecord s = app.services.valueAt(is);
17573            if (s.startRequested) {
17574                app.hasStartedServices = true;
17575                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
17576                    procState = ActivityManager.PROCESS_STATE_SERVICE;
17577                }
17578                if (app.hasShownUi && app != mHomeProcess) {
17579                    // If this process has shown some UI, let it immediately
17580                    // go to the LRU list because it may be pretty heavy with
17581                    // UI stuff.  We'll tag it with a label just to help
17582                    // debug and understand what is going on.
17583                    if (adj > ProcessList.SERVICE_ADJ) {
17584                        app.adjType = "cch-started-ui-services";
17585                    }
17586                } else {
17587                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17588                        // This service has seen some activity within
17589                        // recent memory, so we will keep its process ahead
17590                        // of the background processes.
17591                        if (adj > ProcessList.SERVICE_ADJ) {
17592                            adj = ProcessList.SERVICE_ADJ;
17593                            app.adjType = "started-services";
17594                            app.cached = false;
17595                        }
17596                    }
17597                    // If we have let the service slide into the background
17598                    // state, still have some text describing what it is doing
17599                    // even though the service no longer has an impact.
17600                    if (adj > ProcessList.SERVICE_ADJ) {
17601                        app.adjType = "cch-started-services";
17602                    }
17603                }
17604            }
17605            for (int conni = s.connections.size()-1;
17606                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17607                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17608                            || procState > ActivityManager.PROCESS_STATE_TOP);
17609                    conni--) {
17610                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17611                for (int i = 0;
17612                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17613                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17614                                || procState > ActivityManager.PROCESS_STATE_TOP);
17615                        i++) {
17616                    // XXX should compute this based on the max of
17617                    // all connected clients.
17618                    ConnectionRecord cr = clist.get(i);
17619                    if (cr.binding.client == app) {
17620                        // Binding to ourself is not interesting.
17621                        continue;
17622                    }
17623                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17624                        ProcessRecord client = cr.binding.client;
17625                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
17626                                TOP_APP, doingAll, now);
17627                        int clientProcState = client.curProcState;
17628                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17629                            // If the other app is cached for any reason, for purposes here
17630                            // we are going to consider it empty.  The specific cached state
17631                            // doesn't propagate except under certain conditions.
17632                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17633                        }
17634                        String adjType = null;
17635                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17636                            // Not doing bind OOM management, so treat
17637                            // this guy more like a started service.
17638                            if (app.hasShownUi && app != mHomeProcess) {
17639                                // If this process has shown some UI, let it immediately
17640                                // go to the LRU list because it may be pretty heavy with
17641                                // UI stuff.  We'll tag it with a label just to help
17642                                // debug and understand what is going on.
17643                                if (adj > clientAdj) {
17644                                    adjType = "cch-bound-ui-services";
17645                                }
17646                                app.cached = false;
17647                                clientAdj = adj;
17648                                clientProcState = procState;
17649                            } else {
17650                                if (now >= (s.lastActivity
17651                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17652                                    // This service has not seen activity within
17653                                    // recent memory, so allow it to drop to the
17654                                    // LRU list if there is no other reason to keep
17655                                    // it around.  We'll also tag it with a label just
17656                                    // to help debug and undertand what is going on.
17657                                    if (adj > clientAdj) {
17658                                        adjType = "cch-bound-services";
17659                                    }
17660                                    clientAdj = adj;
17661                                }
17662                            }
17663                        }
17664                        if (adj > clientAdj) {
17665                            // If this process has recently shown UI, and
17666                            // the process that is binding to it is less
17667                            // important than being visible, then we don't
17668                            // care about the binding as much as we care
17669                            // about letting this process get into the LRU
17670                            // list to be killed and restarted if needed for
17671                            // memory.
17672                            if (app.hasShownUi && app != mHomeProcess
17673                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17674                                adjType = "cch-bound-ui-services";
17675                            } else {
17676                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17677                                        |Context.BIND_IMPORTANT)) != 0) {
17678                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17679                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17680                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17681                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17682                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17683                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17684                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17685                                    adj = clientAdj;
17686                                } else {
17687                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17688                                        adj = ProcessList.VISIBLE_APP_ADJ;
17689                                    }
17690                                }
17691                                if (!client.cached) {
17692                                    app.cached = false;
17693                                }
17694                                adjType = "service";
17695                            }
17696                        }
17697                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17698                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17699                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17700                            }
17701                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17702                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17703                                    // Special handling of clients who are in the top state.
17704                                    // We *may* want to consider this process to be in the
17705                                    // top state as well, but only if there is not another
17706                                    // reason for it to be running.  Being on the top is a
17707                                    // special state, meaning you are specifically running
17708                                    // for the current top app.  If the process is already
17709                                    // running in the background for some other reason, it
17710                                    // is more important to continue considering it to be
17711                                    // in the background state.
17712                                    mayBeTop = true;
17713                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17714                                } else {
17715                                    // Special handling for above-top states (persistent
17716                                    // processes).  These should not bring the current process
17717                                    // into the top state, since they are not on top.  Instead
17718                                    // give them the best state after that.
17719                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
17720                                        clientProcState =
17721                                                ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17722                                    } else if (mWakefulness
17723                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
17724                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
17725                                                    != 0) {
17726                                        clientProcState =
17727                                                ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17728                                    } else {
17729                                        clientProcState =
17730                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17731                                    }
17732                                }
17733                            }
17734                        } else {
17735                            if (clientProcState <
17736                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17737                                clientProcState =
17738                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17739                            }
17740                        }
17741                        if (procState > clientProcState) {
17742                            procState = clientProcState;
17743                        }
17744                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17745                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17746                            app.pendingUiClean = true;
17747                        }
17748                        if (adjType != null) {
17749                            app.adjType = adjType;
17750                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17751                                    .REASON_SERVICE_IN_USE;
17752                            app.adjSource = cr.binding.client;
17753                            app.adjSourceProcState = clientProcState;
17754                            app.adjTarget = s.name;
17755                        }
17756                    }
17757                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17758                        app.treatLikeActivity = true;
17759                    }
17760                    final ActivityRecord a = cr.activity;
17761                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17762                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17763                                (a.visible || a.state == ActivityState.RESUMED
17764                                 || a.state == ActivityState.PAUSING)) {
17765                            adj = ProcessList.FOREGROUND_APP_ADJ;
17766                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17767                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17768                            }
17769                            app.cached = false;
17770                            app.adjType = "service";
17771                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17772                                    .REASON_SERVICE_IN_USE;
17773                            app.adjSource = a;
17774                            app.adjSourceProcState = procState;
17775                            app.adjTarget = s.name;
17776                        }
17777                    }
17778                }
17779            }
17780        }
17781
17782        for (int provi = app.pubProviders.size()-1;
17783                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17784                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17785                        || procState > ActivityManager.PROCESS_STATE_TOP);
17786                provi--) {
17787            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17788            for (int i = cpr.connections.size()-1;
17789                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17790                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17791                            || procState > ActivityManager.PROCESS_STATE_TOP);
17792                    i--) {
17793                ContentProviderConnection conn = cpr.connections.get(i);
17794                ProcessRecord client = conn.client;
17795                if (client == app) {
17796                    // Being our own client is not interesting.
17797                    continue;
17798                }
17799                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17800                int clientProcState = client.curProcState;
17801                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17802                    // If the other app is cached for any reason, for purposes here
17803                    // we are going to consider it empty.
17804                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17805                }
17806                if (adj > clientAdj) {
17807                    if (app.hasShownUi && app != mHomeProcess
17808                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17809                        app.adjType = "cch-ui-provider";
17810                    } else {
17811                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17812                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17813                        app.adjType = "provider";
17814                    }
17815                    app.cached &= client.cached;
17816                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17817                            .REASON_PROVIDER_IN_USE;
17818                    app.adjSource = client;
17819                    app.adjSourceProcState = clientProcState;
17820                    app.adjTarget = cpr.name;
17821                }
17822                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17823                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17824                        // Special handling of clients who are in the top state.
17825                        // We *may* want to consider this process to be in the
17826                        // top state as well, but only if there is not another
17827                        // reason for it to be running.  Being on the top is a
17828                        // special state, meaning you are specifically running
17829                        // for the current top app.  If the process is already
17830                        // running in the background for some other reason, it
17831                        // is more important to continue considering it to be
17832                        // in the background state.
17833                        mayBeTop = true;
17834                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17835                    } else {
17836                        // Special handling for above-top states (persistent
17837                        // processes).  These should not bring the current process
17838                        // into the top state, since they are not on top.  Instead
17839                        // give them the best state after that.
17840                        clientProcState =
17841                                ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17842                    }
17843                }
17844                if (procState > clientProcState) {
17845                    procState = clientProcState;
17846                }
17847                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17848                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17849                }
17850            }
17851            // If the provider has external (non-framework) process
17852            // dependencies, ensure that its adjustment is at least
17853            // FOREGROUND_APP_ADJ.
17854            if (cpr.hasExternalProcessHandles()) {
17855                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17856                    adj = ProcessList.FOREGROUND_APP_ADJ;
17857                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17858                    app.cached = false;
17859                    app.adjType = "provider";
17860                    app.adjTarget = cpr.name;
17861                }
17862                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17863                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17864                }
17865            }
17866        }
17867
17868        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17869            // A client of one of our services or providers is in the top state.  We
17870            // *may* want to be in the top state, but not if we are already running in
17871            // the background for some other reason.  For the decision here, we are going
17872            // to pick out a few specific states that we want to remain in when a client
17873            // is top (states that tend to be longer-term) and otherwise allow it to go
17874            // to the top state.
17875            switch (procState) {
17876                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17877                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17878                case ActivityManager.PROCESS_STATE_SERVICE:
17879                    // These all are longer-term states, so pull them up to the top
17880                    // of the background states, but not all the way to the top state.
17881                    procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17882                    break;
17883                default:
17884                    // Otherwise, top is a better choice, so take it.
17885                    procState = ActivityManager.PROCESS_STATE_TOP;
17886                    break;
17887            }
17888        }
17889
17890        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17891            if (app.hasClientActivities) {
17892                // This is a cached process, but with client activities.  Mark it so.
17893                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17894                app.adjType = "cch-client-act";
17895            } else if (app.treatLikeActivity) {
17896                // This is a cached process, but somebody wants us to treat it like it has
17897                // an activity, okay!
17898                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17899                app.adjType = "cch-as-act";
17900            }
17901        }
17902
17903        if (adj == ProcessList.SERVICE_ADJ) {
17904            if (doingAll) {
17905                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17906                mNewNumServiceProcs++;
17907                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17908                if (!app.serviceb) {
17909                    // This service isn't far enough down on the LRU list to
17910                    // normally be a B service, but if we are low on RAM and it
17911                    // is large we want to force it down since we would prefer to
17912                    // keep launcher over it.
17913                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17914                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17915                        app.serviceHighRam = true;
17916                        app.serviceb = true;
17917                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17918                    } else {
17919                        mNewNumAServiceProcs++;
17920                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17921                    }
17922                } else {
17923                    app.serviceHighRam = false;
17924                }
17925            }
17926            if (app.serviceb) {
17927                adj = ProcessList.SERVICE_B_ADJ;
17928            }
17929        }
17930
17931        app.curRawAdj = adj;
17932
17933        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17934        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17935        if (adj > app.maxAdj) {
17936            adj = app.maxAdj;
17937            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17938                schedGroup = Process.THREAD_GROUP_DEFAULT;
17939            }
17940        }
17941
17942        // Do final modification to adj.  Everything we do between here and applying
17943        // the final setAdj must be done in this function, because we will also use
17944        // it when computing the final cached adj later.  Note that we don't need to
17945        // worry about this for max adj above, since max adj will always be used to
17946        // keep it out of the cached vaues.
17947        app.curAdj = app.modifyRawOomAdj(adj);
17948        app.curSchedGroup = schedGroup;
17949        app.curProcState = procState;
17950        app.foregroundActivities = foregroundActivities;
17951
17952        return app.curRawAdj;
17953    }
17954
17955    /**
17956     * Record new PSS sample for a process.
17957     */
17958    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long now) {
17959        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024);
17960        proc.lastPssTime = now;
17961        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
17962        if (DEBUG_PSS) Slog.d(TAG_PSS,
17963                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
17964                + " state=" + ProcessList.makeProcStateString(procState));
17965        if (proc.initialIdlePss == 0) {
17966            proc.initialIdlePss = pss;
17967        }
17968        proc.lastPss = pss;
17969        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
17970            proc.lastCachedPss = pss;
17971        }
17972
17973        final SparseArray<Pair<Long, String>> watchUids
17974                = mMemWatchProcesses.getMap().get(proc.processName);
17975        Long check = null;
17976        if (watchUids != null) {
17977            Pair<Long, String> val = watchUids.get(proc.uid);
17978            if (val == null) {
17979                val = watchUids.get(0);
17980            }
17981            if (val != null) {
17982                check = val.first;
17983            }
17984        }
17985        if (check != null) {
17986            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
17987                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17988                if (!isDebuggable) {
17989                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
17990                        isDebuggable = true;
17991                    }
17992                }
17993                if (isDebuggable) {
17994                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
17995                    final ProcessRecord myProc = proc;
17996                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
17997                    mMemWatchDumpProcName = proc.processName;
17998                    mMemWatchDumpFile = heapdumpFile.toString();
17999                    mMemWatchDumpPid = proc.pid;
18000                    mMemWatchDumpUid = proc.uid;
18001                    BackgroundThread.getHandler().post(new Runnable() {
18002                        @Override
18003                        public void run() {
18004                            revokeUriPermission(ActivityThread.currentActivityThread()
18005                                            .getApplicationThread(),
18006                                    DumpHeapActivity.JAVA_URI,
18007                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
18008                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
18009                                    UserHandle.myUserId());
18010                            ParcelFileDescriptor fd = null;
18011                            try {
18012                                heapdumpFile.delete();
18013                                fd = ParcelFileDescriptor.open(heapdumpFile,
18014                                        ParcelFileDescriptor.MODE_CREATE |
18015                                                ParcelFileDescriptor.MODE_TRUNCATE |
18016                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
18017                                                ParcelFileDescriptor.MODE_APPEND);
18018                                IApplicationThread thread = myProc.thread;
18019                                if (thread != null) {
18020                                    try {
18021                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
18022                                                "Requesting dump heap from "
18023                                                + myProc + " to " + heapdumpFile);
18024                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
18025                                    } catch (RemoteException e) {
18026                                    }
18027                                }
18028                            } catch (FileNotFoundException e) {
18029                                e.printStackTrace();
18030                            } finally {
18031                                if (fd != null) {
18032                                    try {
18033                                        fd.close();
18034                                    } catch (IOException e) {
18035                                    }
18036                                }
18037                            }
18038                        }
18039                    });
18040                } else {
18041                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
18042                            + ", but debugging not enabled");
18043                }
18044            }
18045        }
18046    }
18047
18048    /**
18049     * Schedule PSS collection of a process.
18050     */
18051    void requestPssLocked(ProcessRecord proc, int procState) {
18052        if (mPendingPssProcesses.contains(proc)) {
18053            return;
18054        }
18055        if (mPendingPssProcesses.size() == 0) {
18056            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18057        }
18058        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
18059        proc.pssProcState = procState;
18060        mPendingPssProcesses.add(proc);
18061    }
18062
18063    /**
18064     * Schedule PSS collection of all processes.
18065     */
18066    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
18067        if (!always) {
18068            if (now < (mLastFullPssTime +
18069                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
18070                return;
18071            }
18072        }
18073        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
18074        mLastFullPssTime = now;
18075        mFullPssPending = true;
18076        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
18077        mPendingPssProcesses.clear();
18078        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18079            ProcessRecord app = mLruProcesses.get(i);
18080            if (app.thread == null
18081                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
18082                continue;
18083            }
18084            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
18085                app.pssProcState = app.setProcState;
18086                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18087                        mTestPssMode, isSleeping(), now);
18088                mPendingPssProcesses.add(app);
18089            }
18090        }
18091        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18092    }
18093
18094    public void setTestPssMode(boolean enabled) {
18095        synchronized (this) {
18096            mTestPssMode = enabled;
18097            if (enabled) {
18098                // Whenever we enable the mode, we want to take a snapshot all of current
18099                // process mem use.
18100                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
18101            }
18102        }
18103    }
18104
18105    /**
18106     * Ask a given process to GC right now.
18107     */
18108    final void performAppGcLocked(ProcessRecord app) {
18109        try {
18110            app.lastRequestedGc = SystemClock.uptimeMillis();
18111            if (app.thread != null) {
18112                if (app.reportLowMemory) {
18113                    app.reportLowMemory = false;
18114                    app.thread.scheduleLowMemory();
18115                } else {
18116                    app.thread.processInBackground();
18117                }
18118            }
18119        } catch (Exception e) {
18120            // whatever.
18121        }
18122    }
18123
18124    /**
18125     * Returns true if things are idle enough to perform GCs.
18126     */
18127    private final boolean canGcNowLocked() {
18128        boolean processingBroadcasts = false;
18129        for (BroadcastQueue q : mBroadcastQueues) {
18130            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
18131                processingBroadcasts = true;
18132            }
18133        }
18134        return !processingBroadcasts
18135                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
18136    }
18137
18138    /**
18139     * Perform GCs on all processes that are waiting for it, but only
18140     * if things are idle.
18141     */
18142    final void performAppGcsLocked() {
18143        final int N = mProcessesToGc.size();
18144        if (N <= 0) {
18145            return;
18146        }
18147        if (canGcNowLocked()) {
18148            while (mProcessesToGc.size() > 0) {
18149                ProcessRecord proc = mProcessesToGc.remove(0);
18150                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
18151                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
18152                            <= SystemClock.uptimeMillis()) {
18153                        // To avoid spamming the system, we will GC processes one
18154                        // at a time, waiting a few seconds between each.
18155                        performAppGcLocked(proc);
18156                        scheduleAppGcsLocked();
18157                        return;
18158                    } else {
18159                        // It hasn't been long enough since we last GCed this
18160                        // process...  put it in the list to wait for its time.
18161                        addProcessToGcListLocked(proc);
18162                        break;
18163                    }
18164                }
18165            }
18166
18167            scheduleAppGcsLocked();
18168        }
18169    }
18170
18171    /**
18172     * If all looks good, perform GCs on all processes waiting for them.
18173     */
18174    final void performAppGcsIfAppropriateLocked() {
18175        if (canGcNowLocked()) {
18176            performAppGcsLocked();
18177            return;
18178        }
18179        // Still not idle, wait some more.
18180        scheduleAppGcsLocked();
18181    }
18182
18183    /**
18184     * Schedule the execution of all pending app GCs.
18185     */
18186    final void scheduleAppGcsLocked() {
18187        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
18188
18189        if (mProcessesToGc.size() > 0) {
18190            // Schedule a GC for the time to the next process.
18191            ProcessRecord proc = mProcessesToGc.get(0);
18192            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
18193
18194            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
18195            long now = SystemClock.uptimeMillis();
18196            if (when < (now+GC_TIMEOUT)) {
18197                when = now + GC_TIMEOUT;
18198            }
18199            mHandler.sendMessageAtTime(msg, when);
18200        }
18201    }
18202
18203    /**
18204     * Add a process to the array of processes waiting to be GCed.  Keeps the
18205     * list in sorted order by the last GC time.  The process can't already be
18206     * on the list.
18207     */
18208    final void addProcessToGcListLocked(ProcessRecord proc) {
18209        boolean added = false;
18210        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
18211            if (mProcessesToGc.get(i).lastRequestedGc <
18212                    proc.lastRequestedGc) {
18213                added = true;
18214                mProcessesToGc.add(i+1, proc);
18215                break;
18216            }
18217        }
18218        if (!added) {
18219            mProcessesToGc.add(0, proc);
18220        }
18221    }
18222
18223    /**
18224     * Set up to ask a process to GC itself.  This will either do it
18225     * immediately, or put it on the list of processes to gc the next
18226     * time things are idle.
18227     */
18228    final void scheduleAppGcLocked(ProcessRecord app) {
18229        long now = SystemClock.uptimeMillis();
18230        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
18231            return;
18232        }
18233        if (!mProcessesToGc.contains(app)) {
18234            addProcessToGcListLocked(app);
18235            scheduleAppGcsLocked();
18236        }
18237    }
18238
18239    final void checkExcessivePowerUsageLocked(boolean doKills) {
18240        updateCpuStatsNow();
18241
18242        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18243        boolean doWakeKills = doKills;
18244        boolean doCpuKills = doKills;
18245        if (mLastPowerCheckRealtime == 0) {
18246            doWakeKills = false;
18247        }
18248        if (mLastPowerCheckUptime == 0) {
18249            doCpuKills = false;
18250        }
18251        if (stats.isScreenOn()) {
18252            doWakeKills = false;
18253        }
18254        final long curRealtime = SystemClock.elapsedRealtime();
18255        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
18256        final long curUptime = SystemClock.uptimeMillis();
18257        final long uptimeSince = curUptime - mLastPowerCheckUptime;
18258        mLastPowerCheckRealtime = curRealtime;
18259        mLastPowerCheckUptime = curUptime;
18260        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
18261            doWakeKills = false;
18262        }
18263        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
18264            doCpuKills = false;
18265        }
18266        int i = mLruProcesses.size();
18267        while (i > 0) {
18268            i--;
18269            ProcessRecord app = mLruProcesses.get(i);
18270            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18271                long wtime;
18272                synchronized (stats) {
18273                    wtime = stats.getProcessWakeTime(app.info.uid,
18274                            app.pid, curRealtime);
18275                }
18276                long wtimeUsed = wtime - app.lastWakeTime;
18277                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
18278                if (DEBUG_POWER) {
18279                    StringBuilder sb = new StringBuilder(128);
18280                    sb.append("Wake for ");
18281                    app.toShortString(sb);
18282                    sb.append(": over ");
18283                    TimeUtils.formatDuration(realtimeSince, sb);
18284                    sb.append(" used ");
18285                    TimeUtils.formatDuration(wtimeUsed, sb);
18286                    sb.append(" (");
18287                    sb.append((wtimeUsed*100)/realtimeSince);
18288                    sb.append("%)");
18289                    Slog.i(TAG_POWER, sb.toString());
18290                    sb.setLength(0);
18291                    sb.append("CPU for ");
18292                    app.toShortString(sb);
18293                    sb.append(": over ");
18294                    TimeUtils.formatDuration(uptimeSince, sb);
18295                    sb.append(" used ");
18296                    TimeUtils.formatDuration(cputimeUsed, sb);
18297                    sb.append(" (");
18298                    sb.append((cputimeUsed*100)/uptimeSince);
18299                    sb.append("%)");
18300                    Slog.i(TAG_POWER, sb.toString());
18301                }
18302                // If a process has held a wake lock for more
18303                // than 50% of the time during this period,
18304                // that sounds bad.  Kill!
18305                if (doWakeKills && realtimeSince > 0
18306                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
18307                    synchronized (stats) {
18308                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
18309                                realtimeSince, wtimeUsed);
18310                    }
18311                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
18312                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
18313                } else if (doCpuKills && uptimeSince > 0
18314                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
18315                    synchronized (stats) {
18316                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
18317                                uptimeSince, cputimeUsed);
18318                    }
18319                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
18320                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
18321                } else {
18322                    app.lastWakeTime = wtime;
18323                    app.lastCpuTime = app.curCpuTime;
18324                }
18325            }
18326        }
18327    }
18328
18329    private final boolean applyOomAdjLocked(ProcessRecord app,
18330            ProcessRecord TOP_APP, boolean doingAll, long now) {
18331        boolean success = true;
18332
18333        if (app.curRawAdj != app.setRawAdj) {
18334            app.setRawAdj = app.curRawAdj;
18335        }
18336
18337        int changes = 0;
18338
18339        if (app.curAdj != app.setAdj) {
18340            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
18341            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18342                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
18343                    + app.adjType);
18344            app.setAdj = app.curAdj;
18345        }
18346
18347        if (app.setSchedGroup != app.curSchedGroup) {
18348            app.setSchedGroup = app.curSchedGroup;
18349            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18350                    "Setting process group of " + app.processName
18351                    + " to " + app.curSchedGroup);
18352            if (app.waitingToKill != null &&
18353                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
18354                app.kill(app.waitingToKill, true);
18355                success = false;
18356            } else {
18357                if (true) {
18358                    long oldId = Binder.clearCallingIdentity();
18359                    try {
18360                        Process.setProcessGroup(app.pid, app.curSchedGroup);
18361                    } catch (Exception e) {
18362                        Slog.w(TAG, "Failed setting process group of " + app.pid
18363                                + " to " + app.curSchedGroup);
18364                        e.printStackTrace();
18365                    } finally {
18366                        Binder.restoreCallingIdentity(oldId);
18367                    }
18368                } else {
18369                    if (app.thread != null) {
18370                        try {
18371                            app.thread.setSchedulingGroup(app.curSchedGroup);
18372                        } catch (RemoteException e) {
18373                        }
18374                    }
18375                }
18376                Process.setSwappiness(app.pid,
18377                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
18378            }
18379        }
18380        if (app.repForegroundActivities != app.foregroundActivities) {
18381            app.repForegroundActivities = app.foregroundActivities;
18382            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
18383        }
18384        if (app.repProcState != app.curProcState) {
18385            app.repProcState = app.curProcState;
18386            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
18387            if (app.thread != null) {
18388                try {
18389                    if (false) {
18390                        //RuntimeException h = new RuntimeException("here");
18391                        Slog.i(TAG, "Sending new process state " + app.repProcState
18392                                + " to " + app /*, h*/);
18393                    }
18394                    app.thread.setProcessState(app.repProcState);
18395                } catch (RemoteException e) {
18396                }
18397            }
18398        }
18399        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
18400                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
18401            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
18402                // Experimental code to more aggressively collect pss while
18403                // running test...  the problem is that this tends to collect
18404                // the data right when a process is transitioning between process
18405                // states, which well tend to give noisy data.
18406                long start = SystemClock.uptimeMillis();
18407                long pss = Debug.getPss(app.pid, mTmpLong, null);
18408                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], now);
18409                mPendingPssProcesses.remove(app);
18410                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
18411                        + " to " + app.curProcState + ": "
18412                        + (SystemClock.uptimeMillis()-start) + "ms");
18413            }
18414            app.lastStateTime = now;
18415            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18416                    mTestPssMode, isSleeping(), now);
18417            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
18418                    + ProcessList.makeProcStateString(app.setProcState) + " to "
18419                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
18420                    + (app.nextPssTime-now) + ": " + app);
18421        } else {
18422            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
18423                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
18424                    mTestPssMode)))) {
18425                requestPssLocked(app, app.setProcState);
18426                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
18427                        mTestPssMode, isSleeping(), now);
18428            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
18429                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
18430        }
18431        if (app.setProcState != app.curProcState) {
18432            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18433                    "Proc state change of " + app.processName
18434                    + " to " + app.curProcState);
18435            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
18436            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
18437            if (setImportant && !curImportant) {
18438                // This app is no longer something we consider important enough to allow to
18439                // use arbitrary amounts of battery power.  Note
18440                // its current wake lock time to later know to kill it if
18441                // it is not behaving well.
18442                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18443                synchronized (stats) {
18444                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
18445                            app.pid, SystemClock.elapsedRealtime());
18446                }
18447                app.lastCpuTime = app.curCpuTime;
18448
18449            }
18450            // Inform UsageStats of important process state change
18451            // Must be called before updating setProcState
18452            maybeUpdateUsageStats(app);
18453
18454            app.setProcState = app.curProcState;
18455            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18456                app.notCachedSinceIdle = false;
18457            }
18458            if (!doingAll) {
18459                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
18460            } else {
18461                app.procStateChanged = true;
18462            }
18463        }
18464
18465        if (changes != 0) {
18466            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18467                    "Changes in " + app + ": " + changes);
18468            int i = mPendingProcessChanges.size()-1;
18469            ProcessChangeItem item = null;
18470            while (i >= 0) {
18471                item = mPendingProcessChanges.get(i);
18472                if (item.pid == app.pid) {
18473                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18474                            "Re-using existing item: " + item);
18475                    break;
18476                }
18477                i--;
18478            }
18479            if (i < 0) {
18480                // No existing item in pending changes; need a new one.
18481                final int NA = mAvailProcessChanges.size();
18482                if (NA > 0) {
18483                    item = mAvailProcessChanges.remove(NA-1);
18484                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18485                            "Retrieving available item: " + item);
18486                } else {
18487                    item = new ProcessChangeItem();
18488                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18489                            "Allocating new item: " + item);
18490                }
18491                item.changes = 0;
18492                item.pid = app.pid;
18493                item.uid = app.info.uid;
18494                if (mPendingProcessChanges.size() == 0) {
18495                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18496                            "*** Enqueueing dispatch processes changed!");
18497                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
18498                }
18499                mPendingProcessChanges.add(item);
18500            }
18501            item.changes |= changes;
18502            item.processState = app.repProcState;
18503            item.foregroundActivities = app.repForegroundActivities;
18504            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18505                    "Item " + Integer.toHexString(System.identityHashCode(item))
18506                    + " " + app.toShortString() + ": changes=" + item.changes
18507                    + " procState=" + item.processState
18508                    + " foreground=" + item.foregroundActivities
18509                    + " type=" + app.adjType + " source=" + app.adjSource
18510                    + " target=" + app.adjTarget);
18511        }
18512
18513        return success;
18514    }
18515
18516    private final void enqueueUidChangeLocked(UidRecord uidRec, boolean gone) {
18517        if (uidRec.pendingChange == null) {
18518            if (mPendingUidChanges.size() == 0) {
18519                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18520                        "*** Enqueueing dispatch uid changed!");
18521                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_MSG).sendToTarget();
18522            }
18523            final int NA = mAvailUidChanges.size();
18524            if (NA > 0) {
18525                uidRec.pendingChange = mAvailUidChanges.remove(NA-1);
18526                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18527                        "Retrieving available item: " + uidRec.pendingChange);
18528            } else {
18529                uidRec.pendingChange = new UidRecord.ChangeItem();
18530                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18531                        "Allocating new item: " + uidRec.pendingChange);
18532            }
18533            uidRec.pendingChange.uidRecord = uidRec;
18534            uidRec.pendingChange.uid = uidRec.uid;
18535            mPendingUidChanges.add(uidRec.pendingChange);
18536        }
18537        uidRec.pendingChange.gone = gone;
18538        uidRec.pendingChange.processState = uidRec.setProcState;
18539    }
18540
18541    private void maybeUpdateUsageStats(ProcessRecord app) {
18542        if (DEBUG_USAGE_STATS) {
18543            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
18544                    + "] state changes: old = " + app.setProcState + ", new = "
18545                    + app.curProcState);
18546        }
18547        if (mUsageStatsService == null) {
18548            return;
18549        }
18550        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
18551                && (app.setProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
18552                        || app.setProcState < 0)) {
18553            String[] packages = app.getPackageList();
18554            if (packages != null) {
18555                for (int i = 0; i < packages.length; i++) {
18556                    mUsageStatsService.reportEvent(packages[i], app.userId,
18557                            UsageEvents.Event.INTERACTION);
18558                }
18559            }
18560        }
18561    }
18562
18563    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
18564        if (proc.thread != null) {
18565            if (proc.baseProcessTracker != null) {
18566                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
18567            }
18568            if (proc.repProcState >= 0) {
18569                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
18570                        proc.repProcState);
18571            }
18572        }
18573    }
18574
18575    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
18576            ProcessRecord TOP_APP, boolean doingAll, long now) {
18577        if (app.thread == null) {
18578            return false;
18579        }
18580
18581        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
18582
18583        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
18584    }
18585
18586    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
18587            boolean oomAdj) {
18588        if (isForeground != proc.foregroundServices) {
18589            proc.foregroundServices = isForeground;
18590            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
18591                    proc.info.uid);
18592            if (isForeground) {
18593                if (curProcs == null) {
18594                    curProcs = new ArrayList<ProcessRecord>();
18595                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
18596                }
18597                if (!curProcs.contains(proc)) {
18598                    curProcs.add(proc);
18599                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
18600                            proc.info.packageName, proc.info.uid);
18601                }
18602            } else {
18603                if (curProcs != null) {
18604                    if (curProcs.remove(proc)) {
18605                        mBatteryStatsService.noteEvent(
18606                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
18607                                proc.info.packageName, proc.info.uid);
18608                        if (curProcs.size() <= 0) {
18609                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
18610                        }
18611                    }
18612                }
18613            }
18614            if (oomAdj) {
18615                updateOomAdjLocked();
18616            }
18617        }
18618    }
18619
18620    private final ActivityRecord resumedAppLocked() {
18621        ActivityRecord act = mStackSupervisor.resumedAppLocked();
18622        String pkg;
18623        int uid;
18624        if (act != null) {
18625            pkg = act.packageName;
18626            uid = act.info.applicationInfo.uid;
18627        } else {
18628            pkg = null;
18629            uid = -1;
18630        }
18631        // Has the UID or resumed package name changed?
18632        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
18633                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
18634            if (mCurResumedPackage != null) {
18635                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
18636                        mCurResumedPackage, mCurResumedUid);
18637            }
18638            mCurResumedPackage = pkg;
18639            mCurResumedUid = uid;
18640            if (mCurResumedPackage != null) {
18641                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
18642                        mCurResumedPackage, mCurResumedUid);
18643            }
18644        }
18645        return act;
18646    }
18647
18648    final boolean updateOomAdjLocked(ProcessRecord app) {
18649        final ActivityRecord TOP_ACT = resumedAppLocked();
18650        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18651        final boolean wasCached = app.cached;
18652
18653        mAdjSeq++;
18654
18655        // This is the desired cached adjusment we want to tell it to use.
18656        // If our app is currently cached, we know it, and that is it.  Otherwise,
18657        // we don't know it yet, and it needs to now be cached we will then
18658        // need to do a complete oom adj.
18659        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
18660                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
18661        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
18662                SystemClock.uptimeMillis());
18663        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
18664            // Changed to/from cached state, so apps after it in the LRU
18665            // list may also be changed.
18666            updateOomAdjLocked();
18667        }
18668        return success;
18669    }
18670
18671    final void updateOomAdjLocked() {
18672        final ActivityRecord TOP_ACT = resumedAppLocked();
18673        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18674        final long now = SystemClock.uptimeMillis();
18675        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
18676        final int N = mLruProcesses.size();
18677
18678        if (false) {
18679            RuntimeException e = new RuntimeException();
18680            e.fillInStackTrace();
18681            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
18682        }
18683
18684        // Reset state in all uid records.
18685        for (int i=mActiveUids.size()-1; i>=0; i--) {
18686            final UidRecord uidRec = mActiveUids.valueAt(i);
18687            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18688                    "Starting update of " + uidRec);
18689            uidRec.reset();
18690        }
18691
18692        mAdjSeq++;
18693        mNewNumServiceProcs = 0;
18694        mNewNumAServiceProcs = 0;
18695
18696        final int emptyProcessLimit;
18697        final int cachedProcessLimit;
18698        if (mProcessLimit <= 0) {
18699            emptyProcessLimit = cachedProcessLimit = 0;
18700        } else if (mProcessLimit == 1) {
18701            emptyProcessLimit = 1;
18702            cachedProcessLimit = 0;
18703        } else {
18704            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
18705            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
18706        }
18707
18708        // Let's determine how many processes we have running vs.
18709        // how many slots we have for background processes; we may want
18710        // to put multiple processes in a slot of there are enough of
18711        // them.
18712        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
18713                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
18714        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
18715        if (numEmptyProcs > cachedProcessLimit) {
18716            // If there are more empty processes than our limit on cached
18717            // processes, then use the cached process limit for the factor.
18718            // This ensures that the really old empty processes get pushed
18719            // down to the bottom, so if we are running low on memory we will
18720            // have a better chance at keeping around more cached processes
18721            // instead of a gazillion empty processes.
18722            numEmptyProcs = cachedProcessLimit;
18723        }
18724        int emptyFactor = numEmptyProcs/numSlots;
18725        if (emptyFactor < 1) emptyFactor = 1;
18726        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
18727        if (cachedFactor < 1) cachedFactor = 1;
18728        int stepCached = 0;
18729        int stepEmpty = 0;
18730        int numCached = 0;
18731        int numEmpty = 0;
18732        int numTrimming = 0;
18733
18734        mNumNonCachedProcs = 0;
18735        mNumCachedHiddenProcs = 0;
18736
18737        // First update the OOM adjustment for each of the
18738        // application processes based on their current state.
18739        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
18740        int nextCachedAdj = curCachedAdj+1;
18741        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
18742        int nextEmptyAdj = curEmptyAdj+2;
18743        for (int i=N-1; i>=0; i--) {
18744            ProcessRecord app = mLruProcesses.get(i);
18745            if (!app.killedByAm && app.thread != null) {
18746                app.procStateChanged = false;
18747                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
18748
18749                // If we haven't yet assigned the final cached adj
18750                // to the process, do that now.
18751                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
18752                    switch (app.curProcState) {
18753                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18754                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18755                            // This process is a cached process holding activities...
18756                            // assign it the next cached value for that type, and then
18757                            // step that cached level.
18758                            app.curRawAdj = curCachedAdj;
18759                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
18760                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
18761                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
18762                                    + ")");
18763                            if (curCachedAdj != nextCachedAdj) {
18764                                stepCached++;
18765                                if (stepCached >= cachedFactor) {
18766                                    stepCached = 0;
18767                                    curCachedAdj = nextCachedAdj;
18768                                    nextCachedAdj += 2;
18769                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18770                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
18771                                    }
18772                                }
18773                            }
18774                            break;
18775                        default:
18776                            // For everything else, assign next empty cached process
18777                            // level and bump that up.  Note that this means that
18778                            // long-running services that have dropped down to the
18779                            // cached level will be treated as empty (since their process
18780                            // state is still as a service), which is what we want.
18781                            app.curRawAdj = curEmptyAdj;
18782                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
18783                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
18784                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
18785                                    + ")");
18786                            if (curEmptyAdj != nextEmptyAdj) {
18787                                stepEmpty++;
18788                                if (stepEmpty >= emptyFactor) {
18789                                    stepEmpty = 0;
18790                                    curEmptyAdj = nextEmptyAdj;
18791                                    nextEmptyAdj += 2;
18792                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18793                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
18794                                    }
18795                                }
18796                            }
18797                            break;
18798                    }
18799                }
18800
18801                applyOomAdjLocked(app, TOP_APP, true, now);
18802
18803                // Count the number of process types.
18804                switch (app.curProcState) {
18805                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18806                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18807                        mNumCachedHiddenProcs++;
18808                        numCached++;
18809                        if (numCached > cachedProcessLimit) {
18810                            app.kill("cached #" + numCached, true);
18811                        }
18812                        break;
18813                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
18814                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
18815                                && app.lastActivityTime < oldTime) {
18816                            app.kill("empty for "
18817                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
18818                                    / 1000) + "s", true);
18819                        } else {
18820                            numEmpty++;
18821                            if (numEmpty > emptyProcessLimit) {
18822                                app.kill("empty #" + numEmpty, true);
18823                            }
18824                        }
18825                        break;
18826                    default:
18827                        mNumNonCachedProcs++;
18828                        break;
18829                }
18830
18831                if (app.isolated && app.services.size() <= 0) {
18832                    // If this is an isolated process, and there are no
18833                    // services running in it, then the process is no longer
18834                    // needed.  We agressively kill these because we can by
18835                    // definition not re-use the same process again, and it is
18836                    // good to avoid having whatever code was running in them
18837                    // left sitting around after no longer needed.
18838                    app.kill("isolated not needed", true);
18839                } else {
18840                    // Keeping this process, update its uid.
18841                    final UidRecord uidRec = app.uidRecord;
18842                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
18843                        uidRec.curProcState = app.curProcState;
18844                    }
18845                }
18846
18847                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18848                        && !app.killedByAm) {
18849                    numTrimming++;
18850                }
18851            }
18852        }
18853
18854        mNumServiceProcs = mNewNumServiceProcs;
18855
18856        // Now determine the memory trimming level of background processes.
18857        // Unfortunately we need to start at the back of the list to do this
18858        // properly.  We only do this if the number of background apps we
18859        // are managing to keep around is less than half the maximum we desire;
18860        // if we are keeping a good number around, we'll let them use whatever
18861        // memory they want.
18862        final int numCachedAndEmpty = numCached + numEmpty;
18863        int memFactor;
18864        if (numCached <= ProcessList.TRIM_CACHED_APPS
18865                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
18866            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
18867                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
18868            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
18869                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
18870            } else {
18871                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
18872            }
18873        } else {
18874            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
18875        }
18876        // We always allow the memory level to go up (better).  We only allow it to go
18877        // down if we are in a state where that is allowed, *and* the total number of processes
18878        // has gone down since last time.
18879        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
18880                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
18881                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
18882        if (memFactor > mLastMemoryLevel) {
18883            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
18884                memFactor = mLastMemoryLevel;
18885                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
18886            }
18887        }
18888        mLastMemoryLevel = memFactor;
18889        mLastNumProcesses = mLruProcesses.size();
18890        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
18891        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
18892        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
18893            if (mLowRamStartTime == 0) {
18894                mLowRamStartTime = now;
18895            }
18896            int step = 0;
18897            int fgTrimLevel;
18898            switch (memFactor) {
18899                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18900                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
18901                    break;
18902                case ProcessStats.ADJ_MEM_FACTOR_LOW:
18903                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
18904                    break;
18905                default:
18906                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
18907                    break;
18908            }
18909            int factor = numTrimming/3;
18910            int minFactor = 2;
18911            if (mHomeProcess != null) minFactor++;
18912            if (mPreviousProcess != null) minFactor++;
18913            if (factor < minFactor) factor = minFactor;
18914            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
18915            for (int i=N-1; i>=0; i--) {
18916                ProcessRecord app = mLruProcesses.get(i);
18917                if (allChanged || app.procStateChanged) {
18918                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18919                    app.procStateChanged = false;
18920                }
18921                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18922                        && !app.killedByAm) {
18923                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
18924                        try {
18925                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18926                                    "Trimming memory of " + app.processName + " to " + curLevel);
18927                            app.thread.scheduleTrimMemory(curLevel);
18928                        } catch (RemoteException e) {
18929                        }
18930                        if (false) {
18931                            // For now we won't do this; our memory trimming seems
18932                            // to be good enough at this point that destroying
18933                            // activities causes more harm than good.
18934                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
18935                                    && app != mHomeProcess && app != mPreviousProcess) {
18936                                // Need to do this on its own message because the stack may not
18937                                // be in a consistent state at this point.
18938                                // For these apps we will also finish their activities
18939                                // to help them free memory.
18940                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
18941                            }
18942                        }
18943                    }
18944                    app.trimMemoryLevel = curLevel;
18945                    step++;
18946                    if (step >= factor) {
18947                        step = 0;
18948                        switch (curLevel) {
18949                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18950                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18951                                break;
18952                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18953                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18954                                break;
18955                        }
18956                    }
18957                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18958                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18959                            && app.thread != null) {
18960                        try {
18961                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18962                                    "Trimming memory of heavy-weight " + app.processName
18963                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18964                            app.thread.scheduleTrimMemory(
18965                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18966                        } catch (RemoteException e) {
18967                        }
18968                    }
18969                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18970                } else {
18971                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18972                            || app.systemNoUi) && app.pendingUiClean) {
18973                        // If this application is now in the background and it
18974                        // had done UI, then give it the special trim level to
18975                        // have it free UI resources.
18976                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18977                        if (app.trimMemoryLevel < level && app.thread != null) {
18978                            try {
18979                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18980                                        "Trimming memory of bg-ui " + app.processName
18981                                        + " to " + level);
18982                                app.thread.scheduleTrimMemory(level);
18983                            } catch (RemoteException e) {
18984                            }
18985                        }
18986                        app.pendingUiClean = false;
18987                    }
18988                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18989                        try {
18990                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18991                                    "Trimming memory of fg " + app.processName
18992                                    + " to " + fgTrimLevel);
18993                            app.thread.scheduleTrimMemory(fgTrimLevel);
18994                        } catch (RemoteException e) {
18995                        }
18996                    }
18997                    app.trimMemoryLevel = fgTrimLevel;
18998                }
18999            }
19000        } else {
19001            if (mLowRamStartTime != 0) {
19002                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
19003                mLowRamStartTime = 0;
19004            }
19005            for (int i=N-1; i>=0; i--) {
19006                ProcessRecord app = mLruProcesses.get(i);
19007                if (allChanged || app.procStateChanged) {
19008                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
19009                    app.procStateChanged = false;
19010                }
19011                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19012                        || app.systemNoUi) && app.pendingUiClean) {
19013                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
19014                            && app.thread != null) {
19015                        try {
19016                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19017                                    "Trimming memory of ui hidden " + app.processName
19018                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19019                            app.thread.scheduleTrimMemory(
19020                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19021                        } catch (RemoteException e) {
19022                        }
19023                    }
19024                    app.pendingUiClean = false;
19025                }
19026                app.trimMemoryLevel = 0;
19027            }
19028        }
19029
19030        if (mAlwaysFinishActivities) {
19031            // Need to do this on its own message because the stack may not
19032            // be in a consistent state at this point.
19033            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
19034        }
19035
19036        if (allChanged) {
19037            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
19038        }
19039
19040        // Update from any uid changes.
19041        for (int i=mActiveUids.size()-1; i>=0; i--) {
19042            final UidRecord uidRec = mActiveUids.valueAt(i);
19043            if (uidRec.setProcState != uidRec.curProcState) {
19044                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19045                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
19046                        + " to " + uidRec.curProcState);
19047                uidRec.setProcState = uidRec.curProcState;
19048                enqueueUidChangeLocked(uidRec, false);
19049            }
19050        }
19051
19052        if (mProcessStats.shouldWriteNowLocked(now)) {
19053            mHandler.post(new Runnable() {
19054                @Override public void run() {
19055                    synchronized (ActivityManagerService.this) {
19056                        mProcessStats.writeStateAsyncLocked();
19057                    }
19058                }
19059            });
19060        }
19061
19062        if (DEBUG_OOM_ADJ) {
19063            final long duration = SystemClock.uptimeMillis() - now;
19064            if (false) {
19065                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
19066                        new RuntimeException("here").fillInStackTrace());
19067            } else {
19068                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
19069            }
19070        }
19071    }
19072
19073    final void trimApplications() {
19074        synchronized (this) {
19075            int i;
19076
19077            // First remove any unused application processes whose package
19078            // has been removed.
19079            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
19080                final ProcessRecord app = mRemovedProcesses.get(i);
19081                if (app.activities.size() == 0
19082                        && app.curReceiver == null && app.services.size() == 0) {
19083                    Slog.i(
19084                        TAG, "Exiting empty application process "
19085                        + app.processName + " ("
19086                        + (app.thread != null ? app.thread.asBinder() : null)
19087                        + ")\n");
19088                    if (app.pid > 0 && app.pid != MY_PID) {
19089                        app.kill("empty", false);
19090                    } else {
19091                        try {
19092                            app.thread.scheduleExit();
19093                        } catch (Exception e) {
19094                            // Ignore exceptions.
19095                        }
19096                    }
19097                    cleanUpApplicationRecordLocked(app, false, true, -1);
19098                    mRemovedProcesses.remove(i);
19099
19100                    if (app.persistent) {
19101                        addAppLocked(app.info, false, null /* ABI override */);
19102                    }
19103                }
19104            }
19105
19106            // Now update the oom adj for all processes.
19107            updateOomAdjLocked();
19108        }
19109    }
19110
19111    /** This method sends the specified signal to each of the persistent apps */
19112    public void signalPersistentProcesses(int sig) throws RemoteException {
19113        if (sig != Process.SIGNAL_USR1) {
19114            throw new SecurityException("Only SIGNAL_USR1 is allowed");
19115        }
19116
19117        synchronized (this) {
19118            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
19119                    != PackageManager.PERMISSION_GRANTED) {
19120                throw new SecurityException("Requires permission "
19121                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
19122            }
19123
19124            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
19125                ProcessRecord r = mLruProcesses.get(i);
19126                if (r.thread != null && r.persistent) {
19127                    Process.sendSignal(r.pid, sig);
19128                }
19129            }
19130        }
19131    }
19132
19133    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
19134        if (proc == null || proc == mProfileProc) {
19135            proc = mProfileProc;
19136            profileType = mProfileType;
19137            clearProfilerLocked();
19138        }
19139        if (proc == null) {
19140            return;
19141        }
19142        try {
19143            proc.thread.profilerControl(false, null, profileType);
19144        } catch (RemoteException e) {
19145            throw new IllegalStateException("Process disappeared");
19146        }
19147    }
19148
19149    private void clearProfilerLocked() {
19150        if (mProfileFd != null) {
19151            try {
19152                mProfileFd.close();
19153            } catch (IOException e) {
19154            }
19155        }
19156        mProfileApp = null;
19157        mProfileProc = null;
19158        mProfileFile = null;
19159        mProfileType = 0;
19160        mAutoStopProfiler = false;
19161        mSamplingInterval = 0;
19162    }
19163
19164    public boolean profileControl(String process, int userId, boolean start,
19165            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
19166
19167        try {
19168            synchronized (this) {
19169                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19170                // its own permission.
19171                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19172                        != PackageManager.PERMISSION_GRANTED) {
19173                    throw new SecurityException("Requires permission "
19174                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19175                }
19176
19177                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
19178                    throw new IllegalArgumentException("null profile info or fd");
19179                }
19180
19181                ProcessRecord proc = null;
19182                if (process != null) {
19183                    proc = findProcessLocked(process, userId, "profileControl");
19184                }
19185
19186                if (start && (proc == null || proc.thread == null)) {
19187                    throw new IllegalArgumentException("Unknown process: " + process);
19188                }
19189
19190                if (start) {
19191                    stopProfilerLocked(null, 0);
19192                    setProfileApp(proc.info, proc.processName, profilerInfo);
19193                    mProfileProc = proc;
19194                    mProfileType = profileType;
19195                    ParcelFileDescriptor fd = profilerInfo.profileFd;
19196                    try {
19197                        fd = fd.dup();
19198                    } catch (IOException e) {
19199                        fd = null;
19200                    }
19201                    profilerInfo.profileFd = fd;
19202                    proc.thread.profilerControl(start, profilerInfo, profileType);
19203                    fd = null;
19204                    mProfileFd = null;
19205                } else {
19206                    stopProfilerLocked(proc, profileType);
19207                    if (profilerInfo != null && profilerInfo.profileFd != null) {
19208                        try {
19209                            profilerInfo.profileFd.close();
19210                        } catch (IOException e) {
19211                        }
19212                    }
19213                }
19214
19215                return true;
19216            }
19217        } catch (RemoteException e) {
19218            throw new IllegalStateException("Process disappeared");
19219        } finally {
19220            if (profilerInfo != null && profilerInfo.profileFd != null) {
19221                try {
19222                    profilerInfo.profileFd.close();
19223                } catch (IOException e) {
19224                }
19225            }
19226        }
19227    }
19228
19229    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
19230        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19231                userId, true, ALLOW_FULL_ONLY, callName, null);
19232        ProcessRecord proc = null;
19233        try {
19234            int pid = Integer.parseInt(process);
19235            synchronized (mPidsSelfLocked) {
19236                proc = mPidsSelfLocked.get(pid);
19237            }
19238        } catch (NumberFormatException e) {
19239        }
19240
19241        if (proc == null) {
19242            ArrayMap<String, SparseArray<ProcessRecord>> all
19243                    = mProcessNames.getMap();
19244            SparseArray<ProcessRecord> procs = all.get(process);
19245            if (procs != null && procs.size() > 0) {
19246                proc = procs.valueAt(0);
19247                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
19248                    for (int i=1; i<procs.size(); i++) {
19249                        ProcessRecord thisProc = procs.valueAt(i);
19250                        if (thisProc.userId == userId) {
19251                            proc = thisProc;
19252                            break;
19253                        }
19254                    }
19255                }
19256            }
19257        }
19258
19259        return proc;
19260    }
19261
19262    public boolean dumpHeap(String process, int userId, boolean managed,
19263            String path, ParcelFileDescriptor fd) throws RemoteException {
19264
19265        try {
19266            synchronized (this) {
19267                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19268                // its own permission (same as profileControl).
19269                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19270                        != PackageManager.PERMISSION_GRANTED) {
19271                    throw new SecurityException("Requires permission "
19272                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19273                }
19274
19275                if (fd == null) {
19276                    throw new IllegalArgumentException("null fd");
19277                }
19278
19279                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
19280                if (proc == null || proc.thread == null) {
19281                    throw new IllegalArgumentException("Unknown process: " + process);
19282                }
19283
19284                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19285                if (!isDebuggable) {
19286                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19287                        throw new SecurityException("Process not debuggable: " + proc);
19288                    }
19289                }
19290
19291                proc.thread.dumpHeap(managed, path, fd);
19292                fd = null;
19293                return true;
19294            }
19295        } catch (RemoteException e) {
19296            throw new IllegalStateException("Process disappeared");
19297        } finally {
19298            if (fd != null) {
19299                try {
19300                    fd.close();
19301                } catch (IOException e) {
19302                }
19303            }
19304        }
19305    }
19306
19307    @Override
19308    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
19309            String reportPackage) {
19310        if (processName != null) {
19311            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
19312                    "setDumpHeapDebugLimit()");
19313        } else {
19314            if (!Build.IS_DEBUGGABLE) {
19315                throw new SecurityException("Not running a debuggable build");
19316            }
19317            synchronized (mPidsSelfLocked) {
19318                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
19319                if (proc == null) {
19320                    throw new SecurityException("No process found for calling pid "
19321                            + Binder.getCallingPid());
19322                }
19323                processName = proc.processName;
19324                uid = proc.uid;
19325                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
19326                    throw new SecurityException("Package " + reportPackage + " is not running in "
19327                            + proc);
19328                }
19329            }
19330        }
19331        synchronized (this) {
19332            if (maxMemSize > 0) {
19333                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
19334            } else {
19335                if (uid != 0) {
19336                    mMemWatchProcesses.remove(processName, uid);
19337                } else {
19338                    mMemWatchProcesses.getMap().remove(processName);
19339                }
19340            }
19341        }
19342    }
19343
19344    @Override
19345    public void dumpHeapFinished(String path) {
19346        synchronized (this) {
19347            if (Binder.getCallingPid() != mMemWatchDumpPid) {
19348                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
19349                        + " does not match last pid " + mMemWatchDumpPid);
19350                return;
19351            }
19352            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
19353                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
19354                        + " does not match last path " + mMemWatchDumpFile);
19355                return;
19356            }
19357            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
19358            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
19359        }
19360    }
19361
19362    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
19363    public void monitor() {
19364        synchronized (this) { }
19365    }
19366
19367    void onCoreSettingsChange(Bundle settings) {
19368        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19369            ProcessRecord processRecord = mLruProcesses.get(i);
19370            try {
19371                if (processRecord.thread != null) {
19372                    processRecord.thread.setCoreSettings(settings);
19373                }
19374            } catch (RemoteException re) {
19375                /* ignore */
19376            }
19377        }
19378    }
19379
19380    // Multi-user methods
19381
19382    /**
19383     * Start user, if its not already running, but don't bring it to foreground.
19384     */
19385    @Override
19386    public boolean startUserInBackground(final int userId) {
19387        return startUser(userId, /* foreground */ false);
19388    }
19389
19390    /**
19391     * Start user, if its not already running, and bring it to foreground.
19392     */
19393    boolean startUserInForeground(final int userId, Dialog dlg) {
19394        boolean result = startUser(userId, /* foreground */ true);
19395        dlg.dismiss();
19396        return result;
19397    }
19398
19399    /**
19400     * Refreshes the list of users related to the current user when either a
19401     * user switch happens or when a new related user is started in the
19402     * background.
19403     */
19404    private void updateCurrentProfileIdsLocked() {
19405        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19406                mCurrentUserId, false /* enabledOnly */);
19407        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
19408        for (int i = 0; i < currentProfileIds.length; i++) {
19409            currentProfileIds[i] = profiles.get(i).id;
19410        }
19411        mCurrentProfileIds = currentProfileIds;
19412
19413        synchronized (mUserProfileGroupIdsSelfLocked) {
19414            mUserProfileGroupIdsSelfLocked.clear();
19415            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
19416            for (int i = 0; i < users.size(); i++) {
19417                UserInfo user = users.get(i);
19418                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
19419                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
19420                }
19421            }
19422        }
19423    }
19424
19425    private Set<Integer> getProfileIdsLocked(int userId) {
19426        Set<Integer> userIds = new HashSet<Integer>();
19427        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19428                userId, false /* enabledOnly */);
19429        for (UserInfo user : profiles) {
19430            userIds.add(Integer.valueOf(user.id));
19431        }
19432        return userIds;
19433    }
19434
19435    @Override
19436    public boolean switchUser(final int userId) {
19437        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19438        String userName;
19439        synchronized (this) {
19440            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19441            if (userInfo == null) {
19442                Slog.w(TAG, "No user info for user #" + userId);
19443                return false;
19444            }
19445            if (userInfo.isManagedProfile()) {
19446                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19447                return false;
19448            }
19449            userName = userInfo.name;
19450            mTargetUserId = userId;
19451        }
19452        mUiHandler.removeMessages(START_USER_SWITCH_MSG);
19453        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
19454        return true;
19455    }
19456
19457    private void showUserSwitchDialog(int userId, String userName) {
19458        // The dialog will show and then initiate the user switch by calling startUserInForeground
19459        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
19460                true /* above system */);
19461        d.show();
19462    }
19463
19464    private boolean startUser(final int userId, final boolean foreground) {
19465        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19466                != PackageManager.PERMISSION_GRANTED) {
19467            String msg = "Permission Denial: switchUser() from pid="
19468                    + Binder.getCallingPid()
19469                    + ", uid=" + Binder.getCallingUid()
19470                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19471            Slog.w(TAG, msg);
19472            throw new SecurityException(msg);
19473        }
19474
19475        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
19476
19477        final long ident = Binder.clearCallingIdentity();
19478        try {
19479            synchronized (this) {
19480                final int oldUserId = mCurrentUserId;
19481                if (oldUserId == userId) {
19482                    return true;
19483                }
19484
19485                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
19486                        "startUser", false);
19487
19488                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19489                if (userInfo == null) {
19490                    Slog.w(TAG, "No user info for user #" + userId);
19491                    return false;
19492                }
19493                if (foreground && userInfo.isManagedProfile()) {
19494                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19495                    return false;
19496                }
19497
19498                if (foreground) {
19499                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
19500                            R.anim.screen_user_enter);
19501                }
19502
19503                boolean needStart = false;
19504
19505                // If the user we are switching to is not currently started, then
19506                // we need to start it now.
19507                if (mStartedUsers.get(userId) == null) {
19508                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
19509                    updateStartedUserArrayLocked();
19510                    needStart = true;
19511                }
19512
19513                final Integer userIdInt = Integer.valueOf(userId);
19514                mUserLru.remove(userIdInt);
19515                mUserLru.add(userIdInt);
19516
19517                if (foreground) {
19518                    mCurrentUserId = userId;
19519                    updateUserConfigurationLocked();
19520                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
19521                    updateCurrentProfileIdsLocked();
19522                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
19523                    // Once the internal notion of the active user has switched, we lock the device
19524                    // with the option to show the user switcher on the keyguard.
19525                    mWindowManager.lockNow(null);
19526                } else {
19527                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
19528                    updateCurrentProfileIdsLocked();
19529                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
19530                    mUserLru.remove(currentUserIdInt);
19531                    mUserLru.add(currentUserIdInt);
19532                }
19533
19534                final UserStartedState uss = mStartedUsers.get(userId);
19535
19536                // Make sure user is in the started state.  If it is currently
19537                // stopping, we need to knock that off.
19538                if (uss.mState == UserStartedState.STATE_STOPPING) {
19539                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
19540                    // so we can just fairly silently bring the user back from
19541                    // the almost-dead.
19542                    uss.mState = UserStartedState.STATE_RUNNING;
19543                    updateStartedUserArrayLocked();
19544                    needStart = true;
19545                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
19546                    // This means ACTION_SHUTDOWN has been sent, so we will
19547                    // need to treat this as a new boot of the user.
19548                    uss.mState = UserStartedState.STATE_BOOTING;
19549                    updateStartedUserArrayLocked();
19550                    needStart = true;
19551                }
19552
19553                if (uss.mState == UserStartedState.STATE_BOOTING) {
19554                    // Booting up a new user, need to tell system services about it.
19555                    // Note that this is on the same handler as scheduling of broadcasts,
19556                    // which is important because it needs to go first.
19557                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
19558                }
19559
19560                if (foreground) {
19561                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
19562                            oldUserId));
19563                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
19564                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19565                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
19566                            oldUserId, userId, uss));
19567                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
19568                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
19569                }
19570
19571                if (needStart) {
19572                    // Send USER_STARTED broadcast
19573                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
19574                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19575                            | Intent.FLAG_RECEIVER_FOREGROUND);
19576                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19577                    broadcastIntentLocked(null, null, intent,
19578                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19579                            false, false, MY_PID, Process.SYSTEM_UID, userId);
19580                }
19581
19582                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
19583                    if (userId != UserHandle.USER_OWNER) {
19584                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
19585                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19586                        broadcastIntentLocked(null, null, intent, null,
19587                                new IIntentReceiver.Stub() {
19588                                    public void performReceive(Intent intent, int resultCode,
19589                                            String data, Bundle extras, boolean ordered,
19590                                            boolean sticky, int sendingUser) {
19591                                        onUserInitialized(uss, foreground, oldUserId, userId);
19592                                    }
19593                                }, 0, null, null, null, AppOpsManager.OP_NONE,
19594                                true, false, MY_PID, Process.SYSTEM_UID,
19595                                userId);
19596                        uss.initializing = true;
19597                    } else {
19598                        getUserManagerLocked().makeInitialized(userInfo.id);
19599                    }
19600                }
19601
19602                if (foreground) {
19603                    if (!uss.initializing) {
19604                        moveUserToForegroundLocked(uss, oldUserId, userId);
19605                    }
19606                } else {
19607                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
19608                }
19609
19610                if (needStart) {
19611                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
19612                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19613                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19614                    broadcastIntentLocked(null, null, intent,
19615                            null, new IIntentReceiver.Stub() {
19616                                @Override
19617                                public void performReceive(Intent intent, int resultCode, String data,
19618                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
19619                                        throws RemoteException {
19620                                }
19621                            }, 0, null, null,
19622                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19623                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19624                }
19625            }
19626        } finally {
19627            Binder.restoreCallingIdentity(ident);
19628        }
19629
19630        return true;
19631    }
19632
19633    void dispatchForegroundProfileChanged(int userId) {
19634        final int N = mUserSwitchObservers.beginBroadcast();
19635        for (int i = 0; i < N; i++) {
19636            try {
19637                mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
19638            } catch (RemoteException e) {
19639                // Ignore
19640            }
19641        }
19642        mUserSwitchObservers.finishBroadcast();
19643    }
19644
19645    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
19646        long ident = Binder.clearCallingIdentity();
19647        try {
19648            Intent intent;
19649            if (oldUserId >= 0) {
19650                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
19651                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
19652                int count = profiles.size();
19653                for (int i = 0; i < count; i++) {
19654                    int profileUserId = profiles.get(i).id;
19655                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
19656                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19657                            | Intent.FLAG_RECEIVER_FOREGROUND);
19658                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19659                    broadcastIntentLocked(null, null, intent,
19660                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19661                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19662                }
19663            }
19664            if (newUserId >= 0) {
19665                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
19666                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
19667                int count = profiles.size();
19668                for (int i = 0; i < count; i++) {
19669                    int profileUserId = profiles.get(i).id;
19670                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
19671                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19672                            | Intent.FLAG_RECEIVER_FOREGROUND);
19673                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19674                    broadcastIntentLocked(null, null, intent,
19675                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19676                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19677                }
19678                intent = new Intent(Intent.ACTION_USER_SWITCHED);
19679                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19680                        | Intent.FLAG_RECEIVER_FOREGROUND);
19681                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
19682                broadcastIntentLocked(null, null, intent,
19683                        null, null, 0, null, null,
19684                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
19685                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19686            }
19687        } finally {
19688            Binder.restoreCallingIdentity(ident);
19689        }
19690    }
19691
19692    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
19693            final int newUserId) {
19694        final int N = mUserSwitchObservers.beginBroadcast();
19695        if (N > 0) {
19696            final IRemoteCallback callback = new IRemoteCallback.Stub() {
19697                int mCount = 0;
19698                @Override
19699                public void sendResult(Bundle data) throws RemoteException {
19700                    synchronized (ActivityManagerService.this) {
19701                        if (mCurUserSwitchCallback == this) {
19702                            mCount++;
19703                            if (mCount == N) {
19704                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19705                            }
19706                        }
19707                    }
19708                }
19709            };
19710            synchronized (this) {
19711                uss.switching = true;
19712                mCurUserSwitchCallback = callback;
19713            }
19714            for (int i=0; i<N; i++) {
19715                try {
19716                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
19717                            newUserId, callback);
19718                } catch (RemoteException e) {
19719                }
19720            }
19721        } else {
19722            synchronized (this) {
19723                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19724            }
19725        }
19726        mUserSwitchObservers.finishBroadcast();
19727    }
19728
19729    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
19730        synchronized (this) {
19731            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
19732            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19733        }
19734    }
19735
19736    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
19737        mCurUserSwitchCallback = null;
19738        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19739        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
19740                oldUserId, newUserId, uss));
19741    }
19742
19743    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
19744        synchronized (this) {
19745            if (foreground) {
19746                moveUserToForegroundLocked(uss, oldUserId, newUserId);
19747            }
19748        }
19749
19750        completeSwitchAndInitalize(uss, newUserId, true, false);
19751    }
19752
19753    void moveUserToForegroundLocked(UserStartedState uss, int oldUserId, int newUserId) {
19754        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
19755        if (homeInFront) {
19756            startHomeActivityLocked(newUserId, "moveUserToFroreground");
19757        } else {
19758            mStackSupervisor.resumeTopActivitiesLocked();
19759        }
19760        EventLogTags.writeAmSwitchUser(newUserId);
19761        getUserManagerLocked().onUserForeground(newUserId);
19762        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
19763    }
19764
19765    private void updateUserConfigurationLocked() {
19766        Configuration configuration = new Configuration(mConfiguration);
19767        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
19768                mCurrentUserId);
19769        updateConfigurationLocked(configuration, null, false);
19770    }
19771
19772    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
19773        completeSwitchAndInitalize(uss, newUserId, false, true);
19774    }
19775
19776    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
19777            boolean clearInitializing, boolean clearSwitching) {
19778        boolean unfrozen = false;
19779        synchronized (this) {
19780            if (clearInitializing) {
19781                uss.initializing = false;
19782                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
19783            }
19784            if (clearSwitching) {
19785                uss.switching = false;
19786            }
19787            if (!uss.switching && !uss.initializing) {
19788                mWindowManager.stopFreezingScreen();
19789                unfrozen = true;
19790            }
19791        }
19792        if (unfrozen) {
19793            final int N = mUserSwitchObservers.beginBroadcast();
19794            for (int i=0; i<N; i++) {
19795                try {
19796                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
19797                } catch (RemoteException e) {
19798                }
19799            }
19800            mUserSwitchObservers.finishBroadcast();
19801        }
19802        stopGuestUserIfBackground();
19803    }
19804
19805    /**
19806     * Stops the guest user if it has gone to the background.
19807     */
19808    private void stopGuestUserIfBackground() {
19809        synchronized (this) {
19810            final int num = mUserLru.size();
19811            for (int i = 0; i < num; i++) {
19812                Integer oldUserId = mUserLru.get(i);
19813                UserStartedState oldUss = mStartedUsers.get(oldUserId);
19814                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
19815                        || oldUss.mState == UserStartedState.STATE_STOPPING
19816                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19817                    continue;
19818                }
19819                UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
19820                if (userInfo.isGuest()) {
19821                    // This is a user to be stopped.
19822                    stopUserLocked(oldUserId, null);
19823                    break;
19824                }
19825            }
19826        }
19827    }
19828
19829    void scheduleStartProfilesLocked() {
19830        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
19831            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
19832                    DateUtils.SECOND_IN_MILLIS);
19833        }
19834    }
19835
19836    void startProfilesLocked() {
19837        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
19838        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19839                mCurrentUserId, false /* enabledOnly */);
19840        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
19841        for (UserInfo user : profiles) {
19842            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
19843                    && user.id != mCurrentUserId) {
19844                toStart.add(user);
19845            }
19846        }
19847        final int n = toStart.size();
19848        int i = 0;
19849        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
19850            startUserInBackground(toStart.get(i).id);
19851        }
19852        if (i < n) {
19853            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
19854        }
19855    }
19856
19857    void finishUserBoot(UserStartedState uss) {
19858        synchronized (this) {
19859            if (uss.mState == UserStartedState.STATE_BOOTING
19860                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
19861                uss.mState = UserStartedState.STATE_RUNNING;
19862                final int userId = uss.mHandle.getIdentifier();
19863                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
19864                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19865                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
19866                broadcastIntentLocked(null, null, intent,
19867                        null, null, 0, null, null,
19868                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
19869                        true, false, MY_PID, Process.SYSTEM_UID, userId);
19870            }
19871        }
19872    }
19873
19874    void finishUserSwitch(UserStartedState uss) {
19875        synchronized (this) {
19876            finishUserBoot(uss);
19877
19878            startProfilesLocked();
19879
19880            int num = mUserLru.size();
19881            int i = 0;
19882            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
19883                Integer oldUserId = mUserLru.get(i);
19884                UserStartedState oldUss = mStartedUsers.get(oldUserId);
19885                if (oldUss == null) {
19886                    // Shouldn't happen, but be sane if it does.
19887                    mUserLru.remove(i);
19888                    num--;
19889                    continue;
19890                }
19891                if (oldUss.mState == UserStartedState.STATE_STOPPING
19892                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19893                    // This user is already stopping, doesn't count.
19894                    num--;
19895                    i++;
19896                    continue;
19897                }
19898                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
19899                    // Owner and current can't be stopped, but count as running.
19900                    i++;
19901                    continue;
19902                }
19903                // This is a user to be stopped.
19904                stopUserLocked(oldUserId, null);
19905                num--;
19906                i++;
19907            }
19908        }
19909    }
19910
19911    @Override
19912    public int stopUser(final int userId, final IStopUserCallback callback) {
19913        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19914                != PackageManager.PERMISSION_GRANTED) {
19915            String msg = "Permission Denial: switchUser() from pid="
19916                    + Binder.getCallingPid()
19917                    + ", uid=" + Binder.getCallingUid()
19918                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19919            Slog.w(TAG, msg);
19920            throw new SecurityException(msg);
19921        }
19922        if (userId < 0 || userId == UserHandle.USER_OWNER) {
19923            throw new IllegalArgumentException("Can't stop primary user " + userId);
19924        }
19925        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19926        synchronized (this) {
19927            return stopUserLocked(userId, callback);
19928        }
19929    }
19930
19931    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
19932        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
19933        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
19934            return ActivityManager.USER_OP_IS_CURRENT;
19935        }
19936
19937        final UserStartedState uss = mStartedUsers.get(userId);
19938        if (uss == null) {
19939            // User is not started, nothing to do...  but we do need to
19940            // callback if requested.
19941            if (callback != null) {
19942                mHandler.post(new Runnable() {
19943                    @Override
19944                    public void run() {
19945                        try {
19946                            callback.userStopped(userId);
19947                        } catch (RemoteException e) {
19948                        }
19949                    }
19950                });
19951            }
19952            return ActivityManager.USER_OP_SUCCESS;
19953        }
19954
19955        if (callback != null) {
19956            uss.mStopCallbacks.add(callback);
19957        }
19958
19959        if (uss.mState != UserStartedState.STATE_STOPPING
19960                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19961            uss.mState = UserStartedState.STATE_STOPPING;
19962            updateStartedUserArrayLocked();
19963
19964            long ident = Binder.clearCallingIdentity();
19965            try {
19966                // We are going to broadcast ACTION_USER_STOPPING and then
19967                // once that is done send a final ACTION_SHUTDOWN and then
19968                // stop the user.
19969                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
19970                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19971                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19972                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
19973                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
19974                // This is the result receiver for the final shutdown broadcast.
19975                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
19976                    @Override
19977                    public void performReceive(Intent intent, int resultCode, String data,
19978                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19979                        finishUserStop(uss);
19980                    }
19981                };
19982                // This is the result receiver for the initial stopping broadcast.
19983                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
19984                    @Override
19985                    public void performReceive(Intent intent, int resultCode, String data,
19986                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19987                        // On to the next.
19988                        synchronized (ActivityManagerService.this) {
19989                            if (uss.mState != UserStartedState.STATE_STOPPING) {
19990                                // Whoops, we are being started back up.  Abort, abort!
19991                                return;
19992                            }
19993                            uss.mState = UserStartedState.STATE_SHUTDOWN;
19994                        }
19995                        mBatteryStatsService.noteEvent(
19996                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
19997                                Integer.toString(userId), userId);
19998                        mSystemServiceManager.stopUser(userId);
19999                        broadcastIntentLocked(null, null, shutdownIntent,
20000                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
20001                                true, false, MY_PID, Process.SYSTEM_UID, userId);
20002                    }
20003                };
20004                // Kick things off.
20005                broadcastIntentLocked(null, null, stoppingIntent,
20006                        null, stoppingReceiver, 0, null, null,
20007                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
20008                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
20009            } finally {
20010                Binder.restoreCallingIdentity(ident);
20011            }
20012        }
20013
20014        return ActivityManager.USER_OP_SUCCESS;
20015    }
20016
20017    void finishUserStop(UserStartedState uss) {
20018        final int userId = uss.mHandle.getIdentifier();
20019        boolean stopped;
20020        ArrayList<IStopUserCallback> callbacks;
20021        synchronized (this) {
20022            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
20023            if (mStartedUsers.get(userId) != uss) {
20024                stopped = false;
20025            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
20026                stopped = false;
20027            } else {
20028                stopped = true;
20029                // User can no longer run.
20030                mStartedUsers.remove(userId);
20031                mUserLru.remove(Integer.valueOf(userId));
20032                updateStartedUserArrayLocked();
20033
20034                // Clean up all state and processes associated with the user.
20035                // Kill all the processes for the user.
20036                forceStopUserLocked(userId, "finish user");
20037            }
20038
20039            // Explicitly remove the old information in mRecentTasks.
20040            mRecentTasks.removeTasksForUserLocked(userId);
20041        }
20042
20043        for (int i=0; i<callbacks.size(); i++) {
20044            try {
20045                if (stopped) callbacks.get(i).userStopped(userId);
20046                else callbacks.get(i).userStopAborted(userId);
20047            } catch (RemoteException e) {
20048            }
20049        }
20050
20051        if (stopped) {
20052            mSystemServiceManager.cleanupUser(userId);
20053            synchronized (this) {
20054                mStackSupervisor.removeUserLocked(userId);
20055            }
20056        }
20057    }
20058
20059    @Override
20060    public UserInfo getCurrentUser() {
20061        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
20062                != PackageManager.PERMISSION_GRANTED) && (
20063                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20064                != PackageManager.PERMISSION_GRANTED)) {
20065            String msg = "Permission Denial: getCurrentUser() from pid="
20066                    + Binder.getCallingPid()
20067                    + ", uid=" + Binder.getCallingUid()
20068                    + " requires " + INTERACT_ACROSS_USERS;
20069            Slog.w(TAG, msg);
20070            throw new SecurityException(msg);
20071        }
20072        synchronized (this) {
20073            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20074            return getUserManagerLocked().getUserInfo(userId);
20075        }
20076    }
20077
20078    int getCurrentUserIdLocked() {
20079        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20080    }
20081
20082    @Override
20083    public boolean isUserRunning(int userId, boolean orStopped) {
20084        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20085                != PackageManager.PERMISSION_GRANTED) {
20086            String msg = "Permission Denial: isUserRunning() from pid="
20087                    + Binder.getCallingPid()
20088                    + ", uid=" + Binder.getCallingUid()
20089                    + " requires " + INTERACT_ACROSS_USERS;
20090            Slog.w(TAG, msg);
20091            throw new SecurityException(msg);
20092        }
20093        synchronized (this) {
20094            return isUserRunningLocked(userId, orStopped);
20095        }
20096    }
20097
20098    boolean isUserRunningLocked(int userId, boolean orStopped) {
20099        UserStartedState state = mStartedUsers.get(userId);
20100        if (state == null) {
20101            return false;
20102        }
20103        if (orStopped) {
20104            return true;
20105        }
20106        return state.mState != UserStartedState.STATE_STOPPING
20107                && state.mState != UserStartedState.STATE_SHUTDOWN;
20108    }
20109
20110    @Override
20111    public int[] getRunningUserIds() {
20112        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20113                != PackageManager.PERMISSION_GRANTED) {
20114            String msg = "Permission Denial: isUserRunning() from pid="
20115                    + Binder.getCallingPid()
20116                    + ", uid=" + Binder.getCallingUid()
20117                    + " requires " + INTERACT_ACROSS_USERS;
20118            Slog.w(TAG, msg);
20119            throw new SecurityException(msg);
20120        }
20121        synchronized (this) {
20122            return mStartedUserArray;
20123        }
20124    }
20125
20126    private void updateStartedUserArrayLocked() {
20127        int num = 0;
20128        for (int i=0; i<mStartedUsers.size();  i++) {
20129            UserStartedState uss = mStartedUsers.valueAt(i);
20130            // This list does not include stopping users.
20131            if (uss.mState != UserStartedState.STATE_STOPPING
20132                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
20133                num++;
20134            }
20135        }
20136        mStartedUserArray = new int[num];
20137        num = 0;
20138        for (int i=0; i<mStartedUsers.size();  i++) {
20139            UserStartedState uss = mStartedUsers.valueAt(i);
20140            if (uss.mState != UserStartedState.STATE_STOPPING
20141                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
20142                mStartedUserArray[num] = mStartedUsers.keyAt(i);
20143                num++;
20144            }
20145        }
20146    }
20147
20148    @Override
20149    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20150        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20151                != PackageManager.PERMISSION_GRANTED) {
20152            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
20153                    + Binder.getCallingPid()
20154                    + ", uid=" + Binder.getCallingUid()
20155                    + " requires " + INTERACT_ACROSS_USERS_FULL;
20156            Slog.w(TAG, msg);
20157            throw new SecurityException(msg);
20158        }
20159
20160        mUserSwitchObservers.register(observer);
20161    }
20162
20163    @Override
20164    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20165        mUserSwitchObservers.unregister(observer);
20166    }
20167
20168    int[] getUsersLocked() {
20169        UserManagerService ums = getUserManagerLocked();
20170        return ums != null ? ums.getUserIds() : new int[] { 0 };
20171    }
20172
20173    UserManagerService getUserManagerLocked() {
20174        if (mUserManager == null) {
20175            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
20176            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
20177        }
20178        return mUserManager;
20179    }
20180
20181    private int applyUserId(int uid, int userId) {
20182        return UserHandle.getUid(userId, uid);
20183    }
20184
20185    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20186        if (info == null) return null;
20187        ApplicationInfo newInfo = new ApplicationInfo(info);
20188        newInfo.uid = applyUserId(info.uid, userId);
20189        newInfo.dataDir = PackageManager.getDataDirForUser(info.volumeUuid, info.packageName,
20190                userId).getAbsolutePath();
20191        return newInfo;
20192    }
20193
20194    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20195        if (aInfo == null
20196                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20197            return aInfo;
20198        }
20199
20200        ActivityInfo info = new ActivityInfo(aInfo);
20201        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20202        return info;
20203    }
20204
20205    private final class LocalService extends ActivityManagerInternal {
20206        @Override
20207        public void onWakefulnessChanged(int wakefulness) {
20208            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20209        }
20210
20211        @Override
20212        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20213                String processName, String abiOverride, int uid, Runnable crashHandler) {
20214            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20215                    processName, abiOverride, uid, crashHandler);
20216        }
20217
20218        @Override
20219        public SleepToken acquireSleepToken(String tag) {
20220            Preconditions.checkNotNull(tag);
20221
20222            synchronized (ActivityManagerService.this) {
20223                SleepTokenImpl token = new SleepTokenImpl(tag);
20224                mSleepTokens.add(token);
20225                updateSleepIfNeededLocked();
20226                return token;
20227            }
20228        }
20229
20230        @Override
20231        public ComponentName getHomeActivityForUser(int userId) {
20232            synchronized (ActivityManagerService.this) {
20233                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20234                return homeActivity == null ? null : homeActivity.realActivity;
20235            }
20236        }
20237    }
20238
20239    private final class SleepTokenImpl extends SleepToken {
20240        private final String mTag;
20241        private final long mAcquireTime;
20242
20243        public SleepTokenImpl(String tag) {
20244            mTag = tag;
20245            mAcquireTime = SystemClock.uptimeMillis();
20246        }
20247
20248        @Override
20249        public void release() {
20250            synchronized (ActivityManagerService.this) {
20251                if (mSleepTokens.remove(this)) {
20252                    updateSleepIfNeededLocked();
20253                }
20254            }
20255        }
20256
20257        @Override
20258        public String toString() {
20259            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20260        }
20261    }
20262
20263    /**
20264     * An implementation of IAppTask, that allows an app to manage its own tasks via
20265     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
20266     * only the process that calls getAppTasks() can call the AppTask methods.
20267     */
20268    class AppTaskImpl extends IAppTask.Stub {
20269        private int mTaskId;
20270        private int mCallingUid;
20271
20272        public AppTaskImpl(int taskId, int callingUid) {
20273            mTaskId = taskId;
20274            mCallingUid = callingUid;
20275        }
20276
20277        private void checkCaller() {
20278            if (mCallingUid != Binder.getCallingUid()) {
20279                throw new SecurityException("Caller " + mCallingUid
20280                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
20281            }
20282        }
20283
20284        @Override
20285        public void finishAndRemoveTask() {
20286            checkCaller();
20287
20288            synchronized (ActivityManagerService.this) {
20289                long origId = Binder.clearCallingIdentity();
20290                try {
20291                    if (!removeTaskByIdLocked(mTaskId, false)) {
20292                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20293                    }
20294                } finally {
20295                    Binder.restoreCallingIdentity(origId);
20296                }
20297            }
20298        }
20299
20300        @Override
20301        public ActivityManager.RecentTaskInfo getTaskInfo() {
20302            checkCaller();
20303
20304            synchronized (ActivityManagerService.this) {
20305                long origId = Binder.clearCallingIdentity();
20306                try {
20307                    TaskRecord tr = mRecentTasks.taskForIdLocked(mTaskId);
20308                    if (tr == null) {
20309                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20310                    }
20311                    return createRecentTaskInfoFromTaskRecord(tr);
20312                } finally {
20313                    Binder.restoreCallingIdentity(origId);
20314                }
20315            }
20316        }
20317
20318        @Override
20319        public void moveToFront() {
20320            checkCaller();
20321            // Will bring task to front if it already has a root activity.
20322            startActivityFromRecentsInner(mTaskId, null);
20323        }
20324
20325        @Override
20326        public int startActivity(IBinder whoThread, String callingPackage,
20327                Intent intent, String resolvedType, Bundle options) {
20328            checkCaller();
20329
20330            int callingUser = UserHandle.getCallingUserId();
20331            TaskRecord tr;
20332            IApplicationThread appThread;
20333            synchronized (ActivityManagerService.this) {
20334                tr = mRecentTasks.taskForIdLocked(mTaskId);
20335                if (tr == null) {
20336                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20337                }
20338                appThread = ApplicationThreadNative.asInterface(whoThread);
20339                if (appThread == null) {
20340                    throw new IllegalArgumentException("Bad app thread " + appThread);
20341                }
20342            }
20343            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
20344                    resolvedType, null, null, null, null, 0, 0, null, null,
20345                    null, options, callingUser, null, tr);
20346        }
20347
20348        @Override
20349        public void setExcludeFromRecents(boolean exclude) {
20350            checkCaller();
20351
20352            synchronized (ActivityManagerService.this) {
20353                long origId = Binder.clearCallingIdentity();
20354                try {
20355                    TaskRecord tr = mRecentTasks.taskForIdLocked(mTaskId);
20356                    if (tr == null) {
20357                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20358                    }
20359                    Intent intent = tr.getBaseIntent();
20360                    if (exclude) {
20361                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20362                    } else {
20363                        intent.setFlags(intent.getFlags()
20364                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20365                    }
20366                } finally {
20367                    Binder.restoreCallingIdentity(origId);
20368                }
20369            }
20370        }
20371    }
20372}
20373