ActivityManagerService.java revision 15df08abd8190353e1430f88c2ed6462d72a5b25
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 com.android.server.am.TaskRecord.LOCK_TASK_AUTH_WHITELISTED;
37import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
38import static org.xmlpull.v1.XmlPullParser.START_TAG;
39
40import android.Manifest;
41import android.app.AppOpsManager;
42import android.app.ApplicationThreadNative;
43import android.app.IActivityContainer;
44import android.app.IActivityContainerCallback;
45import android.app.IAppTask;
46import android.app.ITaskStackListener;
47import android.app.ProfilerInfo;
48import android.app.usage.UsageEvents;
49import android.app.usage.UsageStatsManagerInternal;
50import android.appwidget.AppWidgetManager;
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.ActivityManagerNative;
118import android.app.ActivityOptions;
119import android.app.ActivityThread;
120import android.app.AlertDialog;
121import android.app.AppGlobals;
122import android.app.ApplicationErrorReport;
123import android.app.Dialog;
124import android.app.IActivityController;
125import android.app.IApplicationThread;
126import android.app.IInstrumentationWatcher;
127import android.app.INotificationManager;
128import android.app.IProcessObserver;
129import android.app.IServiceConnection;
130import android.app.IStopUserCallback;
131import android.app.IUiAutomationConnection;
132import android.app.IUserSwitchObserver;
133import android.app.Instrumentation;
134import android.app.Notification;
135import android.app.NotificationManager;
136import android.app.PendingIntent;
137import android.app.backup.IBackupManager;
138import android.content.ActivityNotFoundException;
139import android.content.BroadcastReceiver;
140import android.content.ClipData;
141import android.content.ComponentCallbacks2;
142import android.content.ComponentName;
143import android.content.ContentProvider;
144import android.content.ContentResolver;
145import android.content.Context;
146import android.content.DialogInterface;
147import android.content.IContentProvider;
148import android.content.IIntentReceiver;
149import android.content.IIntentSender;
150import android.content.Intent;
151import android.content.IntentFilter;
152import android.content.IntentSender;
153import android.content.pm.ActivityInfo;
154import android.content.pm.ApplicationInfo;
155import android.content.pm.ConfigurationInfo;
156import android.content.pm.IPackageDataObserver;
157import android.content.pm.IPackageManager;
158import android.content.pm.InstrumentationInfo;
159import android.content.pm.PackageInfo;
160import android.content.pm.PackageManager;
161import android.content.pm.ParceledListSlice;
162import android.content.pm.UserInfo;
163import android.content.pm.PackageManager.NameNotFoundException;
164import android.content.pm.PathPermission;
165import android.content.pm.ProviderInfo;
166import android.content.pm.ResolveInfo;
167import android.content.pm.ServiceInfo;
168import android.content.res.CompatibilityInfo;
169import android.content.res.Configuration;
170import android.net.Proxy;
171import android.net.ProxyInfo;
172import android.net.Uri;
173import android.os.Binder;
174import android.os.Build;
175import android.os.Bundle;
176import android.os.Debug;
177import android.os.DropBoxManager;
178import android.os.Environment;
179import android.os.FactoryTest;
180import android.os.FileObserver;
181import android.os.FileUtils;
182import android.os.Handler;
183import android.os.IBinder;
184import android.os.IPermissionController;
185import android.os.IProcessInfoService;
186import android.os.IRemoteCallback;
187import android.os.IUserManager;
188import android.os.Looper;
189import android.os.Message;
190import android.os.Parcel;
191import android.os.ParcelFileDescriptor;
192import android.os.PowerManagerInternal;
193import android.os.Process;
194import android.os.RemoteCallbackList;
195import android.os.RemoteException;
196import android.os.SELinux;
197import android.os.ServiceManager;
198import android.os.StrictMode;
199import android.os.SystemClock;
200import android.os.SystemProperties;
201import android.os.UpdateLock;
202import android.os.UserHandle;
203import android.os.UserManager;
204import android.provider.Settings;
205import android.text.format.DateUtils;
206import android.text.format.Time;
207import android.util.AtomicFile;
208import android.util.EventLog;
209import android.util.Log;
210import android.util.Pair;
211import android.util.PrintWriterPrinter;
212import android.util.Slog;
213import android.util.SparseArray;
214import android.util.TimeUtils;
215import android.util.Xml;
216import android.view.Gravity;
217import android.view.LayoutInflater;
218import android.view.View;
219import android.view.WindowManager;
220
221import dalvik.system.VMRuntime;
222
223import java.io.BufferedInputStream;
224import java.io.BufferedOutputStream;
225import java.io.DataInputStream;
226import java.io.DataOutputStream;
227import java.io.File;
228import java.io.FileDescriptor;
229import java.io.FileInputStream;
230import java.io.FileNotFoundException;
231import java.io.FileOutputStream;
232import java.io.IOException;
233import java.io.InputStreamReader;
234import java.io.PrintWriter;
235import java.io.StringWriter;
236import java.lang.ref.WeakReference;
237import java.util.ArrayList;
238import java.util.Arrays;
239import java.util.Collections;
240import java.util.Comparator;
241import java.util.HashMap;
242import java.util.HashSet;
243import java.util.Iterator;
244import java.util.List;
245import java.util.Locale;
246import java.util.Map;
247import java.util.Set;
248import java.util.concurrent.atomic.AtomicBoolean;
249import java.util.concurrent.atomic.AtomicLong;
250
251public final class ActivityManagerService extends ActivityManagerNative
252        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
253
254    private static final String USER_DATA_DIR = "/data/user/";
255    // File that stores last updated system version and called preboot receivers
256    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
257
258    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
259    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
260    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
261    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
262    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
263    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
264    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
265    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
266    private static final String TAG_LRU = TAG + POSTFIX_LRU;
267    private static final String TAG_MU = TAG + POSTFIX_MU;
268    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
269    private static final String TAG_POWER = TAG + POSTFIX_POWER;
270    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
271    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
272    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
273    private static final String TAG_PSS = TAG + POSTFIX_PSS;
274    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
275    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
276    private static final String TAG_STACK = TAG + POSTFIX_STACK;
277    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
278    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
279    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
280
281    /** Control over CPU and battery monitoring */
282    // write battery stats every 30 minutes.
283    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
284    static final boolean MONITOR_CPU_USAGE = true;
285    // don't sample cpu less than every 5 seconds.
286    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
287    // wait possibly forever for next cpu sample.
288    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
289    static final boolean MONITOR_THREAD_CPU_USAGE = false;
290
291    // The flags that are set for all calls we make to the package manager.
292    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
293
294    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
295
296    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
297
298    // Amount of time after a call to stopAppSwitches() during which we will
299    // prevent further untrusted switches from happening.
300    static final long APP_SWITCH_DELAY_TIME = 5*1000;
301
302    // How long we wait for a launched process to attach to the activity manager
303    // before we decide it's never going to come up for real.
304    static final int PROC_START_TIMEOUT = 10*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, when the process was
308    // started with a wrapper for instrumentation (such as Valgrind) because it
309    // could take much longer than usual.
310    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
311
312    // How long to wait after going idle before forcing apps to GC.
313    static final int GC_TIMEOUT = 5*1000;
314
315    // The minimum amount of time between successive GC requests for a process.
316    static final int GC_MIN_INTERVAL = 60*1000;
317
318    // The minimum amount of time between successive PSS requests for a process.
319    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
320
321    // The minimum amount of time between successive PSS requests for a process
322    // when the request is due to the memory state being lowered.
323    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
324
325    // The rate at which we check for apps using excessive power -- 15 mins.
326    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
327
328    // The minimum sample duration we will allow before deciding we have
329    // enough data on wake locks to start killing things.
330    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
331
332    // The minimum sample duration we will allow before deciding we have
333    // enough data on CPU usage to start killing things.
334    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
335
336    // How long we allow a receiver to run before giving up on it.
337    static final int BROADCAST_FG_TIMEOUT = 10*1000;
338    static final int BROADCAST_BG_TIMEOUT = 60*1000;
339
340    // How long we wait until we timeout on key dispatching.
341    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
342
343    // How long we wait until we timeout on key dispatching during instrumentation.
344    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
345
346    // Amount of time we wait for observers to handle a user switch before
347    // giving up on them and unfreezing the screen.
348    static final int USER_SWITCH_TIMEOUT = 2*1000;
349
350    // Maximum number of users we allow to be running at a time.
351    static final int MAX_RUNNING_USERS = 3;
352
353    // How long to wait in getAssistContextExtras for the activity and foreground services
354    // to respond with the result.
355    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
356
357    // Maximum number of persisted Uri grants a package is allowed
358    static final int MAX_PERSISTED_URI_GRANTS = 128;
359
360    static final int MY_PID = Process.myPid();
361
362    static final String[] EMPTY_STRING_ARRAY = new String[0];
363
364    // How many bytes to write into the dropbox log before truncating
365    static final int DROPBOX_MAX_SIZE = 256 * 1024;
366
367    // Access modes for handleIncomingUser.
368    static final int ALLOW_NON_FULL = 0;
369    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
370    static final int ALLOW_FULL_ONLY = 2;
371
372    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
373
374    // Delay in notifying task stack change listeners (in millis)
375    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
376
377    /** All system services */
378    SystemServiceManager mSystemServiceManager;
379
380    private Installer mInstaller;
381
382    /** Run all ActivityStacks through this */
383    ActivityStackSupervisor mStackSupervisor;
384
385    /** Task stack change listeners. */
386    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
387            new RemoteCallbackList<ITaskStackListener>();
388
389    public IntentFirewall mIntentFirewall;
390
391    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
392    // default actuion automatically.  Important for devices without direct input
393    // devices.
394    private boolean mShowDialogs = true;
395
396    BroadcastQueue mFgBroadcastQueue;
397    BroadcastQueue mBgBroadcastQueue;
398    // Convenient for easy iteration over the queues. Foreground is first
399    // so that dispatch of foreground broadcasts gets precedence.
400    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
401
402    BroadcastQueue broadcastQueueForIntent(Intent intent) {
403        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
404        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
405                "Broadcast intent " + intent + " on "
406                + (isFg ? "foreground" : "background") + " queue");
407        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
408    }
409
410    /**
411     * Activity we have told the window manager to have key focus.
412     */
413    ActivityRecord mFocusedActivity = null;
414
415    /**
416     * List of intents that were used to start the most recent tasks.
417     */
418    private final RecentTasks mRecentTasks;
419
420    /**
421     * For addAppTask: cached of the last activity component that was added.
422     */
423    ComponentName mLastAddedTaskComponent;
424
425    /**
426     * For addAppTask: cached of the last activity uid that was added.
427     */
428    int mLastAddedTaskUid;
429
430    /**
431     * For addAppTask: cached of the last ActivityInfo that was added.
432     */
433    ActivityInfo mLastAddedTaskActivity;
434
435    /**
436     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
437     */
438    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
439
440    public class PendingAssistExtras extends Binder implements Runnable {
441        public final ActivityRecord activity;
442        public final Bundle extras;
443        public final Intent intent;
444        public final String hint;
445        public final IResultReceiver receiver;
446        public final int userHandle;
447        public boolean haveResult = false;
448        public Bundle result = null;
449        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
450                String _hint, IResultReceiver _receiver, int _userHandle) {
451            activity = _activity;
452            extras = _extras;
453            intent = _intent;
454            hint = _hint;
455            receiver = _receiver;
456            userHandle = _userHandle;
457        }
458        @Override
459        public void run() {
460            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
461            synchronized (ActivityManagerService.this) {
462                synchronized (this) {
463                    haveResult = true;
464                    notifyAll();
465                }
466                pendingAssistExtrasTimedOutLocked(this);
467            }
468        }
469    }
470
471    final ArrayList<PendingAssistExtras> mPendingAssistExtras
472            = new ArrayList<PendingAssistExtras>();
473
474    /**
475     * Process management.
476     */
477    final ProcessList mProcessList = new ProcessList();
478
479    /**
480     * All of the applications we currently have running organized by name.
481     * The keys are strings of the application package name (as
482     * returned by the package manager), and the keys are ApplicationRecord
483     * objects.
484     */
485    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
486
487    /**
488     * Tracking long-term execution of processes to look for abuse and other
489     * bad app behavior.
490     */
491    final ProcessStatsService mProcessStats;
492
493    /**
494     * The currently running isolated processes.
495     */
496    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
497
498    /**
499     * Counter for assigning isolated process uids, to avoid frequently reusing the
500     * same ones.
501     */
502    int mNextIsolatedProcessUid = 0;
503
504    /**
505     * The currently running heavy-weight process, if any.
506     */
507    ProcessRecord mHeavyWeightProcess = null;
508
509    /**
510     * The last time that various processes have crashed.
511     */
512    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
513
514    /**
515     * Information about a process that is currently marked as bad.
516     */
517    static final class BadProcessInfo {
518        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
519            this.time = time;
520            this.shortMsg = shortMsg;
521            this.longMsg = longMsg;
522            this.stack = stack;
523        }
524
525        final long time;
526        final String shortMsg;
527        final String longMsg;
528        final String stack;
529    }
530
531    /**
532     * Set of applications that we consider to be bad, and will reject
533     * incoming broadcasts from (which the user has no control over).
534     * Processes are added to this set when they have crashed twice within
535     * a minimum amount of time; they are removed from it when they are
536     * later restarted (hopefully due to some user action).  The value is the
537     * time it was added to the list.
538     */
539    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
540
541    /**
542     * All of the processes we currently have running organized by pid.
543     * The keys are the pid running the application.
544     *
545     * <p>NOTE: This object is protected by its own lock, NOT the global
546     * activity manager lock!
547     */
548    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
549
550    /**
551     * All of the processes that have been forced to be foreground.  The key
552     * is the pid of the caller who requested it (we hold a death
553     * link on it).
554     */
555    abstract class ForegroundToken implements IBinder.DeathRecipient {
556        int pid;
557        IBinder token;
558    }
559    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
560
561    /**
562     * List of records for processes that someone had tried to start before the
563     * system was ready.  We don't start them at that point, but ensure they
564     * are started by the time booting is complete.
565     */
566    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
567
568    /**
569     * List of persistent applications that are in the process
570     * of being started.
571     */
572    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
573
574    /**
575     * Processes that are being forcibly torn down.
576     */
577    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
578
579    /**
580     * List of running applications, sorted by recent usage.
581     * The first entry in the list is the least recently used.
582     */
583    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
584
585    /**
586     * Where in mLruProcesses that the processes hosting activities start.
587     */
588    int mLruProcessActivityStart = 0;
589
590    /**
591     * Where in mLruProcesses that the processes hosting services start.
592     * This is after (lower index) than mLruProcessesActivityStart.
593     */
594    int mLruProcessServiceStart = 0;
595
596    /**
597     * List of processes that should gc as soon as things are idle.
598     */
599    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
600
601    /**
602     * Processes we want to collect PSS data from.
603     */
604    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
605
606    /**
607     * Last time we requested PSS data of all processes.
608     */
609    long mLastFullPssTime = SystemClock.uptimeMillis();
610
611    /**
612     * If set, the next time we collect PSS data we should do a full collection
613     * with data from native processes and the kernel.
614     */
615    boolean mFullPssPending = false;
616
617    /**
618     * This is the process holding what we currently consider to be
619     * the "home" activity.
620     */
621    ProcessRecord mHomeProcess;
622
623    /**
624     * This is the process holding the activity the user last visited that
625     * is in a different process from the one they are currently in.
626     */
627    ProcessRecord mPreviousProcess;
628
629    /**
630     * The time at which the previous process was last visible.
631     */
632    long mPreviousProcessVisibleTime;
633
634    /**
635     * Which uses have been started, so are allowed to run code.
636     */
637    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
638
639    /**
640     * LRU list of history of current users.  Most recently current is at the end.
641     */
642    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
643
644    /**
645     * Constant array of the users that are currently started.
646     */
647    int[] mStartedUserArray = new int[] { 0 };
648
649    /**
650     * Registered observers of the user switching mechanics.
651     */
652    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
653            = new RemoteCallbackList<IUserSwitchObserver>();
654
655    /**
656     * Currently active user switch.
657     */
658    Object mCurUserSwitchCallback;
659
660    /**
661     * Packages that the user has asked to have run in screen size
662     * compatibility mode instead of filling the screen.
663     */
664    final CompatModePackages mCompatModePackages;
665
666    /**
667     * Set of IntentSenderRecord objects that are currently active.
668     */
669    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
670            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
671
672    /**
673     * Fingerprints (hashCode()) of stack traces that we've
674     * already logged DropBox entries for.  Guarded by itself.  If
675     * something (rogue user app) forces this over
676     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
677     */
678    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
679    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
680
681    /**
682     * Strict Mode background batched logging state.
683     *
684     * The string buffer is guarded by itself, and its lock is also
685     * used to determine if another batched write is already
686     * in-flight.
687     */
688    private final StringBuilder mStrictModeBuffer = new StringBuilder();
689
690    /**
691     * Keeps track of all IIntentReceivers that have been registered for
692     * broadcasts.  Hash keys are the receiver IBinder, hash value is
693     * a ReceiverList.
694     */
695    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
696            new HashMap<IBinder, ReceiverList>();
697
698    /**
699     * Resolver for broadcast intents to registered receivers.
700     * Holds BroadcastFilter (subclass of IntentFilter).
701     */
702    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
703            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
704        @Override
705        protected boolean allowFilterResult(
706                BroadcastFilter filter, List<BroadcastFilter> dest) {
707            IBinder target = filter.receiverList.receiver.asBinder();
708            for (int i=dest.size()-1; i>=0; i--) {
709                if (dest.get(i).receiverList.receiver.asBinder() == target) {
710                    return false;
711                }
712            }
713            return true;
714        }
715
716        @Override
717        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
718            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
719                    || userId == filter.owningUserId) {
720                return super.newResult(filter, match, userId);
721            }
722            return null;
723        }
724
725        @Override
726        protected BroadcastFilter[] newArray(int size) {
727            return new BroadcastFilter[size];
728        }
729
730        @Override
731        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
732            return packageName.equals(filter.packageName);
733        }
734    };
735
736    /**
737     * State of all active sticky broadcasts per user.  Keys are the action of the
738     * sticky Intent, values are an ArrayList of all broadcasted intents with
739     * that action (which should usually be one).  The SparseArray is keyed
740     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
741     * for stickies that are sent to all users.
742     */
743    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
744            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
745
746    final ActiveServices mServices;
747
748    final static class Association {
749        final int mSourceUid;
750        final String mSourceProcess;
751        final int mTargetUid;
752        final ComponentName mTargetComponent;
753        final String mTargetProcess;
754
755        int mCount;
756        long mTime;
757
758        int mNesting;
759        long mStartTime;
760
761        Association(int sourceUid, String sourceProcess, int targetUid,
762                ComponentName targetComponent, String targetProcess) {
763            mSourceUid = sourceUid;
764            mSourceProcess = sourceProcess;
765            mTargetUid = targetUid;
766            mTargetComponent = targetComponent;
767            mTargetProcess = targetProcess;
768        }
769    }
770
771    /**
772     * When service association tracking is enabled, this is all of the associations we
773     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
774     * -> association data.
775     */
776    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
777            mAssociations = new SparseArray<>();
778    boolean mTrackingAssociations;
779
780    /**
781     * Backup/restore process management
782     */
783    String mBackupAppName = null;
784    BackupRecord mBackupTarget = null;
785
786    final ProviderMap mProviderMap;
787
788    /**
789     * List of content providers who have clients waiting for them.  The
790     * application is currently being launched and the provider will be
791     * removed from this list once it is published.
792     */
793    final ArrayList<ContentProviderRecord> mLaunchingProviders
794            = new ArrayList<ContentProviderRecord>();
795
796    /**
797     * File storing persisted {@link #mGrantedUriPermissions}.
798     */
799    private final AtomicFile mGrantFile;
800
801    /** XML constants used in {@link #mGrantFile} */
802    private static final String TAG_URI_GRANTS = "uri-grants";
803    private static final String TAG_URI_GRANT = "uri-grant";
804    private static final String ATTR_USER_HANDLE = "userHandle";
805    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
806    private static final String ATTR_TARGET_USER_ID = "targetUserId";
807    private static final String ATTR_SOURCE_PKG = "sourcePkg";
808    private static final String ATTR_TARGET_PKG = "targetPkg";
809    private static final String ATTR_URI = "uri";
810    private static final String ATTR_MODE_FLAGS = "modeFlags";
811    private static final String ATTR_CREATED_TIME = "createdTime";
812    private static final String ATTR_PREFIX = "prefix";
813
814    /**
815     * Global set of specific {@link Uri} permissions that have been granted.
816     * This optimized lookup structure maps from {@link UriPermission#targetUid}
817     * to {@link UriPermission#uri} to {@link UriPermission}.
818     */
819    @GuardedBy("this")
820    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
821            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
822
823    public static class GrantUri {
824        public final int sourceUserId;
825        public final Uri uri;
826        public boolean prefix;
827
828        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
829            this.sourceUserId = sourceUserId;
830            this.uri = uri;
831            this.prefix = prefix;
832        }
833
834        @Override
835        public int hashCode() {
836            int hashCode = 1;
837            hashCode = 31 * hashCode + sourceUserId;
838            hashCode = 31 * hashCode + uri.hashCode();
839            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
840            return hashCode;
841        }
842
843        @Override
844        public boolean equals(Object o) {
845            if (o instanceof GrantUri) {
846                GrantUri other = (GrantUri) o;
847                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
848                        && prefix == other.prefix;
849            }
850            return false;
851        }
852
853        @Override
854        public String toString() {
855            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
856            if (prefix) result += " [prefix]";
857            return result;
858        }
859
860        public String toSafeString() {
861            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
862            if (prefix) result += " [prefix]";
863            return result;
864        }
865
866        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
867            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
868                    ContentProvider.getUriWithoutUserId(uri), false);
869        }
870    }
871
872    CoreSettingsObserver mCoreSettingsObserver;
873
874    /**
875     * Thread-local storage used to carry caller permissions over through
876     * indirect content-provider access.
877     */
878    private class Identity {
879        public final IBinder token;
880        public final int pid;
881        public final int uid;
882
883        Identity(IBinder _token, int _pid, int _uid) {
884            token = _token;
885            pid = _pid;
886            uid = _uid;
887        }
888    }
889
890    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
891
892    /**
893     * All information we have collected about the runtime performance of
894     * any user id that can impact battery performance.
895     */
896    final BatteryStatsService mBatteryStatsService;
897
898    /**
899     * Information about component usage
900     */
901    UsageStatsManagerInternal mUsageStatsService;
902
903    /**
904     * Information about and control over application operations
905     */
906    final AppOpsService mAppOpsService;
907
908    /**
909     * Save recent tasks information across reboots.
910     */
911    final TaskPersister mTaskPersister;
912
913    /**
914     * Current configuration information.  HistoryRecord objects are given
915     * a reference to this object to indicate which configuration they are
916     * currently running in, so this object must be kept immutable.
917     */
918    Configuration mConfiguration = new Configuration();
919
920    /**
921     * Current sequencing integer of the configuration, for skipping old
922     * configurations.
923     */
924    int mConfigurationSeq = 0;
925
926    /**
927     * Hardware-reported OpenGLES version.
928     */
929    final int GL_ES_VERSION;
930
931    /**
932     * List of initialization arguments to pass to all processes when binding applications to them.
933     * For example, references to the commonly used services.
934     */
935    HashMap<String, IBinder> mAppBindArgs;
936
937    /**
938     * Temporary to avoid allocations.  Protected by main lock.
939     */
940    final StringBuilder mStringBuilder = new StringBuilder(256);
941
942    /**
943     * Used to control how we initialize the service.
944     */
945    ComponentName mTopComponent;
946    String mTopAction = Intent.ACTION_MAIN;
947    String mTopData;
948    boolean mProcessesReady = false;
949    boolean mSystemReady = false;
950    boolean mBooting = false;
951    boolean mCallFinishBooting = false;
952    boolean mBootAnimationComplete = false;
953    boolean mWaitingUpdate = false;
954    boolean mDidUpdate = false;
955    boolean mOnBattery = false;
956    boolean mLaunchWarningShown = false;
957
958    Context mContext;
959
960    int mFactoryTest;
961
962    boolean mCheckedForSetup;
963
964    /**
965     * The time at which we will allow normal application switches again,
966     * after a call to {@link #stopAppSwitches()}.
967     */
968    long mAppSwitchesAllowedTime;
969
970    /**
971     * This is set to true after the first switch after mAppSwitchesAllowedTime
972     * is set; any switches after that will clear the time.
973     */
974    boolean mDidAppSwitch;
975
976    /**
977     * Last time (in realtime) at which we checked for power usage.
978     */
979    long mLastPowerCheckRealtime;
980
981    /**
982     * Last time (in uptime) at which we checked for power usage.
983     */
984    long mLastPowerCheckUptime;
985
986    /**
987     * Set while we are wanting to sleep, to prevent any
988     * activities from being started/resumed.
989     */
990    private boolean mSleeping = false;
991
992    /**
993     * The process state used for processes that are running the top activities.
994     * This changes between TOP and TOP_SLEEPING to following mSleeping.
995     */
996    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
997
998    /**
999     * Set while we are running a voice interaction.  This overrides
1000     * sleeping while it is active.
1001     */
1002    private IVoiceInteractionSession mRunningVoice;
1003
1004    /**
1005     * We want to hold a wake lock while running a voice interaction session, since
1006     * this may happen with the screen off and we need to keep the CPU running to
1007     * be able to continue to interact with the user.
1008     */
1009    PowerManager.WakeLock mVoiceWakeLock;
1010
1011    /**
1012     * State of external calls telling us if the device is awake or asleep.
1013     */
1014    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1015
1016    static final int LOCK_SCREEN_HIDDEN = 0;
1017    static final int LOCK_SCREEN_LEAVING = 1;
1018    static final int LOCK_SCREEN_SHOWN = 2;
1019    /**
1020     * State of external call telling us if the lock screen is shown.
1021     */
1022    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1023
1024    /**
1025     * Set if we are shutting down the system, similar to sleeping.
1026     */
1027    boolean mShuttingDown = false;
1028
1029    /**
1030     * Current sequence id for oom_adj computation traversal.
1031     */
1032    int mAdjSeq = 0;
1033
1034    /**
1035     * Current sequence id for process LRU updating.
1036     */
1037    int mLruSeq = 0;
1038
1039    /**
1040     * Keep track of the non-cached/empty process we last found, to help
1041     * determine how to distribute cached/empty processes next time.
1042     */
1043    int mNumNonCachedProcs = 0;
1044
1045    /**
1046     * Keep track of the number of cached hidden procs, to balance oom adj
1047     * distribution between those and empty procs.
1048     */
1049    int mNumCachedHiddenProcs = 0;
1050
1051    /**
1052     * Keep track of the number of service processes we last found, to
1053     * determine on the next iteration which should be B services.
1054     */
1055    int mNumServiceProcs = 0;
1056    int mNewNumAServiceProcs = 0;
1057    int mNewNumServiceProcs = 0;
1058
1059    /**
1060     * Allow the current computed overall memory level of the system to go down?
1061     * This is set to false when we are killing processes for reasons other than
1062     * memory management, so that the now smaller process list will not be taken as
1063     * an indication that memory is tighter.
1064     */
1065    boolean mAllowLowerMemLevel = false;
1066
1067    /**
1068     * The last computed memory level, for holding when we are in a state that
1069     * processes are going away for other reasons.
1070     */
1071    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1072
1073    /**
1074     * The last total number of process we have, to determine if changes actually look
1075     * like a shrinking number of process due to lower RAM.
1076     */
1077    int mLastNumProcesses;
1078
1079    /**
1080     * The uptime of the last time we performed idle maintenance.
1081     */
1082    long mLastIdleTime = SystemClock.uptimeMillis();
1083
1084    /**
1085     * Total time spent with RAM that has been added in the past since the last idle time.
1086     */
1087    long mLowRamTimeSinceLastIdle = 0;
1088
1089    /**
1090     * If RAM is currently low, when that horrible situation started.
1091     */
1092    long mLowRamStartTime = 0;
1093
1094    /**
1095     * For reporting to battery stats the current top application.
1096     */
1097    private String mCurResumedPackage = null;
1098    private int mCurResumedUid = -1;
1099
1100    /**
1101     * For reporting to battery stats the apps currently running foreground
1102     * service.  The ProcessMap is package/uid tuples; each of these contain
1103     * an array of the currently foreground processes.
1104     */
1105    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1106            = new ProcessMap<ArrayList<ProcessRecord>>();
1107
1108    /**
1109     * This is set if we had to do a delayed dexopt of an app before launching
1110     * it, to increase the ANR timeouts in that case.
1111     */
1112    boolean mDidDexOpt;
1113
1114    /**
1115     * Set if the systemServer made a call to enterSafeMode.
1116     */
1117    boolean mSafeMode;
1118
1119    /**
1120     * If true, we are running under a test environment so will sample PSS from processes
1121     * much more rapidly to try to collect better data when the tests are rapidly
1122     * running through apps.
1123     */
1124    boolean mTestPssMode = false;
1125
1126    String mDebugApp = null;
1127    boolean mWaitForDebugger = false;
1128    boolean mDebugTransient = false;
1129    String mOrigDebugApp = null;
1130    boolean mOrigWaitForDebugger = false;
1131    boolean mAlwaysFinishActivities = false;
1132    IActivityController mController = null;
1133    String mProfileApp = null;
1134    ProcessRecord mProfileProc = null;
1135    String mProfileFile;
1136    ParcelFileDescriptor mProfileFd;
1137    int mSamplingInterval = 0;
1138    boolean mAutoStopProfiler = false;
1139    int mProfileType = 0;
1140    String mOpenGlTraceApp = null;
1141    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1142    String mMemWatchDumpProcName;
1143    String mMemWatchDumpFile;
1144    int mMemWatchDumpPid;
1145    int mMemWatchDumpUid;
1146
1147    final long[] mTmpLong = new long[1];
1148
1149    static class ProcessChangeItem {
1150        static final int CHANGE_ACTIVITIES = 1<<0;
1151        static final int CHANGE_PROCESS_STATE = 1<<1;
1152        int changes;
1153        int uid;
1154        int pid;
1155        int processState;
1156        boolean foregroundActivities;
1157    }
1158
1159    final RemoteCallbackList<IProcessObserver> mProcessObservers
1160            = new RemoteCallbackList<IProcessObserver>();
1161    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1162
1163    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1164            = new ArrayList<ProcessChangeItem>();
1165    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1166            = new ArrayList<ProcessChangeItem>();
1167
1168    /**
1169     * Runtime CPU use collection thread.  This object's lock is used to
1170     * perform synchronization with the thread (notifying it to run).
1171     */
1172    final Thread mProcessCpuThread;
1173
1174    /**
1175     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1176     * Must acquire this object's lock when accessing it.
1177     * NOTE: this lock will be held while doing long operations (trawling
1178     * through all processes in /proc), so it should never be acquired by
1179     * any critical paths such as when holding the main activity manager lock.
1180     */
1181    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1182            MONITOR_THREAD_CPU_USAGE);
1183    final AtomicLong mLastCpuTime = new AtomicLong(0);
1184    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1185
1186    long mLastWriteTime = 0;
1187
1188    /**
1189     * Used to retain an update lock when the foreground activity is in
1190     * immersive mode.
1191     */
1192    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1193
1194    /**
1195     * Set to true after the system has finished booting.
1196     */
1197    boolean mBooted = false;
1198
1199    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1200    int mProcessLimitOverride = -1;
1201
1202    WindowManagerService mWindowManager;
1203
1204    final ActivityThread mSystemThread;
1205
1206    // Holds the current foreground user's id
1207    int mCurrentUserId = 0;
1208    // Holds the target user's id during a user switch
1209    int mTargetUserId = UserHandle.USER_NULL;
1210    // If there are multiple profiles for the current user, their ids are here
1211    // Currently only the primary user can have managed profiles
1212    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1213
1214    /**
1215     * Mapping from each known user ID to the profile group ID it is associated with.
1216     */
1217    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1218
1219    private UserManagerService mUserManager;
1220
1221    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1222        final ProcessRecord mApp;
1223        final int mPid;
1224        final IApplicationThread mAppThread;
1225
1226        AppDeathRecipient(ProcessRecord app, int pid,
1227                IApplicationThread thread) {
1228            if (DEBUG_ALL) Slog.v(
1229                TAG, "New death recipient " + this
1230                + " for thread " + thread.asBinder());
1231            mApp = app;
1232            mPid = pid;
1233            mAppThread = thread;
1234        }
1235
1236        @Override
1237        public void binderDied() {
1238            if (DEBUG_ALL) Slog.v(
1239                TAG, "Death received in " + this
1240                + " for thread " + mAppThread.asBinder());
1241            synchronized(ActivityManagerService.this) {
1242                appDiedLocked(mApp, mPid, mAppThread, true);
1243            }
1244        }
1245    }
1246
1247    static final int SHOW_ERROR_MSG = 1;
1248    static final int SHOW_NOT_RESPONDING_MSG = 2;
1249    static final int SHOW_FACTORY_ERROR_MSG = 3;
1250    static final int UPDATE_CONFIGURATION_MSG = 4;
1251    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1252    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1253    static final int SERVICE_TIMEOUT_MSG = 12;
1254    static final int UPDATE_TIME_ZONE = 13;
1255    static final int SHOW_UID_ERROR_MSG = 14;
1256    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1257    static final int PROC_START_TIMEOUT_MSG = 20;
1258    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1259    static final int KILL_APPLICATION_MSG = 22;
1260    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1261    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1262    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1263    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1264    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1265    static final int CLEAR_DNS_CACHE_MSG = 28;
1266    static final int UPDATE_HTTP_PROXY_MSG = 29;
1267    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1268    static final int DISPATCH_PROCESSES_CHANGED = 31;
1269    static final int DISPATCH_PROCESS_DIED = 32;
1270    static final int REPORT_MEM_USAGE_MSG = 33;
1271    static final int REPORT_USER_SWITCH_MSG = 34;
1272    static final int CONTINUE_USER_SWITCH_MSG = 35;
1273    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1274    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1275    static final int PERSIST_URI_GRANTS_MSG = 38;
1276    static final int REQUEST_ALL_PSS_MSG = 39;
1277    static final int START_PROFILES_MSG = 40;
1278    static final int UPDATE_TIME = 41;
1279    static final int SYSTEM_USER_START_MSG = 42;
1280    static final int SYSTEM_USER_CURRENT_MSG = 43;
1281    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1282    static final int FINISH_BOOTING_MSG = 45;
1283    static final int START_USER_SWITCH_MSG = 46;
1284    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1285    static final int DISMISS_DIALOG_MSG = 48;
1286    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1287    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1288    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1289    static final int DELETE_DUMPHEAP_MSG = 52;
1290    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1291
1292    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1293    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1294    static final int FIRST_COMPAT_MODE_MSG = 300;
1295    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1296
1297    CompatModeDialog mCompatModeDialog;
1298    long mLastMemUsageReportTime = 0;
1299
1300    /**
1301     * Flag whether the current user is a "monkey", i.e. whether
1302     * the UI is driven by a UI automation tool.
1303     */
1304    private boolean mUserIsMonkey;
1305
1306    /** Flag whether the device has a Recents UI */
1307    boolean mHasRecents;
1308
1309    /** The dimensions of the thumbnails in the Recents UI. */
1310    int mThumbnailWidth;
1311    int mThumbnailHeight;
1312
1313    final ServiceThread mHandlerThread;
1314    final MainHandler mHandler;
1315
1316    final class MainHandler extends Handler {
1317        public MainHandler(Looper looper) {
1318            super(looper, null, true);
1319        }
1320
1321        @Override
1322        public void handleMessage(Message msg) {
1323            switch (msg.what) {
1324            case SHOW_ERROR_MSG: {
1325                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1326                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1327                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1328                synchronized (ActivityManagerService.this) {
1329                    ProcessRecord proc = (ProcessRecord)data.get("app");
1330                    AppErrorResult res = (AppErrorResult) data.get("result");
1331                    if (proc != null && proc.crashDialog != null) {
1332                        Slog.e(TAG, "App already has crash dialog: " + proc);
1333                        if (res != null) {
1334                            res.set(0);
1335                        }
1336                        return;
1337                    }
1338                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1339                            >= Process.FIRST_APPLICATION_UID
1340                            && proc.pid != MY_PID);
1341                    for (int userId : mCurrentProfileIds) {
1342                        isBackground &= (proc.userId != userId);
1343                    }
1344                    if (isBackground && !showBackground) {
1345                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1346                        if (res != null) {
1347                            res.set(0);
1348                        }
1349                        return;
1350                    }
1351                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1352                        Dialog d = new AppErrorDialog(mContext,
1353                                ActivityManagerService.this, res, proc);
1354                        d.show();
1355                        proc.crashDialog = d;
1356                    } else {
1357                        // The device is asleep, so just pretend that the user
1358                        // saw a crash dialog and hit "force quit".
1359                        if (res != null) {
1360                            res.set(0);
1361                        }
1362                    }
1363                }
1364
1365                ensureBootCompleted();
1366            } break;
1367            case SHOW_NOT_RESPONDING_MSG: {
1368                synchronized (ActivityManagerService.this) {
1369                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1370                    ProcessRecord proc = (ProcessRecord)data.get("app");
1371                    if (proc != null && proc.anrDialog != null) {
1372                        Slog.e(TAG, "App already has anr dialog: " + proc);
1373                        return;
1374                    }
1375
1376                    Intent intent = new Intent("android.intent.action.ANR");
1377                    if (!mProcessesReady) {
1378                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1379                                | Intent.FLAG_RECEIVER_FOREGROUND);
1380                    }
1381                    broadcastIntentLocked(null, null, intent,
1382                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1383                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1384
1385                    if (mShowDialogs) {
1386                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1387                                mContext, proc, (ActivityRecord)data.get("activity"),
1388                                msg.arg1 != 0);
1389                        d.show();
1390                        proc.anrDialog = d;
1391                    } else {
1392                        // Just kill the app if there is no dialog to be shown.
1393                        killAppAtUsersRequest(proc, null);
1394                    }
1395                }
1396
1397                ensureBootCompleted();
1398            } break;
1399            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1400                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1401                synchronized (ActivityManagerService.this) {
1402                    ProcessRecord proc = (ProcessRecord) data.get("app");
1403                    if (proc == null) {
1404                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1405                        break;
1406                    }
1407                    if (proc.crashDialog != null) {
1408                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1409                        return;
1410                    }
1411                    AppErrorResult res = (AppErrorResult) data.get("result");
1412                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1413                        Dialog d = new StrictModeViolationDialog(mContext,
1414                                ActivityManagerService.this, res, proc);
1415                        d.show();
1416                        proc.crashDialog = d;
1417                    } else {
1418                        // The device is asleep, so just pretend that the user
1419                        // saw a crash dialog and hit "force quit".
1420                        res.set(0);
1421                    }
1422                }
1423                ensureBootCompleted();
1424            } break;
1425            case SHOW_FACTORY_ERROR_MSG: {
1426                Dialog d = new FactoryErrorDialog(
1427                    mContext, msg.getData().getCharSequence("msg"));
1428                d.show();
1429                ensureBootCompleted();
1430            } break;
1431            case UPDATE_CONFIGURATION_MSG: {
1432                final ContentResolver resolver = mContext.getContentResolver();
1433                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1434            } break;
1435            case GC_BACKGROUND_PROCESSES_MSG: {
1436                synchronized (ActivityManagerService.this) {
1437                    performAppGcsIfAppropriateLocked();
1438                }
1439            } break;
1440            case WAIT_FOR_DEBUGGER_MSG: {
1441                synchronized (ActivityManagerService.this) {
1442                    ProcessRecord app = (ProcessRecord)msg.obj;
1443                    if (msg.arg1 != 0) {
1444                        if (!app.waitedForDebugger) {
1445                            Dialog d = new AppWaitingForDebuggerDialog(
1446                                    ActivityManagerService.this,
1447                                    mContext, app);
1448                            app.waitDialog = d;
1449                            app.waitedForDebugger = true;
1450                            d.show();
1451                        }
1452                    } else {
1453                        if (app.waitDialog != null) {
1454                            app.waitDialog.dismiss();
1455                            app.waitDialog = null;
1456                        }
1457                    }
1458                }
1459            } break;
1460            case SERVICE_TIMEOUT_MSG: {
1461                if (mDidDexOpt) {
1462                    mDidDexOpt = false;
1463                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1464                    nmsg.obj = msg.obj;
1465                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1466                    return;
1467                }
1468                mServices.serviceTimeout((ProcessRecord)msg.obj);
1469            } break;
1470            case UPDATE_TIME_ZONE: {
1471                synchronized (ActivityManagerService.this) {
1472                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1473                        ProcessRecord r = mLruProcesses.get(i);
1474                        if (r.thread != null) {
1475                            try {
1476                                r.thread.updateTimeZone();
1477                            } catch (RemoteException ex) {
1478                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1479                            }
1480                        }
1481                    }
1482                }
1483            } break;
1484            case CLEAR_DNS_CACHE_MSG: {
1485                synchronized (ActivityManagerService.this) {
1486                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1487                        ProcessRecord r = mLruProcesses.get(i);
1488                        if (r.thread != null) {
1489                            try {
1490                                r.thread.clearDnsCache();
1491                            } catch (RemoteException ex) {
1492                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1493                            }
1494                        }
1495                    }
1496                }
1497            } break;
1498            case UPDATE_HTTP_PROXY_MSG: {
1499                ProxyInfo proxy = (ProxyInfo)msg.obj;
1500                String host = "";
1501                String port = "";
1502                String exclList = "";
1503                Uri pacFileUrl = Uri.EMPTY;
1504                if (proxy != null) {
1505                    host = proxy.getHost();
1506                    port = Integer.toString(proxy.getPort());
1507                    exclList = proxy.getExclusionListAsString();
1508                    pacFileUrl = proxy.getPacFileUrl();
1509                }
1510                synchronized (ActivityManagerService.this) {
1511                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1512                        ProcessRecord r = mLruProcesses.get(i);
1513                        if (r.thread != null) {
1514                            try {
1515                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1516                            } catch (RemoteException ex) {
1517                                Slog.w(TAG, "Failed to update http proxy for: " +
1518                                        r.info.processName);
1519                            }
1520                        }
1521                    }
1522                }
1523            } break;
1524            case SHOW_UID_ERROR_MSG: {
1525                if (mShowDialogs) {
1526                    AlertDialog d = new BaseErrorDialog(mContext);
1527                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1528                    d.setCancelable(false);
1529                    d.setTitle(mContext.getText(R.string.android_system_label));
1530                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1531                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1532                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1533                    d.show();
1534                }
1535            } break;
1536            case SHOW_FINGERPRINT_ERROR_MSG: {
1537                if (mShowDialogs) {
1538                    AlertDialog d = new BaseErrorDialog(mContext);
1539                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1540                    d.setCancelable(false);
1541                    d.setTitle(mContext.getText(R.string.android_system_label));
1542                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1543                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1544                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1545                    d.show();
1546                }
1547            } break;
1548            case PROC_START_TIMEOUT_MSG: {
1549                if (mDidDexOpt) {
1550                    mDidDexOpt = false;
1551                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1552                    nmsg.obj = msg.obj;
1553                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1554                    return;
1555                }
1556                ProcessRecord app = (ProcessRecord)msg.obj;
1557                synchronized (ActivityManagerService.this) {
1558                    processStartTimedOutLocked(app);
1559                }
1560            } break;
1561            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1562                synchronized (ActivityManagerService.this) {
1563                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1564                }
1565            } break;
1566            case KILL_APPLICATION_MSG: {
1567                synchronized (ActivityManagerService.this) {
1568                    int appid = msg.arg1;
1569                    boolean restart = (msg.arg2 == 1);
1570                    Bundle bundle = (Bundle)msg.obj;
1571                    String pkg = bundle.getString("pkg");
1572                    String reason = bundle.getString("reason");
1573                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1574                            false, UserHandle.USER_ALL, reason);
1575                }
1576            } break;
1577            case FINALIZE_PENDING_INTENT_MSG: {
1578                ((PendingIntentRecord)msg.obj).completeFinalize();
1579            } break;
1580            case POST_HEAVY_NOTIFICATION_MSG: {
1581                INotificationManager inm = NotificationManager.getService();
1582                if (inm == null) {
1583                    return;
1584                }
1585
1586                ActivityRecord root = (ActivityRecord)msg.obj;
1587                ProcessRecord process = root.app;
1588                if (process == null) {
1589                    return;
1590                }
1591
1592                try {
1593                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1594                    String text = mContext.getString(R.string.heavy_weight_notification,
1595                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1596                    Notification notification = new Notification();
1597                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1598                    notification.when = 0;
1599                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1600                    notification.tickerText = text;
1601                    notification.defaults = 0; // please be quiet
1602                    notification.sound = null;
1603                    notification.vibrate = null;
1604                    notification.color = mContext.getColor(
1605                            com.android.internal.R.color.system_notification_accent_color);
1606                    notification.setLatestEventInfo(context, text,
1607                            mContext.getText(R.string.heavy_weight_notification_detail),
1608                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1609                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1610                                    new UserHandle(root.userId)));
1611
1612                    try {
1613                        int[] outId = new int[1];
1614                        inm.enqueueNotificationWithTag("android", "android", null,
1615                                R.string.heavy_weight_notification,
1616                                notification, outId, root.userId);
1617                    } catch (RuntimeException e) {
1618                        Slog.w(ActivityManagerService.TAG,
1619                                "Error showing notification for heavy-weight app", e);
1620                    } catch (RemoteException e) {
1621                    }
1622                } catch (NameNotFoundException e) {
1623                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1624                }
1625            } break;
1626            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1627                INotificationManager inm = NotificationManager.getService();
1628                if (inm == null) {
1629                    return;
1630                }
1631                try {
1632                    inm.cancelNotificationWithTag("android", null,
1633                            R.string.heavy_weight_notification,  msg.arg1);
1634                } catch (RuntimeException e) {
1635                    Slog.w(ActivityManagerService.TAG,
1636                            "Error canceling notification for service", e);
1637                } catch (RemoteException e) {
1638                }
1639            } break;
1640            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1641                synchronized (ActivityManagerService.this) {
1642                    checkExcessivePowerUsageLocked(true);
1643                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1644                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1645                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1646                }
1647            } break;
1648            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1649                synchronized (ActivityManagerService.this) {
1650                    ActivityRecord ar = (ActivityRecord)msg.obj;
1651                    if (mCompatModeDialog != null) {
1652                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1653                                ar.info.applicationInfo.packageName)) {
1654                            return;
1655                        }
1656                        mCompatModeDialog.dismiss();
1657                        mCompatModeDialog = null;
1658                    }
1659                    if (ar != null && false) {
1660                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1661                                ar.packageName)) {
1662                            int mode = mCompatModePackages.computeCompatModeLocked(
1663                                    ar.info.applicationInfo);
1664                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1665                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1666                                mCompatModeDialog = new CompatModeDialog(
1667                                        ActivityManagerService.this, mContext,
1668                                        ar.info.applicationInfo);
1669                                mCompatModeDialog.show();
1670                            }
1671                        }
1672                    }
1673                }
1674                break;
1675            }
1676            case DISPATCH_PROCESSES_CHANGED: {
1677                dispatchProcessesChanged();
1678                break;
1679            }
1680            case DISPATCH_PROCESS_DIED: {
1681                final int pid = msg.arg1;
1682                final int uid = msg.arg2;
1683                dispatchProcessDied(pid, uid);
1684                break;
1685            }
1686            case REPORT_MEM_USAGE_MSG: {
1687                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1688                Thread thread = new Thread() {
1689                    @Override public void run() {
1690                        reportMemUsage(memInfos);
1691                    }
1692                };
1693                thread.start();
1694                break;
1695            }
1696            case START_USER_SWITCH_MSG: {
1697                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1698                break;
1699            }
1700            case REPORT_USER_SWITCH_MSG: {
1701                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1702                break;
1703            }
1704            case CONTINUE_USER_SWITCH_MSG: {
1705                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1706                break;
1707            }
1708            case USER_SWITCH_TIMEOUT_MSG: {
1709                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1710                break;
1711            }
1712            case IMMERSIVE_MODE_LOCK_MSG: {
1713                final boolean nextState = (msg.arg1 != 0);
1714                if (mUpdateLock.isHeld() != nextState) {
1715                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1716                            "Applying new update lock state '" + nextState
1717                            + "' for " + (ActivityRecord)msg.obj);
1718                    if (nextState) {
1719                        mUpdateLock.acquire();
1720                    } else {
1721                        mUpdateLock.release();
1722                    }
1723                }
1724                break;
1725            }
1726            case PERSIST_URI_GRANTS_MSG: {
1727                writeGrantedUriPermissions();
1728                break;
1729            }
1730            case REQUEST_ALL_PSS_MSG: {
1731                synchronized (ActivityManagerService.this) {
1732                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1733                }
1734                break;
1735            }
1736            case START_PROFILES_MSG: {
1737                synchronized (ActivityManagerService.this) {
1738                    startProfilesLocked();
1739                }
1740                break;
1741            }
1742            case UPDATE_TIME: {
1743                synchronized (ActivityManagerService.this) {
1744                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1745                        ProcessRecord r = mLruProcesses.get(i);
1746                        if (r.thread != null) {
1747                            try {
1748                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1749                            } catch (RemoteException ex) {
1750                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1751                            }
1752                        }
1753                    }
1754                }
1755                break;
1756            }
1757            case SYSTEM_USER_START_MSG: {
1758                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1759                        Integer.toString(msg.arg1), msg.arg1);
1760                mSystemServiceManager.startUser(msg.arg1);
1761                break;
1762            }
1763            case SYSTEM_USER_CURRENT_MSG: {
1764                mBatteryStatsService.noteEvent(
1765                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1766                        Integer.toString(msg.arg2), msg.arg2);
1767                mBatteryStatsService.noteEvent(
1768                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1769                        Integer.toString(msg.arg1), msg.arg1);
1770                mSystemServiceManager.switchUser(msg.arg1);
1771                break;
1772            }
1773            case ENTER_ANIMATION_COMPLETE_MSG: {
1774                synchronized (ActivityManagerService.this) {
1775                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1776                    if (r != null && r.app != null && r.app.thread != null) {
1777                        try {
1778                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1779                        } catch (RemoteException e) {
1780                        }
1781                    }
1782                }
1783                break;
1784            }
1785            case FINISH_BOOTING_MSG: {
1786                if (msg.arg1 != 0) {
1787                    finishBooting();
1788                }
1789                if (msg.arg2 != 0) {
1790                    enableScreenAfterBoot();
1791                }
1792                break;
1793            }
1794            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1795                try {
1796                    Locale l = (Locale) msg.obj;
1797                    IBinder service = ServiceManager.getService("mount");
1798                    IMountService mountService = IMountService.Stub.asInterface(service);
1799                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1800                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1801                } catch (RemoteException e) {
1802                    Log.e(TAG, "Error storing locale for decryption UI", e);
1803                }
1804                break;
1805            }
1806            case DISMISS_DIALOG_MSG: {
1807                final Dialog d = (Dialog) msg.obj;
1808                d.dismiss();
1809                break;
1810            }
1811            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1812                synchronized (ActivityManagerService.this) {
1813                    int i = mTaskStackListeners.beginBroadcast();
1814                    while (i > 0) {
1815                        i--;
1816                        try {
1817                            // Make a one-way callback to the listener
1818                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1819                        } catch (RemoteException e){
1820                            // Handled by the RemoteCallbackList
1821                        }
1822                    }
1823                    mTaskStackListeners.finishBroadcast();
1824                }
1825                break;
1826            }
1827            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1828                final int uid = msg.arg1;
1829                final byte[] firstPacket = (byte[]) msg.obj;
1830
1831                synchronized (mPidsSelfLocked) {
1832                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
1833                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
1834                        if (p.uid == uid) {
1835                            try {
1836                                p.thread.notifyCleartextNetwork(firstPacket);
1837                            } catch (RemoteException ignored) {
1838                            }
1839                        }
1840                    }
1841                }
1842                break;
1843            }
1844            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
1845                final String procName;
1846                final int uid;
1847                final long memLimit;
1848                final String reportPackage;
1849                synchronized (ActivityManagerService.this) {
1850                    procName = mMemWatchDumpProcName;
1851                    uid = mMemWatchDumpUid;
1852                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
1853                    if (val == null) {
1854                        val = mMemWatchProcesses.get(procName, 0);
1855                    }
1856                    if (val != null) {
1857                        memLimit = val.first;
1858                        reportPackage = val.second;
1859                    } else {
1860                        memLimit = 0;
1861                        reportPackage = null;
1862                    }
1863                }
1864                if (procName == null) {
1865                    return;
1866                }
1867
1868                if (DEBUG_PSS) Slog.d(TAG_PSS,
1869                        "Showing dump heap notification from " + procName + "/" + uid);
1870
1871                INotificationManager inm = NotificationManager.getService();
1872                if (inm == null) {
1873                    return;
1874                }
1875
1876                String text = mContext.getString(R.string.dump_heap_notification, procName);
1877                Notification notification = new Notification();
1878                notification.icon = com.android.internal.R.drawable.stat_sys_adb;
1879                notification.when = 0;
1880                notification.flags = Notification.FLAG_ONGOING_EVENT|Notification.FLAG_AUTO_CANCEL;
1881                notification.tickerText = text;
1882                notification.defaults = 0; // please be quiet
1883                notification.sound = null;
1884                notification.vibrate = null;
1885                notification.color = mContext.getColor(
1886                        com.android.internal.R.color.system_notification_accent_color);
1887                Intent deleteIntent = new Intent();
1888                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
1889                notification.deleteIntent = PendingIntent.getBroadcastAsUser(mContext, 0,
1890                        deleteIntent, 0, UserHandle.OWNER);
1891                Intent intent = new Intent();
1892                intent.setClassName("android", DumpHeapActivity.class.getName());
1893                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
1894                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
1895                if (reportPackage != null) {
1896                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
1897                }
1898                int userId = UserHandle.getUserId(uid);
1899                notification.setLatestEventInfo(mContext, text,
1900                        mContext.getText(R.string.dump_heap_notification_detail),
1901                        PendingIntent.getActivityAsUser(mContext, 0, intent,
1902                                PendingIntent.FLAG_CANCEL_CURRENT, null,
1903                                new UserHandle(userId)));
1904
1905                try {
1906                    int[] outId = new int[1];
1907                    inm.enqueueNotificationWithTag("android", "android", null,
1908                            R.string.dump_heap_notification,
1909                            notification, outId, userId);
1910                } catch (RuntimeException e) {
1911                    Slog.w(ActivityManagerService.TAG,
1912                            "Error showing notification for dump heap", e);
1913                } catch (RemoteException e) {
1914                }
1915            } break;
1916            case DELETE_DUMPHEAP_MSG: {
1917                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
1918                        DumpHeapActivity.JAVA_URI,
1919                        Intent.FLAG_GRANT_READ_URI_PERMISSION
1920                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
1921                        UserHandle.myUserId());
1922                synchronized (ActivityManagerService.this) {
1923                    mMemWatchDumpFile = null;
1924                    mMemWatchDumpProcName = null;
1925                    mMemWatchDumpPid = -1;
1926                    mMemWatchDumpUid = -1;
1927                }
1928            } break;
1929            case FOREGROUND_PROFILE_CHANGED_MSG: {
1930                dispatchForegroundProfileChanged(msg.arg1);
1931            } break;
1932            }
1933        }
1934    };
1935
1936    static final int COLLECT_PSS_BG_MSG = 1;
1937
1938    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1939        @Override
1940        public void handleMessage(Message msg) {
1941            switch (msg.what) {
1942            case COLLECT_PSS_BG_MSG: {
1943                long start = SystemClock.uptimeMillis();
1944                MemInfoReader memInfo = null;
1945                synchronized (ActivityManagerService.this) {
1946                    if (mFullPssPending) {
1947                        mFullPssPending = false;
1948                        memInfo = new MemInfoReader();
1949                    }
1950                }
1951                if (memInfo != null) {
1952                    updateCpuStatsNow();
1953                    long nativeTotalPss = 0;
1954                    synchronized (mProcessCpuTracker) {
1955                        final int N = mProcessCpuTracker.countStats();
1956                        for (int j=0; j<N; j++) {
1957                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1958                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1959                                // This is definitely an application process; skip it.
1960                                continue;
1961                            }
1962                            synchronized (mPidsSelfLocked) {
1963                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1964                                    // This is one of our own processes; skip it.
1965                                    continue;
1966                                }
1967                            }
1968                            nativeTotalPss += Debug.getPss(st.pid, null, null);
1969                        }
1970                    }
1971                    memInfo.readMemInfo();
1972                    synchronized (ActivityManagerService.this) {
1973                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
1974                                + (SystemClock.uptimeMillis()-start) + "ms");
1975                        final long cachedKb = memInfo.getCachedSizeKb();
1976                        final long freeKb = memInfo.getFreeSizeKb();
1977                        final long zramKb = memInfo.getZramTotalSizeKb();
1978                        final long kernelKb = memInfo.getKernelUsedSizeKb();
1979                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
1980                                kernelKb*1024, nativeTotalPss*1024);
1981                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
1982                                nativeTotalPss);
1983                    }
1984                }
1985
1986                int num = 0;
1987                long[] tmp = new long[1];
1988                do {
1989                    ProcessRecord proc;
1990                    int procState;
1991                    int pid;
1992                    long lastPssTime;
1993                    synchronized (ActivityManagerService.this) {
1994                        if (mPendingPssProcesses.size() <= 0) {
1995                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
1996                                    "Collected PSS of " + num + " processes in "
1997                                    + (SystemClock.uptimeMillis() - start) + "ms");
1998                            mPendingPssProcesses.clear();
1999                            return;
2000                        }
2001                        proc = mPendingPssProcesses.remove(0);
2002                        procState = proc.pssProcState;
2003                        lastPssTime = proc.lastPssTime;
2004                        if (proc.thread != null && procState == proc.setProcState
2005                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2006                                        < SystemClock.uptimeMillis()) {
2007                            pid = proc.pid;
2008                        } else {
2009                            proc = null;
2010                            pid = 0;
2011                        }
2012                    }
2013                    if (proc != null) {
2014                        long pss = Debug.getPss(pid, tmp, null);
2015                        synchronized (ActivityManagerService.this) {
2016                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2017                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2018                                num++;
2019                                recordPssSampleLocked(proc, procState, pss, tmp[0],
2020                                        SystemClock.uptimeMillis());
2021                            }
2022                        }
2023                    }
2024                } while (true);
2025            }
2026            }
2027        }
2028    };
2029
2030    public void setSystemProcess() {
2031        try {
2032            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2033            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2034            ServiceManager.addService("meminfo", new MemBinder(this));
2035            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2036            ServiceManager.addService("dbinfo", new DbBinder(this));
2037            if (MONITOR_CPU_USAGE) {
2038                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2039            }
2040            ServiceManager.addService("permission", new PermissionController(this));
2041            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2042
2043            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2044                    "android", STOCK_PM_FLAGS);
2045            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2046
2047            synchronized (this) {
2048                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2049                app.persistent = true;
2050                app.pid = MY_PID;
2051                app.maxAdj = ProcessList.SYSTEM_ADJ;
2052                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2053                mProcessNames.put(app.processName, app.uid, app);
2054                synchronized (mPidsSelfLocked) {
2055                    mPidsSelfLocked.put(app.pid, app);
2056                }
2057                updateLruProcessLocked(app, false, null);
2058                updateOomAdjLocked();
2059            }
2060        } catch (PackageManager.NameNotFoundException e) {
2061            throw new RuntimeException(
2062                    "Unable to find android system package", e);
2063        }
2064    }
2065
2066    public void setWindowManager(WindowManagerService wm) {
2067        mWindowManager = wm;
2068        mStackSupervisor.setWindowManager(wm);
2069    }
2070
2071    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2072        mUsageStatsService = usageStatsManager;
2073    }
2074
2075    public void startObservingNativeCrashes() {
2076        final NativeCrashListener ncl = new NativeCrashListener(this);
2077        ncl.start();
2078    }
2079
2080    public IAppOpsService getAppOpsService() {
2081        return mAppOpsService;
2082    }
2083
2084    static class MemBinder extends Binder {
2085        ActivityManagerService mActivityManagerService;
2086        MemBinder(ActivityManagerService activityManagerService) {
2087            mActivityManagerService = activityManagerService;
2088        }
2089
2090        @Override
2091        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2092            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2093                    != PackageManager.PERMISSION_GRANTED) {
2094                pw.println("Permission Denial: can't dump meminfo from from pid="
2095                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2096                        + " without permission " + android.Manifest.permission.DUMP);
2097                return;
2098            }
2099
2100            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2101        }
2102    }
2103
2104    static class GraphicsBinder extends Binder {
2105        ActivityManagerService mActivityManagerService;
2106        GraphicsBinder(ActivityManagerService activityManagerService) {
2107            mActivityManagerService = activityManagerService;
2108        }
2109
2110        @Override
2111        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2112            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2113                    != PackageManager.PERMISSION_GRANTED) {
2114                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2115                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2116                        + " without permission " + android.Manifest.permission.DUMP);
2117                return;
2118            }
2119
2120            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2121        }
2122    }
2123
2124    static class DbBinder extends Binder {
2125        ActivityManagerService mActivityManagerService;
2126        DbBinder(ActivityManagerService activityManagerService) {
2127            mActivityManagerService = activityManagerService;
2128        }
2129
2130        @Override
2131        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2132            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2133                    != PackageManager.PERMISSION_GRANTED) {
2134                pw.println("Permission Denial: can't dump dbinfo from from pid="
2135                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2136                        + " without permission " + android.Manifest.permission.DUMP);
2137                return;
2138            }
2139
2140            mActivityManagerService.dumpDbInfo(fd, pw, args);
2141        }
2142    }
2143
2144    static class CpuBinder extends Binder {
2145        ActivityManagerService mActivityManagerService;
2146        CpuBinder(ActivityManagerService activityManagerService) {
2147            mActivityManagerService = activityManagerService;
2148        }
2149
2150        @Override
2151        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2152            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2153                    != PackageManager.PERMISSION_GRANTED) {
2154                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2155                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2156                        + " without permission " + android.Manifest.permission.DUMP);
2157                return;
2158            }
2159
2160            synchronized (mActivityManagerService.mProcessCpuTracker) {
2161                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2162                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2163                        SystemClock.uptimeMillis()));
2164            }
2165        }
2166    }
2167
2168    public static final class Lifecycle extends SystemService {
2169        private final ActivityManagerService mService;
2170
2171        public Lifecycle(Context context) {
2172            super(context);
2173            mService = new ActivityManagerService(context);
2174        }
2175
2176        @Override
2177        public void onStart() {
2178            mService.start();
2179        }
2180
2181        public ActivityManagerService getService() {
2182            return mService;
2183        }
2184    }
2185
2186    // Note: This method is invoked on the main thread but may need to attach various
2187    // handlers to other threads.  So take care to be explicit about the looper.
2188    public ActivityManagerService(Context systemContext) {
2189        mContext = systemContext;
2190        mFactoryTest = FactoryTest.getMode();
2191        mSystemThread = ActivityThread.currentActivityThread();
2192
2193        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2194
2195        mHandlerThread = new ServiceThread(TAG,
2196                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2197        mHandlerThread.start();
2198        mHandler = new MainHandler(mHandlerThread.getLooper());
2199
2200        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2201                "foreground", BROADCAST_FG_TIMEOUT, false);
2202        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2203                "background", BROADCAST_BG_TIMEOUT, true);
2204        mBroadcastQueues[0] = mFgBroadcastQueue;
2205        mBroadcastQueues[1] = mBgBroadcastQueue;
2206
2207        mServices = new ActiveServices(this);
2208        mProviderMap = new ProviderMap(this);
2209
2210        // TODO: Move creation of battery stats service outside of activity manager service.
2211        File dataDir = Environment.getDataDirectory();
2212        File systemDir = new File(dataDir, "system");
2213        systemDir.mkdirs();
2214        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2215        mBatteryStatsService.getActiveStatistics().readLocked();
2216        mBatteryStatsService.scheduleWriteToDisk();
2217        mOnBattery = DEBUG_POWER ? true
2218                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2219        mBatteryStatsService.getActiveStatistics().setCallback(this);
2220
2221        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2222
2223        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2224
2225        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2226
2227        // User 0 is the first and only user that runs at boot.
2228        mStartedUsers.put(UserHandle.USER_OWNER, new UserStartedState(UserHandle.OWNER, true));
2229        mUserLru.add(UserHandle.USER_OWNER);
2230        updateStartedUserArrayLocked();
2231
2232        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2233            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2234
2235        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2236
2237        mConfiguration.setToDefaults();
2238        mConfiguration.setLocale(Locale.getDefault());
2239
2240        mConfigurationSeq = mConfiguration.seq = 1;
2241        mProcessCpuTracker.init();
2242
2243        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2244        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2245        mRecentTasks = new RecentTasks(this);
2246        mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
2247        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
2248
2249        mProcessCpuThread = new Thread("CpuTracker") {
2250            @Override
2251            public void run() {
2252                while (true) {
2253                    try {
2254                        try {
2255                            synchronized(this) {
2256                                final long now = SystemClock.uptimeMillis();
2257                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2258                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2259                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2260                                //        + ", write delay=" + nextWriteDelay);
2261                                if (nextWriteDelay < nextCpuDelay) {
2262                                    nextCpuDelay = nextWriteDelay;
2263                                }
2264                                if (nextCpuDelay > 0) {
2265                                    mProcessCpuMutexFree.set(true);
2266                                    this.wait(nextCpuDelay);
2267                                }
2268                            }
2269                        } catch (InterruptedException e) {
2270                        }
2271                        updateCpuStatsNow();
2272                    } catch (Exception e) {
2273                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2274                    }
2275                }
2276            }
2277        };
2278
2279        Watchdog.getInstance().addMonitor(this);
2280        Watchdog.getInstance().addThread(mHandler);
2281    }
2282
2283    public void setSystemServiceManager(SystemServiceManager mgr) {
2284        mSystemServiceManager = mgr;
2285    }
2286
2287    public void setInstaller(Installer installer) {
2288        mInstaller = installer;
2289    }
2290
2291    private void start() {
2292        Process.removeAllProcessGroups();
2293        mProcessCpuThread.start();
2294
2295        mBatteryStatsService.publish(mContext);
2296        mAppOpsService.publish(mContext);
2297        Slog.d("AppOps", "AppOpsService published");
2298        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2299    }
2300
2301    public void initPowerManagement() {
2302        mStackSupervisor.initPowerManagement();
2303        mBatteryStatsService.initPowerManagement();
2304        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2305        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2306        mVoiceWakeLock.setReferenceCounted(false);
2307    }
2308
2309    @Override
2310    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2311            throws RemoteException {
2312        if (code == SYSPROPS_TRANSACTION) {
2313            // We need to tell all apps about the system property change.
2314            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2315            synchronized(this) {
2316                final int NP = mProcessNames.getMap().size();
2317                for (int ip=0; ip<NP; ip++) {
2318                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2319                    final int NA = apps.size();
2320                    for (int ia=0; ia<NA; ia++) {
2321                        ProcessRecord app = apps.valueAt(ia);
2322                        if (app.thread != null) {
2323                            procs.add(app.thread.asBinder());
2324                        }
2325                    }
2326                }
2327            }
2328
2329            int N = procs.size();
2330            for (int i=0; i<N; i++) {
2331                Parcel data2 = Parcel.obtain();
2332                try {
2333                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2334                } catch (RemoteException e) {
2335                }
2336                data2.recycle();
2337            }
2338        }
2339        try {
2340            return super.onTransact(code, data, reply, flags);
2341        } catch (RuntimeException e) {
2342            // The activity manager only throws security exceptions, so let's
2343            // log all others.
2344            if (!(e instanceof SecurityException)) {
2345                Slog.wtf(TAG, "Activity Manager Crash", e);
2346            }
2347            throw e;
2348        }
2349    }
2350
2351    void updateCpuStats() {
2352        final long now = SystemClock.uptimeMillis();
2353        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2354            return;
2355        }
2356        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2357            synchronized (mProcessCpuThread) {
2358                mProcessCpuThread.notify();
2359            }
2360        }
2361    }
2362
2363    void updateCpuStatsNow() {
2364        synchronized (mProcessCpuTracker) {
2365            mProcessCpuMutexFree.set(false);
2366            final long now = SystemClock.uptimeMillis();
2367            boolean haveNewCpuStats = false;
2368
2369            if (MONITOR_CPU_USAGE &&
2370                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2371                mLastCpuTime.set(now);
2372                mProcessCpuTracker.update();
2373                if (mProcessCpuTracker.hasGoodLastStats()) {
2374                    haveNewCpuStats = true;
2375                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2376                    //Slog.i(TAG, "Total CPU usage: "
2377                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2378
2379                    // Slog the cpu usage if the property is set.
2380                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2381                        int user = mProcessCpuTracker.getLastUserTime();
2382                        int system = mProcessCpuTracker.getLastSystemTime();
2383                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2384                        int irq = mProcessCpuTracker.getLastIrqTime();
2385                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2386                        int idle = mProcessCpuTracker.getLastIdleTime();
2387
2388                        int total = user + system + iowait + irq + softIrq + idle;
2389                        if (total == 0) total = 1;
2390
2391                        EventLog.writeEvent(EventLogTags.CPU,
2392                                ((user+system+iowait+irq+softIrq) * 100) / total,
2393                                (user * 100) / total,
2394                                (system * 100) / total,
2395                                (iowait * 100) / total,
2396                                (irq * 100) / total,
2397                                (softIrq * 100) / total);
2398                    }
2399                }
2400            }
2401
2402            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2403            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2404            synchronized(bstats) {
2405                synchronized(mPidsSelfLocked) {
2406                    if (haveNewCpuStats) {
2407                        final int perc = bstats.startAddingCpuLocked();
2408                        if (perc >= 0) {
2409                            int remainUTime = 0;
2410                            int remainSTime = 0;
2411                            int totalUTime = 0;
2412                            int totalSTime = 0;
2413                            final int N = mProcessCpuTracker.countStats();
2414                            for (int i=0; i<N; i++) {
2415                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2416                                if (!st.working) {
2417                                    continue;
2418                                }
2419                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2420                                int otherUTime = (st.rel_utime*perc)/100;
2421                                int otherSTime = (st.rel_stime*perc)/100;
2422                                remainUTime += otherUTime;
2423                                remainSTime += otherSTime;
2424                                totalUTime += st.rel_utime;
2425                                totalSTime += st.rel_stime;
2426                                if (pr != null) {
2427                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2428                                    if (ps == null || !ps.isActive()) {
2429                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2430                                                pr.info.uid, pr.processName);
2431                                    }
2432                                    ps.addCpuTimeLocked(st.rel_utime - otherUTime,
2433                                            st.rel_stime - otherSTime, cpuSpeedTimes);
2434                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2435                                } else {
2436                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2437                                    if (ps == null || !ps.isActive()) {
2438                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2439                                                bstats.mapUid(st.uid), st.name);
2440                                    }
2441                                    ps.addCpuTimeLocked(st.rel_utime - otherUTime,
2442                                            st.rel_stime - otherSTime, cpuSpeedTimes);
2443                                }
2444                            }
2445                            final int userTime = mProcessCpuTracker.getLastUserTime();
2446                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2447                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2448                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2449                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2450                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2451                            bstats.finishAddingCpuLocked(perc, remainUTime,
2452                                    remainSTime, totalUTime, totalSTime, userTime, systemTime,
2453                                    iowaitTime, irqTime, softIrqTime, idleTime, cpuSpeedTimes);
2454                        }
2455                    }
2456                }
2457
2458                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2459                    mLastWriteTime = now;
2460                    mBatteryStatsService.scheduleWriteToDisk();
2461                }
2462            }
2463        }
2464    }
2465
2466    @Override
2467    public void batteryNeedsCpuUpdate() {
2468        updateCpuStatsNow();
2469    }
2470
2471    @Override
2472    public void batteryPowerChanged(boolean onBattery) {
2473        // When plugging in, update the CPU stats first before changing
2474        // the plug state.
2475        updateCpuStatsNow();
2476        synchronized (this) {
2477            synchronized(mPidsSelfLocked) {
2478                mOnBattery = DEBUG_POWER ? true : onBattery;
2479            }
2480        }
2481    }
2482
2483    @Override
2484    public void batterySendBroadcast(Intent intent) {
2485        broadcastIntentLocked(null, null, intent, null,
2486                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
2487                Process.SYSTEM_UID, UserHandle.USER_ALL);
2488    }
2489
2490    /**
2491     * Initialize the application bind args. These are passed to each
2492     * process when the bindApplication() IPC is sent to the process. They're
2493     * lazily setup to make sure the services are running when they're asked for.
2494     */
2495    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2496        if (mAppBindArgs == null) {
2497            mAppBindArgs = new HashMap<>();
2498
2499            // Isolated processes won't get this optimization, so that we don't
2500            // violate the rules about which services they have access to.
2501            if (!isolated) {
2502                // Setup the application init args
2503                mAppBindArgs.put("package", ServiceManager.getService("package"));
2504                mAppBindArgs.put("window", ServiceManager.getService("window"));
2505                mAppBindArgs.put(Context.ALARM_SERVICE,
2506                        ServiceManager.getService(Context.ALARM_SERVICE));
2507            }
2508        }
2509        return mAppBindArgs;
2510    }
2511
2512    final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2513        if (r != null && mFocusedActivity != r) {
2514            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2515            ActivityRecord last = mFocusedActivity;
2516            mFocusedActivity = r;
2517            if (r.task != null && r.task.voiceInteractor != null) {
2518                startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2519            } else {
2520                finishRunningVoiceLocked();
2521                if (last != null && last.task.voiceSession != null) {
2522                    // We had been in a voice interaction session, but now focused has
2523                    // move to something different.  Just finish the session, we can't
2524                    // return to it and retain the proper state and synchronization with
2525                    // the voice interaction service.
2526                    finishVoiceTask(last.task.voiceSession);
2527                }
2528            }
2529            if (mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
2530                mWindowManager.setFocusedApp(r.appToken, true);
2531            }
2532            applyUpdateLockStateLocked(r);
2533            if (last != null && last.userId != mFocusedActivity.userId) {
2534                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2535                mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2536                                mFocusedActivity.userId, 0));
2537            }
2538        }
2539        EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, mCurrentUserId,
2540                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2541    }
2542
2543    final void clearFocusedActivity(ActivityRecord r) {
2544        if (mFocusedActivity == r) {
2545            mFocusedActivity = null;
2546        }
2547    }
2548
2549    @Override
2550    public void setFocusedStack(int stackId) {
2551        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2552        synchronized (ActivityManagerService.this) {
2553            ActivityStack stack = mStackSupervisor.getStack(stackId);
2554            if (stack != null) {
2555                ActivityRecord r = stack.topRunningActivityLocked(null);
2556                if (r != null) {
2557                    setFocusedActivityLocked(r, "setFocusedStack");
2558                    mStackSupervisor.resumeTopActivitiesLocked(stack, null, null);
2559                }
2560            }
2561        }
2562    }
2563
2564    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2565    @Override
2566    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2567        synchronized (ActivityManagerService.this) {
2568            if (listener != null) {
2569                mTaskStackListeners.register(listener);
2570            }
2571        }
2572    }
2573
2574    @Override
2575    public void notifyActivityDrawn(IBinder token) {
2576        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2577        synchronized (this) {
2578            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2579            if (r != null) {
2580                r.task.stack.notifyActivityDrawnLocked(r);
2581            }
2582        }
2583    }
2584
2585    final void applyUpdateLockStateLocked(ActivityRecord r) {
2586        // Modifications to the UpdateLock state are done on our handler, outside
2587        // the activity manager's locks.  The new state is determined based on the
2588        // state *now* of the relevant activity record.  The object is passed to
2589        // the handler solely for logging detail, not to be consulted/modified.
2590        final boolean nextState = r != null && r.immersive;
2591        mHandler.sendMessage(
2592                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2593    }
2594
2595    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2596        Message msg = Message.obtain();
2597        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2598        msg.obj = r.task.askedCompatMode ? null : r;
2599        mHandler.sendMessage(msg);
2600    }
2601
2602    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2603            String what, Object obj, ProcessRecord srcApp) {
2604        app.lastActivityTime = now;
2605
2606        if (app.activities.size() > 0) {
2607            // Don't want to touch dependent processes that are hosting activities.
2608            return index;
2609        }
2610
2611        int lrui = mLruProcesses.lastIndexOf(app);
2612        if (lrui < 0) {
2613            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2614                    + what + " " + obj + " from " + srcApp);
2615            return index;
2616        }
2617
2618        if (lrui >= index) {
2619            // Don't want to cause this to move dependent processes *back* in the
2620            // list as if they were less frequently used.
2621            return index;
2622        }
2623
2624        if (lrui >= mLruProcessActivityStart) {
2625            // Don't want to touch dependent processes that are hosting activities.
2626            return index;
2627        }
2628
2629        mLruProcesses.remove(lrui);
2630        if (index > 0) {
2631            index--;
2632        }
2633        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2634                + " in LRU list: " + app);
2635        mLruProcesses.add(index, app);
2636        return index;
2637    }
2638
2639    final void removeLruProcessLocked(ProcessRecord app) {
2640        int lrui = mLruProcesses.lastIndexOf(app);
2641        if (lrui >= 0) {
2642            if (!app.killed) {
2643                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2644                Process.killProcessQuiet(app.pid);
2645                Process.killProcessGroup(app.info.uid, app.pid);
2646            }
2647            if (lrui <= mLruProcessActivityStart) {
2648                mLruProcessActivityStart--;
2649            }
2650            if (lrui <= mLruProcessServiceStart) {
2651                mLruProcessServiceStart--;
2652            }
2653            mLruProcesses.remove(lrui);
2654        }
2655    }
2656
2657    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2658            ProcessRecord client) {
2659        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2660                || app.treatLikeActivity;
2661        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2662        if (!activityChange && hasActivity) {
2663            // The process has activities, so we are only allowing activity-based adjustments
2664            // to move it.  It should be kept in the front of the list with other
2665            // processes that have activities, and we don't want those to change their
2666            // order except due to activity operations.
2667            return;
2668        }
2669
2670        mLruSeq++;
2671        final long now = SystemClock.uptimeMillis();
2672        app.lastActivityTime = now;
2673
2674        // First a quick reject: if the app is already at the position we will
2675        // put it, then there is nothing to do.
2676        if (hasActivity) {
2677            final int N = mLruProcesses.size();
2678            if (N > 0 && mLruProcesses.get(N-1) == app) {
2679                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
2680                return;
2681            }
2682        } else {
2683            if (mLruProcessServiceStart > 0
2684                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2685                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
2686                return;
2687            }
2688        }
2689
2690        int lrui = mLruProcesses.lastIndexOf(app);
2691
2692        if (app.persistent && lrui >= 0) {
2693            // We don't care about the position of persistent processes, as long as
2694            // they are in the list.
2695            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
2696            return;
2697        }
2698
2699        /* In progress: compute new position first, so we can avoid doing work
2700           if the process is not actually going to move.  Not yet working.
2701        int addIndex;
2702        int nextIndex;
2703        boolean inActivity = false, inService = false;
2704        if (hasActivity) {
2705            // Process has activities, put it at the very tipsy-top.
2706            addIndex = mLruProcesses.size();
2707            nextIndex = mLruProcessServiceStart;
2708            inActivity = true;
2709        } else if (hasService) {
2710            // Process has services, put it at the top of the service list.
2711            addIndex = mLruProcessActivityStart;
2712            nextIndex = mLruProcessServiceStart;
2713            inActivity = true;
2714            inService = true;
2715        } else  {
2716            // Process not otherwise of interest, it goes to the top of the non-service area.
2717            addIndex = mLruProcessServiceStart;
2718            if (client != null) {
2719                int clientIndex = mLruProcesses.lastIndexOf(client);
2720                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2721                        + app);
2722                if (clientIndex >= 0 && addIndex > clientIndex) {
2723                    addIndex = clientIndex;
2724                }
2725            }
2726            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2727        }
2728
2729        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2730                + mLruProcessActivityStart + "): " + app);
2731        */
2732
2733        if (lrui >= 0) {
2734            if (lrui < mLruProcessActivityStart) {
2735                mLruProcessActivityStart--;
2736            }
2737            if (lrui < mLruProcessServiceStart) {
2738                mLruProcessServiceStart--;
2739            }
2740            /*
2741            if (addIndex > lrui) {
2742                addIndex--;
2743            }
2744            if (nextIndex > lrui) {
2745                nextIndex--;
2746            }
2747            */
2748            mLruProcesses.remove(lrui);
2749        }
2750
2751        /*
2752        mLruProcesses.add(addIndex, app);
2753        if (inActivity) {
2754            mLruProcessActivityStart++;
2755        }
2756        if (inService) {
2757            mLruProcessActivityStart++;
2758        }
2759        */
2760
2761        int nextIndex;
2762        if (hasActivity) {
2763            final int N = mLruProcesses.size();
2764            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
2765                // Process doesn't have activities, but has clients with
2766                // activities...  move it up, but one below the top (the top
2767                // should always have a real activity).
2768                if (DEBUG_LRU) Slog.d(TAG_LRU,
2769                        "Adding to second-top of LRU activity list: " + app);
2770                mLruProcesses.add(N - 1, app);
2771                // To keep it from spamming the LRU list (by making a bunch of clients),
2772                // we will push down any other entries owned by the app.
2773                final int uid = app.info.uid;
2774                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
2775                    ProcessRecord subProc = mLruProcesses.get(i);
2776                    if (subProc.info.uid == uid) {
2777                        // We want to push this one down the list.  If the process after
2778                        // it is for the same uid, however, don't do so, because we don't
2779                        // want them internally to be re-ordered.
2780                        if (mLruProcesses.get(i - 1).info.uid != uid) {
2781                            if (DEBUG_LRU) Slog.d(TAG_LRU,
2782                                    "Pushing uid " + uid + " swapping at " + i + ": "
2783                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
2784                            ProcessRecord tmp = mLruProcesses.get(i);
2785                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
2786                            mLruProcesses.set(i - 1, tmp);
2787                            i--;
2788                        }
2789                    } else {
2790                        // A gap, we can stop here.
2791                        break;
2792                    }
2793                }
2794            } else {
2795                // Process has activities, put it at the very tipsy-top.
2796                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
2797                mLruProcesses.add(app);
2798            }
2799            nextIndex = mLruProcessServiceStart;
2800        } else if (hasService) {
2801            // Process has services, put it at the top of the service list.
2802            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
2803            mLruProcesses.add(mLruProcessActivityStart, app);
2804            nextIndex = mLruProcessServiceStart;
2805            mLruProcessActivityStart++;
2806        } else  {
2807            // Process not otherwise of interest, it goes to the top of the non-service area.
2808            int index = mLruProcessServiceStart;
2809            if (client != null) {
2810                // If there is a client, don't allow the process to be moved up higher
2811                // in the list than that client.
2812                int clientIndex = mLruProcesses.lastIndexOf(client);
2813                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
2814                        + " when updating " + app);
2815                if (clientIndex <= lrui) {
2816                    // Don't allow the client index restriction to push it down farther in the
2817                    // list than it already is.
2818                    clientIndex = lrui;
2819                }
2820                if (clientIndex >= 0 && index > clientIndex) {
2821                    index = clientIndex;
2822                }
2823            }
2824            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
2825            mLruProcesses.add(index, app);
2826            nextIndex = index-1;
2827            mLruProcessActivityStart++;
2828            mLruProcessServiceStart++;
2829        }
2830
2831        // If the app is currently using a content provider or service,
2832        // bump those processes as well.
2833        for (int j=app.connections.size()-1; j>=0; j--) {
2834            ConnectionRecord cr = app.connections.valueAt(j);
2835            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2836                    && cr.binding.service.app != null
2837                    && cr.binding.service.app.lruSeq != mLruSeq
2838                    && !cr.binding.service.app.persistent) {
2839                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2840                        "service connection", cr, app);
2841            }
2842        }
2843        for (int j=app.conProviders.size()-1; j>=0; j--) {
2844            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2845            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2846                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2847                        "provider reference", cpr, app);
2848            }
2849        }
2850    }
2851
2852    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2853        if (uid == Process.SYSTEM_UID) {
2854            // The system gets to run in any process.  If there are multiple
2855            // processes with the same uid, just pick the first (this
2856            // should never happen).
2857            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2858            if (procs == null) return null;
2859            final int N = procs.size();
2860            for (int i = 0; i < N; i++) {
2861                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2862            }
2863        }
2864        ProcessRecord proc = mProcessNames.get(processName, uid);
2865        if (false && proc != null && !keepIfLarge
2866                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2867                && proc.lastCachedPss >= 4000) {
2868            // Turn this condition on to cause killing to happen regularly, for testing.
2869            if (proc.baseProcessTracker != null) {
2870                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2871            }
2872            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2873        } else if (proc != null && !keepIfLarge
2874                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2875                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2876            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2877            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2878                if (proc.baseProcessTracker != null) {
2879                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2880                }
2881                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2882            }
2883        }
2884        return proc;
2885    }
2886
2887    void ensurePackageDexOpt(String packageName) {
2888        IPackageManager pm = AppGlobals.getPackageManager();
2889        try {
2890            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2891                mDidDexOpt = true;
2892            }
2893        } catch (RemoteException e) {
2894        }
2895    }
2896
2897    boolean isNextTransitionForward() {
2898        int transit = mWindowManager.getPendingAppTransition();
2899        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2900                || transit == AppTransition.TRANSIT_TASK_OPEN
2901                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2902    }
2903
2904    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2905            String processName, String abiOverride, int uid, Runnable crashHandler) {
2906        synchronized(this) {
2907            ApplicationInfo info = new ApplicationInfo();
2908            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2909            // For isolated processes, the former contains the parent's uid and the latter the
2910            // actual uid of the isolated process.
2911            // In the special case introduced by this method (which is, starting an isolated
2912            // process directly from the SystemServer without an actual parent app process) the
2913            // closest thing to a parent's uid is SYSTEM_UID.
2914            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2915            // the |isolated| logic in the ProcessRecord constructor.
2916            info.uid = Process.SYSTEM_UID;
2917            info.processName = processName;
2918            info.className = entryPoint;
2919            info.packageName = "android";
2920            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2921                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2922                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2923                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2924                    crashHandler);
2925            return proc != null ? proc.pid : 0;
2926        }
2927    }
2928
2929    final ProcessRecord startProcessLocked(String processName,
2930            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2931            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2932            boolean isolated, boolean keepIfLarge) {
2933        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2934                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2935                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2936                null /* crashHandler */);
2937    }
2938
2939    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2940            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2941            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2942            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2943        long startTime = SystemClock.elapsedRealtime();
2944        ProcessRecord app;
2945        if (!isolated) {
2946            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2947            checkTime(startTime, "startProcess: after getProcessRecord");
2948
2949            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
2950                // If we are in the background, then check to see if this process
2951                // is bad.  If so, we will just silently fail.
2952                if (mBadProcesses.get(info.processName, info.uid) != null) {
2953                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2954                            + "/" + info.processName);
2955                    return null;
2956                }
2957            } else {
2958                // When the user is explicitly starting a process, then clear its
2959                // crash count so that we won't make it bad until they see at
2960                // least one crash dialog again, and make the process good again
2961                // if it had been bad.
2962                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2963                        + "/" + info.processName);
2964                mProcessCrashTimes.remove(info.processName, info.uid);
2965                if (mBadProcesses.get(info.processName, info.uid) != null) {
2966                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2967                            UserHandle.getUserId(info.uid), info.uid,
2968                            info.processName);
2969                    mBadProcesses.remove(info.processName, info.uid);
2970                    if (app != null) {
2971                        app.bad = false;
2972                    }
2973                }
2974            }
2975        } else {
2976            // If this is an isolated process, it can't re-use an existing process.
2977            app = null;
2978        }
2979
2980        // We don't have to do anything more if:
2981        // (1) There is an existing application record; and
2982        // (2) The caller doesn't think it is dead, OR there is no thread
2983        //     object attached to it so we know it couldn't have crashed; and
2984        // (3) There is a pid assigned to it, so it is either starting or
2985        //     already running.
2986        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
2987                + " app=" + app + " knownToBeDead=" + knownToBeDead
2988                + " thread=" + (app != null ? app.thread : null)
2989                + " pid=" + (app != null ? app.pid : -1));
2990        if (app != null && app.pid > 0) {
2991            if (!knownToBeDead || app.thread == null) {
2992                // We already have the app running, or are waiting for it to
2993                // come up (we have a pid but not yet its thread), so keep it.
2994                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
2995                // If this is a new package in the process, add the package to the list
2996                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2997                checkTime(startTime, "startProcess: done, added package to proc");
2998                return app;
2999            }
3000
3001            // An application record is attached to a previous process,
3002            // clean it up now.
3003            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3004            checkTime(startTime, "startProcess: bad proc running, killing");
3005            Process.killProcessGroup(app.info.uid, app.pid);
3006            handleAppDiedLocked(app, true, true);
3007            checkTime(startTime, "startProcess: done killing old proc");
3008        }
3009
3010        String hostingNameStr = hostingName != null
3011                ? hostingName.flattenToShortString() : null;
3012
3013        if (app == null) {
3014            checkTime(startTime, "startProcess: creating new process record");
3015            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3016            if (app == null) {
3017                Slog.w(TAG, "Failed making new process record for "
3018                        + processName + "/" + info.uid + " isolated=" + isolated);
3019                return null;
3020            }
3021            app.crashHandler = crashHandler;
3022            mProcessNames.put(processName, app.uid, app);
3023            if (isolated) {
3024                mIsolatedProcesses.put(app.uid, app);
3025            }
3026            checkTime(startTime, "startProcess: done creating new process record");
3027        } else {
3028            // If this is a new package in the process, add the package to the list
3029            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3030            checkTime(startTime, "startProcess: added package to existing proc");
3031        }
3032
3033        // If the system is not ready yet, then hold off on starting this
3034        // process until it is.
3035        if (!mProcessesReady
3036                && !isAllowedWhileBooting(info)
3037                && !allowWhileBooting) {
3038            if (!mProcessesOnHold.contains(app)) {
3039                mProcessesOnHold.add(app);
3040            }
3041            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3042                    "System not ready, putting on hold: " + app);
3043            checkTime(startTime, "startProcess: returning with proc on hold");
3044            return app;
3045        }
3046
3047        checkTime(startTime, "startProcess: stepping in to startProcess");
3048        startProcessLocked(
3049                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3050        checkTime(startTime, "startProcess: done starting proc!");
3051        return (app.pid != 0) ? app : null;
3052    }
3053
3054    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3055        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3056    }
3057
3058    private final void startProcessLocked(ProcessRecord app,
3059            String hostingType, String hostingNameStr) {
3060        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3061                null /* entryPoint */, null /* entryPointArgs */);
3062    }
3063
3064    private final void startProcessLocked(ProcessRecord app, String hostingType,
3065            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3066        long startTime = SystemClock.elapsedRealtime();
3067        if (app.pid > 0 && app.pid != MY_PID) {
3068            checkTime(startTime, "startProcess: removing from pids map");
3069            synchronized (mPidsSelfLocked) {
3070                mPidsSelfLocked.remove(app.pid);
3071                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3072            }
3073            checkTime(startTime, "startProcess: done removing from pids map");
3074            app.setPid(0);
3075        }
3076
3077        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3078                "startProcessLocked removing on hold: " + app);
3079        mProcessesOnHold.remove(app);
3080
3081        checkTime(startTime, "startProcess: starting to update cpu stats");
3082        updateCpuStats();
3083        checkTime(startTime, "startProcess: done updating cpu stats");
3084
3085        try {
3086            int uid = app.uid;
3087
3088            int[] gids = null;
3089            int mountExternal = Zygote.MOUNT_EXTERNAL_DEFAULT;
3090            if (!app.isolated) {
3091                int[] permGids = null;
3092                try {
3093                    checkTime(startTime, "startProcess: getting gids from package manager");
3094                    permGids = AppGlobals.getPackageManager().getPackageGids(app.info.packageName,
3095                            app.userId);
3096                } catch (RemoteException e) {
3097                    Slog.w(TAG, "Unable to retrieve gids", e);
3098                }
3099
3100                /*
3101                 * Add shared application and profile GIDs so applications can share some
3102                 * resources like shared libraries and access user-wide resources
3103                 */
3104                if (ArrayUtils.isEmpty(permGids)) {
3105                    gids = new int[2];
3106                } else {
3107                    gids = new int[permGids.length + 2];
3108                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3109                }
3110                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3111                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3112            }
3113            checkTime(startTime, "startProcess: building args");
3114            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3115                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3116                        && mTopComponent != null
3117                        && app.processName.equals(mTopComponent.getPackageName())) {
3118                    uid = 0;
3119                }
3120                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3121                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3122                    uid = 0;
3123                }
3124            }
3125            int debugFlags = 0;
3126            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3127                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3128                // Also turn on CheckJNI for debuggable apps. It's quite
3129                // awkward to turn on otherwise.
3130                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3131            }
3132            // Run the app in safe mode if its manifest requests so or the
3133            // system is booted in safe mode.
3134            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3135                mSafeMode == true) {
3136                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3137            }
3138            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3139                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3140            }
3141            String jitDebugProperty = SystemProperties.get("debug.usejit");
3142            if ("true".equals(jitDebugProperty)) {
3143                debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3144            } else if (!"false".equals(jitDebugProperty)) {
3145                // If we didn't force disable by setting false, defer to the dalvik vm options.
3146                if ("true".equals(SystemProperties.get("dalvik.vm.usejit"))) {
3147                    debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3148                }
3149            }
3150            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3151                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3152            }
3153            if ("1".equals(SystemProperties.get("debug.assert"))) {
3154                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3155            }
3156
3157            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3158            if (requiredAbi == null) {
3159                requiredAbi = Build.SUPPORTED_ABIS[0];
3160            }
3161
3162            String instructionSet = null;
3163            if (app.info.primaryCpuAbi != null) {
3164                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3165            }
3166
3167            app.gids = gids;
3168            app.requiredAbi = requiredAbi;
3169            app.instructionSet = instructionSet;
3170
3171            // Start the process.  It will either succeed and return a result containing
3172            // the PID of the new process, or else throw a RuntimeException.
3173            boolean isActivityProcess = (entryPoint == null);
3174            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3175            checkTime(startTime, "startProcess: asking zygote to start proc");
3176            Process.ProcessStartResult startResult = Process.start(entryPoint,
3177                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3178                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3179                    app.info.dataDir, entryPointArgs);
3180            checkTime(startTime, "startProcess: returned from zygote!");
3181
3182            if (app.isolated) {
3183                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3184            }
3185            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3186            checkTime(startTime, "startProcess: done updating battery stats");
3187
3188            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3189                    UserHandle.getUserId(uid), startResult.pid, uid,
3190                    app.processName, hostingType,
3191                    hostingNameStr != null ? hostingNameStr : "");
3192
3193            if (app.persistent) {
3194                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3195            }
3196
3197            checkTime(startTime, "startProcess: building log message");
3198            StringBuilder buf = mStringBuilder;
3199            buf.setLength(0);
3200            buf.append("Start proc ");
3201            buf.append(startResult.pid);
3202            buf.append(':');
3203            buf.append(app.processName);
3204            buf.append('/');
3205            UserHandle.formatUid(buf, uid);
3206            if (!isActivityProcess) {
3207                buf.append(" [");
3208                buf.append(entryPoint);
3209                buf.append("]");
3210            }
3211            buf.append(" for ");
3212            buf.append(hostingType);
3213            if (hostingNameStr != null) {
3214                buf.append(" ");
3215                buf.append(hostingNameStr);
3216            }
3217            Slog.i(TAG, buf.toString());
3218            app.setPid(startResult.pid);
3219            app.usingWrapper = startResult.usingWrapper;
3220            app.removed = false;
3221            app.killed = false;
3222            app.killedByAm = false;
3223            checkTime(startTime, "startProcess: starting to update pids map");
3224            synchronized (mPidsSelfLocked) {
3225                this.mPidsSelfLocked.put(startResult.pid, app);
3226                if (isActivityProcess) {
3227                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3228                    msg.obj = app;
3229                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3230                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3231                }
3232            }
3233            checkTime(startTime, "startProcess: done updating pids map");
3234        } catch (RuntimeException e) {
3235            // XXX do better error recovery.
3236            app.setPid(0);
3237            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3238            if (app.isolated) {
3239                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3240            }
3241            Slog.e(TAG, "Failure starting process " + app.processName, e);
3242        }
3243    }
3244
3245    void updateUsageStats(ActivityRecord component, boolean resumed) {
3246        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3247                "updateUsageStats: comp=" + component + "res=" + resumed);
3248        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3249        if (resumed) {
3250            if (mUsageStatsService != null) {
3251                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3252                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3253            }
3254            synchronized (stats) {
3255                stats.noteActivityResumedLocked(component.app.uid);
3256            }
3257        } else {
3258            if (mUsageStatsService != null) {
3259                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3260                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3261            }
3262            synchronized (stats) {
3263                stats.noteActivityPausedLocked(component.app.uid);
3264            }
3265        }
3266    }
3267
3268    Intent getHomeIntent() {
3269        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3270        intent.setComponent(mTopComponent);
3271        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3272            intent.addCategory(Intent.CATEGORY_HOME);
3273        }
3274        return intent;
3275    }
3276
3277    boolean startHomeActivityLocked(int userId, String reason) {
3278        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3279                && mTopAction == null) {
3280            // We are running in factory test mode, but unable to find
3281            // the factory test app, so just sit around displaying the
3282            // error message and don't try to start anything.
3283            return false;
3284        }
3285        Intent intent = getHomeIntent();
3286        ActivityInfo aInfo =
3287            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3288        if (aInfo != null) {
3289            intent.setComponent(new ComponentName(
3290                    aInfo.applicationInfo.packageName, aInfo.name));
3291            // Don't do this if the home app is currently being
3292            // instrumented.
3293            aInfo = new ActivityInfo(aInfo);
3294            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3295            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3296                    aInfo.applicationInfo.uid, true);
3297            if (app == null || app.instrumentationClass == null) {
3298                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3299                mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3300            }
3301        }
3302
3303        return true;
3304    }
3305
3306    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3307        ActivityInfo ai = null;
3308        ComponentName comp = intent.getComponent();
3309        try {
3310            if (comp != null) {
3311                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3312            } else {
3313                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3314                        intent,
3315                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3316                            flags, userId);
3317
3318                if (info != null) {
3319                    ai = info.activityInfo;
3320                }
3321            }
3322        } catch (RemoteException e) {
3323            // ignore
3324        }
3325
3326        return ai;
3327    }
3328
3329    /**
3330     * Starts the "new version setup screen" if appropriate.
3331     */
3332    void startSetupActivityLocked() {
3333        // Only do this once per boot.
3334        if (mCheckedForSetup) {
3335            return;
3336        }
3337
3338        // We will show this screen if the current one is a different
3339        // version than the last one shown, and we are not running in
3340        // low-level factory test mode.
3341        final ContentResolver resolver = mContext.getContentResolver();
3342        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3343                Settings.Global.getInt(resolver,
3344                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3345            mCheckedForSetup = true;
3346
3347            // See if we should be showing the platform update setup UI.
3348            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3349            List<ResolveInfo> ris = mContext.getPackageManager()
3350                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3351
3352            // We don't allow third party apps to replace this.
3353            ResolveInfo ri = null;
3354            for (int i=0; ris != null && i<ris.size(); i++) {
3355                if ((ris.get(i).activityInfo.applicationInfo.flags
3356                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3357                    ri = ris.get(i);
3358                    break;
3359                }
3360            }
3361
3362            if (ri != null) {
3363                String vers = ri.activityInfo.metaData != null
3364                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3365                        : null;
3366                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3367                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3368                            Intent.METADATA_SETUP_VERSION);
3369                }
3370                String lastVers = Settings.Secure.getString(
3371                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3372                if (vers != null && !vers.equals(lastVers)) {
3373                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3374                    intent.setComponent(new ComponentName(
3375                            ri.activityInfo.packageName, ri.activityInfo.name));
3376                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3377                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3378                            null);
3379                }
3380            }
3381        }
3382    }
3383
3384    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3385        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3386    }
3387
3388    void enforceNotIsolatedCaller(String caller) {
3389        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3390            throw new SecurityException("Isolated process not allowed to call " + caller);
3391        }
3392    }
3393
3394    void enforceShellRestriction(String restriction, int userHandle) {
3395        if (Binder.getCallingUid() == Process.SHELL_UID) {
3396            if (userHandle < 0
3397                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3398                throw new SecurityException("Shell does not have permission to access user "
3399                        + userHandle);
3400            }
3401        }
3402    }
3403
3404    @Override
3405    public int getFrontActivityScreenCompatMode() {
3406        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3407        synchronized (this) {
3408            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3409        }
3410    }
3411
3412    @Override
3413    public void setFrontActivityScreenCompatMode(int mode) {
3414        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3415                "setFrontActivityScreenCompatMode");
3416        synchronized (this) {
3417            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3418        }
3419    }
3420
3421    @Override
3422    public int getPackageScreenCompatMode(String packageName) {
3423        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3424        synchronized (this) {
3425            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3426        }
3427    }
3428
3429    @Override
3430    public void setPackageScreenCompatMode(String packageName, int mode) {
3431        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3432                "setPackageScreenCompatMode");
3433        synchronized (this) {
3434            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3435        }
3436    }
3437
3438    @Override
3439    public boolean getPackageAskScreenCompat(String packageName) {
3440        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3441        synchronized (this) {
3442            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3443        }
3444    }
3445
3446    @Override
3447    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3448        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3449                "setPackageAskScreenCompat");
3450        synchronized (this) {
3451            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3452        }
3453    }
3454
3455    @Override
3456    public int getPackageProcessState(String packageName) {
3457        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3458        synchronized (this) {
3459            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3460                final ProcessRecord proc = mLruProcesses.get(i);
3461                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3462                        || procState > proc.setProcState) {
3463                    boolean found = false;
3464                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3465                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3466                            procState = proc.setProcState;
3467                            found = true;
3468                        }
3469                    }
3470                    if (proc.pkgDeps != null && !found) {
3471                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3472                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3473                                procState = proc.setProcState;
3474                                break;
3475                            }
3476                        }
3477                    }
3478                }
3479            }
3480        }
3481        return procState;
3482    }
3483
3484    private void dispatchProcessesChanged() {
3485        int N;
3486        synchronized (this) {
3487            N = mPendingProcessChanges.size();
3488            if (mActiveProcessChanges.length < N) {
3489                mActiveProcessChanges = new ProcessChangeItem[N];
3490            }
3491            mPendingProcessChanges.toArray(mActiveProcessChanges);
3492            mAvailProcessChanges.addAll(mPendingProcessChanges);
3493            mPendingProcessChanges.clear();
3494            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3495                    "*** Delivering " + N + " process changes");
3496        }
3497
3498        int i = mProcessObservers.beginBroadcast();
3499        while (i > 0) {
3500            i--;
3501            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3502            if (observer != null) {
3503                try {
3504                    for (int j=0; j<N; j++) {
3505                        ProcessChangeItem item = mActiveProcessChanges[j];
3506                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3507                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3508                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3509                                    + item.uid + ": " + item.foregroundActivities);
3510                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3511                                    item.foregroundActivities);
3512                        }
3513                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3514                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3515                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3516                                    + ": " + item.processState);
3517                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3518                        }
3519                    }
3520                } catch (RemoteException e) {
3521                }
3522            }
3523        }
3524        mProcessObservers.finishBroadcast();
3525    }
3526
3527    private void dispatchProcessDied(int pid, int uid) {
3528        int i = mProcessObservers.beginBroadcast();
3529        while (i > 0) {
3530            i--;
3531            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3532            if (observer != null) {
3533                try {
3534                    observer.onProcessDied(pid, uid);
3535                } catch (RemoteException e) {
3536                }
3537            }
3538        }
3539        mProcessObservers.finishBroadcast();
3540    }
3541
3542    @Override
3543    public final int startActivity(IApplicationThread caller, String callingPackage,
3544            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3545            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3546        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3547            resultWho, requestCode, startFlags, profilerInfo, options,
3548            UserHandle.getCallingUserId());
3549    }
3550
3551    @Override
3552    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3553            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3554            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3555        enforceNotIsolatedCaller("startActivity");
3556        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3557                false, ALLOW_FULL_ONLY, "startActivity", null);
3558        // TODO: Switch to user app stacks here.
3559        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3560                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3561                profilerInfo, null, null, options, userId, null, null);
3562    }
3563
3564    @Override
3565    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3566            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3567            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3568
3569        // This is very dangerous -- it allows you to perform a start activity (including
3570        // permission grants) as any app that may launch one of your own activities.  So
3571        // we will only allow this to be done from activities that are part of the core framework,
3572        // and then only when they are running as the system.
3573        final ActivityRecord sourceRecord;
3574        final int targetUid;
3575        final String targetPackage;
3576        synchronized (this) {
3577            if (resultTo == null) {
3578                throw new SecurityException("Must be called from an activity");
3579            }
3580            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3581            if (sourceRecord == null) {
3582                throw new SecurityException("Called with bad activity token: " + resultTo);
3583            }
3584            if (!sourceRecord.info.packageName.equals("android")) {
3585                throw new SecurityException(
3586                        "Must be called from an activity that is declared in the android package");
3587            }
3588            if (sourceRecord.app == null) {
3589                throw new SecurityException("Called without a process attached to activity");
3590            }
3591            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3592                // This is still okay, as long as this activity is running under the
3593                // uid of the original calling activity.
3594                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3595                    throw new SecurityException(
3596                            "Calling activity in uid " + sourceRecord.app.uid
3597                                    + " must be system uid or original calling uid "
3598                                    + sourceRecord.launchedFromUid);
3599                }
3600            }
3601            targetUid = sourceRecord.launchedFromUid;
3602            targetPackage = sourceRecord.launchedFromPackage;
3603        }
3604
3605        if (userId == UserHandle.USER_NULL) {
3606            userId = UserHandle.getUserId(sourceRecord.app.uid);
3607        }
3608
3609        // TODO: Switch to user app stacks here.
3610        try {
3611            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3612                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3613                    null, null, options, userId, null, null);
3614            return ret;
3615        } catch (SecurityException e) {
3616            // XXX need to figure out how to propagate to original app.
3617            // A SecurityException here is generally actually a fault of the original
3618            // calling activity (such as a fairly granting permissions), so propagate it
3619            // back to them.
3620            /*
3621            StringBuilder msg = new StringBuilder();
3622            msg.append("While launching");
3623            msg.append(intent.toString());
3624            msg.append(": ");
3625            msg.append(e.getMessage());
3626            */
3627            throw e;
3628        }
3629    }
3630
3631    @Override
3632    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3633            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3634            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3635        enforceNotIsolatedCaller("startActivityAndWait");
3636        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3637                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3638        WaitResult res = new WaitResult();
3639        // TODO: Switch to user app stacks here.
3640        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3641                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3642                options, userId, null, null);
3643        return res;
3644    }
3645
3646    @Override
3647    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3648            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3649            int startFlags, Configuration config, Bundle options, int userId) {
3650        enforceNotIsolatedCaller("startActivityWithConfig");
3651        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3652                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3653        // TODO: Switch to user app stacks here.
3654        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3655                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3656                null, null, config, options, userId, null, null);
3657        return ret;
3658    }
3659
3660    @Override
3661    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
3662            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
3663            int requestCode, int flagsMask, int flagsValues, Bundle options)
3664            throws TransactionTooLargeException {
3665        enforceNotIsolatedCaller("startActivityIntentSender");
3666        // Refuse possible leaked file descriptors
3667        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3668            throw new IllegalArgumentException("File descriptors passed in Intent");
3669        }
3670
3671        IIntentSender sender = intent.getTarget();
3672        if (!(sender instanceof PendingIntentRecord)) {
3673            throw new IllegalArgumentException("Bad PendingIntent object");
3674        }
3675
3676        PendingIntentRecord pir = (PendingIntentRecord)sender;
3677
3678        synchronized (this) {
3679            // If this is coming from the currently resumed activity, it is
3680            // effectively saying that app switches are allowed at this point.
3681            final ActivityStack stack = getFocusedStack();
3682            if (stack.mResumedActivity != null &&
3683                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3684                mAppSwitchesAllowedTime = 0;
3685            }
3686        }
3687        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3688                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3689        return ret;
3690    }
3691
3692    @Override
3693    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3694            Intent intent, String resolvedType, IVoiceInteractionSession session,
3695            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3696            Bundle options, int userId) {
3697        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3698                != PackageManager.PERMISSION_GRANTED) {
3699            String msg = "Permission Denial: startVoiceActivity() from pid="
3700                    + Binder.getCallingPid()
3701                    + ", uid=" + Binder.getCallingUid()
3702                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3703            Slog.w(TAG, msg);
3704            throw new SecurityException(msg);
3705        }
3706        if (session == null || interactor == null) {
3707            throw new NullPointerException("null session or interactor");
3708        }
3709        userId = handleIncomingUser(callingPid, callingUid, userId,
3710                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3711        // TODO: Switch to user app stacks here.
3712        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3713                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3714                null, options, userId, null, null);
3715    }
3716
3717    @Override
3718    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
3719        synchronized (this) {
3720            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
3721                if (keepAwake) {
3722                    mVoiceWakeLock.acquire();
3723                } else {
3724                    mVoiceWakeLock.release();
3725                }
3726            }
3727        }
3728    }
3729
3730    @Override
3731    public boolean startNextMatchingActivity(IBinder callingActivity,
3732            Intent intent, Bundle options) {
3733        // Refuse possible leaked file descriptors
3734        if (intent != null && intent.hasFileDescriptors() == true) {
3735            throw new IllegalArgumentException("File descriptors passed in Intent");
3736        }
3737
3738        synchronized (this) {
3739            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3740            if (r == null) {
3741                ActivityOptions.abort(options);
3742                return false;
3743            }
3744            if (r.app == null || r.app.thread == null) {
3745                // The caller is not running...  d'oh!
3746                ActivityOptions.abort(options);
3747                return false;
3748            }
3749            intent = new Intent(intent);
3750            // The caller is not allowed to change the data.
3751            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3752            // And we are resetting to find the next component...
3753            intent.setComponent(null);
3754
3755            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3756
3757            ActivityInfo aInfo = null;
3758            try {
3759                List<ResolveInfo> resolves =
3760                    AppGlobals.getPackageManager().queryIntentActivities(
3761                            intent, r.resolvedType,
3762                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3763                            UserHandle.getCallingUserId());
3764
3765                // Look for the original activity in the list...
3766                final int N = resolves != null ? resolves.size() : 0;
3767                for (int i=0; i<N; i++) {
3768                    ResolveInfo rInfo = resolves.get(i);
3769                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3770                            && rInfo.activityInfo.name.equals(r.info.name)) {
3771                        // We found the current one...  the next matching is
3772                        // after it.
3773                        i++;
3774                        if (i<N) {
3775                            aInfo = resolves.get(i).activityInfo;
3776                        }
3777                        if (debug) {
3778                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3779                                    + "/" + r.info.name);
3780                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3781                                    + "/" + aInfo.name);
3782                        }
3783                        break;
3784                    }
3785                }
3786            } catch (RemoteException e) {
3787            }
3788
3789            if (aInfo == null) {
3790                // Nobody who is next!
3791                ActivityOptions.abort(options);
3792                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3793                return false;
3794            }
3795
3796            intent.setComponent(new ComponentName(
3797                    aInfo.applicationInfo.packageName, aInfo.name));
3798            intent.setFlags(intent.getFlags()&~(
3799                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3800                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3801                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3802                    Intent.FLAG_ACTIVITY_NEW_TASK));
3803
3804            // Okay now we need to start the new activity, replacing the
3805            // currently running activity.  This is a little tricky because
3806            // we want to start the new one as if the current one is finished,
3807            // but not finish the current one first so that there is no flicker.
3808            // And thus...
3809            final boolean wasFinishing = r.finishing;
3810            r.finishing = true;
3811
3812            // Propagate reply information over to the new activity.
3813            final ActivityRecord resultTo = r.resultTo;
3814            final String resultWho = r.resultWho;
3815            final int requestCode = r.requestCode;
3816            r.resultTo = null;
3817            if (resultTo != null) {
3818                resultTo.removeResultsLocked(r, resultWho, requestCode);
3819            }
3820
3821            final long origId = Binder.clearCallingIdentity();
3822            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3823                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3824                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3825                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3826            Binder.restoreCallingIdentity(origId);
3827
3828            r.finishing = wasFinishing;
3829            if (res != ActivityManager.START_SUCCESS) {
3830                return false;
3831            }
3832            return true;
3833        }
3834    }
3835
3836    @Override
3837    public final int startActivityFromRecents(int taskId, Bundle options) {
3838        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3839            String msg = "Permission Denial: startActivityFromRecents called without " +
3840                    START_TASKS_FROM_RECENTS;
3841            Slog.w(TAG, msg);
3842            throw new SecurityException(msg);
3843        }
3844        return startActivityFromRecentsInner(taskId, options);
3845    }
3846
3847    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3848        final TaskRecord task;
3849        final int callingUid;
3850        final String callingPackage;
3851        final Intent intent;
3852        final int userId;
3853        synchronized (this) {
3854            task = mRecentTasks.taskForIdLocked(taskId);
3855            if (task == null) {
3856                throw new IllegalArgumentException("Task " + taskId + " not found.");
3857            }
3858            if (task.getRootActivity() != null) {
3859                moveTaskToFrontLocked(task.taskId, 0, null);
3860                return ActivityManager.START_TASK_TO_FRONT;
3861            }
3862            callingUid = task.mCallingUid;
3863            callingPackage = task.mCallingPackage;
3864            intent = task.intent;
3865            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3866            userId = task.userId;
3867        }
3868        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3869                options, userId, null, task);
3870    }
3871
3872    final int startActivityInPackage(int uid, String callingPackage,
3873            Intent intent, String resolvedType, IBinder resultTo,
3874            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3875            IActivityContainer container, TaskRecord inTask) {
3876
3877        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3878                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3879
3880        // TODO: Switch to user app stacks here.
3881        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3882                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3883                null, null, null, options, userId, container, inTask);
3884        return ret;
3885    }
3886
3887    @Override
3888    public final int startActivities(IApplicationThread caller, String callingPackage,
3889            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3890            int userId) {
3891        enforceNotIsolatedCaller("startActivities");
3892        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3893                false, ALLOW_FULL_ONLY, "startActivity", null);
3894        // TODO: Switch to user app stacks here.
3895        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3896                resolvedTypes, resultTo, options, userId);
3897        return ret;
3898    }
3899
3900    final int startActivitiesInPackage(int uid, String callingPackage,
3901            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3902            Bundle options, int userId) {
3903
3904        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3905                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3906        // TODO: Switch to user app stacks here.
3907        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3908                resultTo, options, userId);
3909        return ret;
3910    }
3911
3912    @Override
3913    public void reportActivityFullyDrawn(IBinder token) {
3914        synchronized (this) {
3915            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3916            if (r == null) {
3917                return;
3918            }
3919            r.reportFullyDrawnLocked();
3920        }
3921    }
3922
3923    @Override
3924    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3925        synchronized (this) {
3926            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3927            if (r == null) {
3928                return;
3929            }
3930            if (r.task != null && r.task.mResizeable) {
3931                // Fixed screen orientation isn't supported with resizeable activities.
3932                return;
3933            }
3934            final long origId = Binder.clearCallingIdentity();
3935            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3936            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3937                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3938            if (config != null) {
3939                r.frozenBeforeDestroy = true;
3940                if (!updateConfigurationLocked(config, r, false, false)) {
3941                    mStackSupervisor.resumeTopActivitiesLocked();
3942                }
3943            }
3944            Binder.restoreCallingIdentity(origId);
3945        }
3946    }
3947
3948    @Override
3949    public int getRequestedOrientation(IBinder token) {
3950        synchronized (this) {
3951            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3952            if (r == null) {
3953                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3954            }
3955            return mWindowManager.getAppOrientation(r.appToken);
3956        }
3957    }
3958
3959    /**
3960     * This is the internal entry point for handling Activity.finish().
3961     *
3962     * @param token The Binder token referencing the Activity we want to finish.
3963     * @param resultCode Result code, if any, from this Activity.
3964     * @param resultData Result data (Intent), if any, from this Activity.
3965     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3966     *            the root Activity in the task.
3967     *
3968     * @return Returns true if the activity successfully finished, or false if it is still running.
3969     */
3970    @Override
3971    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3972            boolean finishTask) {
3973        // Refuse possible leaked file descriptors
3974        if (resultData != null && resultData.hasFileDescriptors() == true) {
3975            throw new IllegalArgumentException("File descriptors passed in Intent");
3976        }
3977
3978        synchronized(this) {
3979            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3980            if (r == null) {
3981                return true;
3982            }
3983            // Keep track of the root activity of the task before we finish it
3984            TaskRecord tr = r.task;
3985            ActivityRecord rootR = tr.getRootActivity();
3986            if (rootR == null) {
3987                Slog.w(TAG, "Finishing task with all activities already finished");
3988            }
3989            // Do not allow task to finish if last task in lockTask mode. Launchable apps can
3990            // finish themselves.
3991            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE && rootR == r &&
3992                    mStackSupervisor.isLastLockedTask(tr)) {
3993                Slog.i(TAG, "Not finishing task in lock task mode");
3994                mStackSupervisor.showLockTaskToast();
3995                return false;
3996            }
3997            if (mController != null) {
3998                // Find the first activity that is not finishing.
3999                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4000                if (next != null) {
4001                    // ask watcher if this is allowed
4002                    boolean resumeOK = true;
4003                    try {
4004                        resumeOK = mController.activityResuming(next.packageName);
4005                    } catch (RemoteException e) {
4006                        mController = null;
4007                        Watchdog.getInstance().setActivityController(null);
4008                    }
4009
4010                    if (!resumeOK) {
4011                        Slog.i(TAG, "Not finishing activity because controller resumed");
4012                        return false;
4013                    }
4014                }
4015            }
4016            final long origId = Binder.clearCallingIdentity();
4017            try {
4018                boolean res;
4019                if (finishTask && r == rootR) {
4020                    // If requested, remove the task that is associated to this activity only if it
4021                    // was the root activity in the task. The result code and data is ignored
4022                    // because we don't support returning them across task boundaries.
4023                    res = removeTaskByIdLocked(tr.taskId, false);
4024                    if (!res) {
4025                        Slog.i(TAG, "Removing task failed to finish activity");
4026                    }
4027                } else {
4028                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4029                            resultData, "app-request", true);
4030                    if (!res) {
4031                        Slog.i(TAG, "Failed to finish by app-request");
4032                    }
4033                }
4034                return res;
4035            } finally {
4036                Binder.restoreCallingIdentity(origId);
4037            }
4038        }
4039    }
4040
4041    @Override
4042    public final void finishHeavyWeightApp() {
4043        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4044                != PackageManager.PERMISSION_GRANTED) {
4045            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4046                    + Binder.getCallingPid()
4047                    + ", uid=" + Binder.getCallingUid()
4048                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4049            Slog.w(TAG, msg);
4050            throw new SecurityException(msg);
4051        }
4052
4053        synchronized(this) {
4054            if (mHeavyWeightProcess == null) {
4055                return;
4056            }
4057
4058            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4059            for (int i = 0; i < activities.size(); i++) {
4060                ActivityRecord r = activities.get(i);
4061                if (!r.finishing && r.isInStackLocked()) {
4062                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4063                            null, "finish-heavy", true);
4064                }
4065            }
4066
4067            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4068                    mHeavyWeightProcess.userId, 0));
4069            mHeavyWeightProcess = null;
4070        }
4071    }
4072
4073    @Override
4074    public void crashApplication(int uid, int initialPid, String packageName,
4075            String message) {
4076        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4077                != PackageManager.PERMISSION_GRANTED) {
4078            String msg = "Permission Denial: crashApplication() from pid="
4079                    + Binder.getCallingPid()
4080                    + ", uid=" + Binder.getCallingUid()
4081                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4082            Slog.w(TAG, msg);
4083            throw new SecurityException(msg);
4084        }
4085
4086        synchronized(this) {
4087            ProcessRecord proc = null;
4088
4089            // Figure out which process to kill.  We don't trust that initialPid
4090            // still has any relation to current pids, so must scan through the
4091            // list.
4092            synchronized (mPidsSelfLocked) {
4093                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4094                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4095                    if (p.uid != uid) {
4096                        continue;
4097                    }
4098                    if (p.pid == initialPid) {
4099                        proc = p;
4100                        break;
4101                    }
4102                    if (p.pkgList.containsKey(packageName)) {
4103                        proc = p;
4104                    }
4105                }
4106            }
4107
4108            if (proc == null) {
4109                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4110                        + " initialPid=" + initialPid
4111                        + " packageName=" + packageName);
4112                return;
4113            }
4114
4115            if (proc.thread != null) {
4116                if (proc.pid == Process.myPid()) {
4117                    Log.w(TAG, "crashApplication: trying to crash self!");
4118                    return;
4119                }
4120                long ident = Binder.clearCallingIdentity();
4121                try {
4122                    proc.thread.scheduleCrash(message);
4123                } catch (RemoteException e) {
4124                }
4125                Binder.restoreCallingIdentity(ident);
4126            }
4127        }
4128    }
4129
4130    @Override
4131    public final void finishSubActivity(IBinder token, String resultWho,
4132            int requestCode) {
4133        synchronized(this) {
4134            final long origId = Binder.clearCallingIdentity();
4135            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4136            if (r != null) {
4137                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4138            }
4139            Binder.restoreCallingIdentity(origId);
4140        }
4141    }
4142
4143    @Override
4144    public boolean finishActivityAffinity(IBinder token) {
4145        synchronized(this) {
4146            final long origId = Binder.clearCallingIdentity();
4147            try {
4148                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4149                if (r == null) {
4150                    return false;
4151                }
4152
4153                // Do not allow the last non-launchable task to finish in Lock Task mode.
4154                final TaskRecord task = r.task;
4155                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE &&
4156                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4157                    mStackSupervisor.showLockTaskToast();
4158                    return false;
4159                }
4160                return task.stack.finishActivityAffinityLocked(r);
4161            } finally {
4162                Binder.restoreCallingIdentity(origId);
4163            }
4164        }
4165    }
4166
4167    @Override
4168    public void finishVoiceTask(IVoiceInteractionSession session) {
4169        synchronized(this) {
4170            final long origId = Binder.clearCallingIdentity();
4171            try {
4172                mStackSupervisor.finishVoiceTask(session);
4173            } finally {
4174                Binder.restoreCallingIdentity(origId);
4175            }
4176        }
4177
4178    }
4179
4180    @Override
4181    public boolean releaseActivityInstance(IBinder token) {
4182        synchronized(this) {
4183            final long origId = Binder.clearCallingIdentity();
4184            try {
4185                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4186                if (r == null) {
4187                    return false;
4188                }
4189                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4190            } finally {
4191                Binder.restoreCallingIdentity(origId);
4192            }
4193        }
4194    }
4195
4196    @Override
4197    public void releaseSomeActivities(IApplicationThread appInt) {
4198        synchronized(this) {
4199            final long origId = Binder.clearCallingIdentity();
4200            try {
4201                ProcessRecord app = getRecordForAppLocked(appInt);
4202                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4203            } finally {
4204                Binder.restoreCallingIdentity(origId);
4205            }
4206        }
4207    }
4208
4209    @Override
4210    public boolean willActivityBeVisible(IBinder token) {
4211        synchronized(this) {
4212            ActivityStack stack = ActivityRecord.getStackLocked(token);
4213            if (stack != null) {
4214                return stack.willActivityBeVisibleLocked(token);
4215            }
4216            return false;
4217        }
4218    }
4219
4220    @Override
4221    public void overridePendingTransition(IBinder token, String packageName,
4222            int enterAnim, int exitAnim) {
4223        synchronized(this) {
4224            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4225            if (self == null) {
4226                return;
4227            }
4228
4229            final long origId = Binder.clearCallingIdentity();
4230
4231            if (self.state == ActivityState.RESUMED
4232                    || self.state == ActivityState.PAUSING) {
4233                mWindowManager.overridePendingAppTransition(packageName,
4234                        enterAnim, exitAnim, null);
4235            }
4236
4237            Binder.restoreCallingIdentity(origId);
4238        }
4239    }
4240
4241    /**
4242     * Main function for removing an existing process from the activity manager
4243     * as a result of that process going away.  Clears out all connections
4244     * to the process.
4245     */
4246    private final void handleAppDiedLocked(ProcessRecord app,
4247            boolean restarting, boolean allowRestart) {
4248        int pid = app.pid;
4249        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4250        if (!kept && !restarting) {
4251            removeLruProcessLocked(app);
4252            if (pid > 0) {
4253                ProcessList.remove(pid);
4254            }
4255        }
4256
4257        if (mProfileProc == app) {
4258            clearProfilerLocked();
4259        }
4260
4261        // Remove this application's activities from active lists.
4262        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4263
4264        app.activities.clear();
4265
4266        if (app.instrumentationClass != null) {
4267            Slog.w(TAG, "Crash of app " + app.processName
4268                  + " running instrumentation " + app.instrumentationClass);
4269            Bundle info = new Bundle();
4270            info.putString("shortMsg", "Process crashed.");
4271            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4272        }
4273
4274        if (!restarting && hasVisibleActivities && !mStackSupervisor.resumeTopActivitiesLocked()) {
4275            // If there was nothing to resume, and we are not already
4276            // restarting this process, but there is a visible activity that
4277            // is hosted by the process...  then make sure all visible
4278            // activities are running, taking care of restarting this
4279            // process.
4280            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4281        }
4282    }
4283
4284    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4285        IBinder threadBinder = thread.asBinder();
4286        // Find the application record.
4287        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4288            ProcessRecord rec = mLruProcesses.get(i);
4289            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4290                return i;
4291            }
4292        }
4293        return -1;
4294    }
4295
4296    final ProcessRecord getRecordForAppLocked(
4297            IApplicationThread thread) {
4298        if (thread == null) {
4299            return null;
4300        }
4301
4302        int appIndex = getLRURecordIndexForAppLocked(thread);
4303        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4304    }
4305
4306    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4307        // If there are no longer any background processes running,
4308        // and the app that died was not running instrumentation,
4309        // then tell everyone we are now low on memory.
4310        boolean haveBg = false;
4311        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4312            ProcessRecord rec = mLruProcesses.get(i);
4313            if (rec.thread != null
4314                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4315                haveBg = true;
4316                break;
4317            }
4318        }
4319
4320        if (!haveBg) {
4321            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4322            if (doReport) {
4323                long now = SystemClock.uptimeMillis();
4324                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4325                    doReport = false;
4326                } else {
4327                    mLastMemUsageReportTime = now;
4328                }
4329            }
4330            final ArrayList<ProcessMemInfo> memInfos
4331                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4332            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4333            long now = SystemClock.uptimeMillis();
4334            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4335                ProcessRecord rec = mLruProcesses.get(i);
4336                if (rec == dyingProc || rec.thread == null) {
4337                    continue;
4338                }
4339                if (doReport) {
4340                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4341                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4342                }
4343                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4344                    // The low memory report is overriding any current
4345                    // state for a GC request.  Make sure to do
4346                    // heavy/important/visible/foreground processes first.
4347                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4348                        rec.lastRequestedGc = 0;
4349                    } else {
4350                        rec.lastRequestedGc = rec.lastLowMemory;
4351                    }
4352                    rec.reportLowMemory = true;
4353                    rec.lastLowMemory = now;
4354                    mProcessesToGc.remove(rec);
4355                    addProcessToGcListLocked(rec);
4356                }
4357            }
4358            if (doReport) {
4359                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4360                mHandler.sendMessage(msg);
4361            }
4362            scheduleAppGcsLocked();
4363        }
4364    }
4365
4366    final void appDiedLocked(ProcessRecord app) {
4367       appDiedLocked(app, app.pid, app.thread, false);
4368    }
4369
4370    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4371            boolean fromBinderDied) {
4372        // First check if this ProcessRecord is actually active for the pid.
4373        synchronized (mPidsSelfLocked) {
4374            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4375            if (curProc != app) {
4376                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4377                return;
4378            }
4379        }
4380
4381        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4382        synchronized (stats) {
4383            stats.noteProcessDiedLocked(app.info.uid, pid);
4384        }
4385
4386        if (!app.killed) {
4387            if (!fromBinderDied) {
4388                Process.killProcessQuiet(pid);
4389            }
4390            Process.killProcessGroup(app.info.uid, pid);
4391            app.killed = true;
4392        }
4393
4394        // Clean up already done if the process has been re-started.
4395        if (app.pid == pid && app.thread != null &&
4396                app.thread.asBinder() == thread.asBinder()) {
4397            boolean doLowMem = app.instrumentationClass == null;
4398            boolean doOomAdj = doLowMem;
4399            if (!app.killedByAm) {
4400                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4401                        + ") has died");
4402                mAllowLowerMemLevel = true;
4403            } else {
4404                // Note that we always want to do oom adj to update our state with the
4405                // new number of procs.
4406                mAllowLowerMemLevel = false;
4407                doLowMem = false;
4408            }
4409            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4410            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4411                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
4412            handleAppDiedLocked(app, false, true);
4413
4414            if (doOomAdj) {
4415                updateOomAdjLocked();
4416            }
4417            if (doLowMem) {
4418                doLowMemReportIfNeededLocked(app);
4419            }
4420        } else if (app.pid != pid) {
4421            // A new process has already been started.
4422            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4423                    + ") has died and restarted (pid " + app.pid + ").");
4424            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4425        } else if (DEBUG_PROCESSES) {
4426            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
4427                    + thread.asBinder());
4428        }
4429    }
4430
4431    /**
4432     * If a stack trace dump file is configured, dump process stack traces.
4433     * @param clearTraces causes the dump file to be erased prior to the new
4434     *    traces being written, if true; when false, the new traces will be
4435     *    appended to any existing file content.
4436     * @param firstPids of dalvik VM processes to dump stack traces for first
4437     * @param lastPids of dalvik VM processes to dump stack traces for last
4438     * @param nativeProcs optional list of native process names to dump stack crawls
4439     * @return file containing stack traces, or null if no dump file is configured
4440     */
4441    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4442            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4443        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4444        if (tracesPath == null || tracesPath.length() == 0) {
4445            return null;
4446        }
4447
4448        File tracesFile = new File(tracesPath);
4449        try {
4450            File tracesDir = tracesFile.getParentFile();
4451            if (!tracesDir.exists()) {
4452                tracesDir.mkdirs();
4453                if (!SELinux.restorecon(tracesDir)) {
4454                    return null;
4455                }
4456            }
4457            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4458
4459            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4460            tracesFile.createNewFile();
4461            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4462        } catch (IOException e) {
4463            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4464            return null;
4465        }
4466
4467        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4468        return tracesFile;
4469    }
4470
4471    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4472            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4473        // Use a FileObserver to detect when traces finish writing.
4474        // The order of traces is considered important to maintain for legibility.
4475        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4476            @Override
4477            public synchronized void onEvent(int event, String path) { notify(); }
4478        };
4479
4480        try {
4481            observer.startWatching();
4482
4483            // First collect all of the stacks of the most important pids.
4484            if (firstPids != null) {
4485                try {
4486                    int num = firstPids.size();
4487                    for (int i = 0; i < num; i++) {
4488                        synchronized (observer) {
4489                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4490                            observer.wait(200);  // Wait for write-close, give up after 200msec
4491                        }
4492                    }
4493                } catch (InterruptedException e) {
4494                    Slog.wtf(TAG, e);
4495                }
4496            }
4497
4498            // Next collect the stacks of the native pids
4499            if (nativeProcs != null) {
4500                int[] pids = Process.getPidsForCommands(nativeProcs);
4501                if (pids != null) {
4502                    for (int pid : pids) {
4503                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4504                    }
4505                }
4506            }
4507
4508            // Lastly, measure CPU usage.
4509            if (processCpuTracker != null) {
4510                processCpuTracker.init();
4511                System.gc();
4512                processCpuTracker.update();
4513                try {
4514                    synchronized (processCpuTracker) {
4515                        processCpuTracker.wait(500); // measure over 1/2 second.
4516                    }
4517                } catch (InterruptedException e) {
4518                }
4519                processCpuTracker.update();
4520
4521                // We'll take the stack crawls of just the top apps using CPU.
4522                final int N = processCpuTracker.countWorkingStats();
4523                int numProcs = 0;
4524                for (int i=0; i<N && numProcs<5; i++) {
4525                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4526                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4527                        numProcs++;
4528                        try {
4529                            synchronized (observer) {
4530                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4531                                observer.wait(200);  // Wait for write-close, give up after 200msec
4532                            }
4533                        } catch (InterruptedException e) {
4534                            Slog.wtf(TAG, e);
4535                        }
4536
4537                    }
4538                }
4539            }
4540        } finally {
4541            observer.stopWatching();
4542        }
4543    }
4544
4545    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4546        if (true || IS_USER_BUILD) {
4547            return;
4548        }
4549        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4550        if (tracesPath == null || tracesPath.length() == 0) {
4551            return;
4552        }
4553
4554        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4555        StrictMode.allowThreadDiskWrites();
4556        try {
4557            final File tracesFile = new File(tracesPath);
4558            final File tracesDir = tracesFile.getParentFile();
4559            final File tracesTmp = new File(tracesDir, "__tmp__");
4560            try {
4561                if (!tracesDir.exists()) {
4562                    tracesDir.mkdirs();
4563                    if (!SELinux.restorecon(tracesDir.getPath())) {
4564                        return;
4565                    }
4566                }
4567                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4568
4569                if (tracesFile.exists()) {
4570                    tracesTmp.delete();
4571                    tracesFile.renameTo(tracesTmp);
4572                }
4573                StringBuilder sb = new StringBuilder();
4574                Time tobj = new Time();
4575                tobj.set(System.currentTimeMillis());
4576                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4577                sb.append(": ");
4578                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4579                sb.append(" since ");
4580                sb.append(msg);
4581                FileOutputStream fos = new FileOutputStream(tracesFile);
4582                fos.write(sb.toString().getBytes());
4583                if (app == null) {
4584                    fos.write("\n*** No application process!".getBytes());
4585                }
4586                fos.close();
4587                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4588            } catch (IOException e) {
4589                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4590                return;
4591            }
4592
4593            if (app != null) {
4594                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4595                firstPids.add(app.pid);
4596                dumpStackTraces(tracesPath, firstPids, null, null, null);
4597            }
4598
4599            File lastTracesFile = null;
4600            File curTracesFile = null;
4601            for (int i=9; i>=0; i--) {
4602                String name = String.format(Locale.US, "slow%02d.txt", i);
4603                curTracesFile = new File(tracesDir, name);
4604                if (curTracesFile.exists()) {
4605                    if (lastTracesFile != null) {
4606                        curTracesFile.renameTo(lastTracesFile);
4607                    } else {
4608                        curTracesFile.delete();
4609                    }
4610                }
4611                lastTracesFile = curTracesFile;
4612            }
4613            tracesFile.renameTo(curTracesFile);
4614            if (tracesTmp.exists()) {
4615                tracesTmp.renameTo(tracesFile);
4616            }
4617        } finally {
4618            StrictMode.setThreadPolicy(oldPolicy);
4619        }
4620    }
4621
4622    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4623            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4624        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4625        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4626
4627        if (mController != null) {
4628            try {
4629                // 0 == continue, -1 = kill process immediately
4630                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4631                if (res < 0 && app.pid != MY_PID) {
4632                    app.kill("anr", true);
4633                }
4634            } catch (RemoteException e) {
4635                mController = null;
4636                Watchdog.getInstance().setActivityController(null);
4637            }
4638        }
4639
4640        long anrTime = SystemClock.uptimeMillis();
4641        if (MONITOR_CPU_USAGE) {
4642            updateCpuStatsNow();
4643        }
4644
4645        synchronized (this) {
4646            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4647            if (mShuttingDown) {
4648                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4649                return;
4650            } else if (app.notResponding) {
4651                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4652                return;
4653            } else if (app.crashing) {
4654                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4655                return;
4656            }
4657
4658            // In case we come through here for the same app before completing
4659            // this one, mark as anring now so we will bail out.
4660            app.notResponding = true;
4661
4662            // Log the ANR to the event log.
4663            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4664                    app.processName, app.info.flags, annotation);
4665
4666            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4667            firstPids.add(app.pid);
4668
4669            int parentPid = app.pid;
4670            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4671            if (parentPid != app.pid) firstPids.add(parentPid);
4672
4673            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4674
4675            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4676                ProcessRecord r = mLruProcesses.get(i);
4677                if (r != null && r.thread != null) {
4678                    int pid = r.pid;
4679                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4680                        if (r.persistent) {
4681                            firstPids.add(pid);
4682                        } else {
4683                            lastPids.put(pid, Boolean.TRUE);
4684                        }
4685                    }
4686                }
4687            }
4688        }
4689
4690        // Log the ANR to the main log.
4691        StringBuilder info = new StringBuilder();
4692        info.setLength(0);
4693        info.append("ANR in ").append(app.processName);
4694        if (activity != null && activity.shortComponentName != null) {
4695            info.append(" (").append(activity.shortComponentName).append(")");
4696        }
4697        info.append("\n");
4698        info.append("PID: ").append(app.pid).append("\n");
4699        if (annotation != null) {
4700            info.append("Reason: ").append(annotation).append("\n");
4701        }
4702        if (parent != null && parent != activity) {
4703            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4704        }
4705
4706        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4707
4708        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4709                NATIVE_STACKS_OF_INTEREST);
4710
4711        String cpuInfo = null;
4712        if (MONITOR_CPU_USAGE) {
4713            updateCpuStatsNow();
4714            synchronized (mProcessCpuTracker) {
4715                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4716            }
4717            info.append(processCpuTracker.printCurrentLoad());
4718            info.append(cpuInfo);
4719        }
4720
4721        info.append(processCpuTracker.printCurrentState(anrTime));
4722
4723        Slog.e(TAG, info.toString());
4724        if (tracesFile == null) {
4725            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4726            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4727        }
4728
4729        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4730                cpuInfo, tracesFile, null);
4731
4732        if (mController != null) {
4733            try {
4734                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4735                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4736                if (res != 0) {
4737                    if (res < 0 && app.pid != MY_PID) {
4738                        app.kill("anr", true);
4739                    } else {
4740                        synchronized (this) {
4741                            mServices.scheduleServiceTimeoutLocked(app);
4742                        }
4743                    }
4744                    return;
4745                }
4746            } catch (RemoteException e) {
4747                mController = null;
4748                Watchdog.getInstance().setActivityController(null);
4749            }
4750        }
4751
4752        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4753        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4754                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4755
4756        synchronized (this) {
4757            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
4758
4759            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4760                app.kill("bg anr", true);
4761                return;
4762            }
4763
4764            // Set the app's notResponding state, and look up the errorReportReceiver
4765            makeAppNotRespondingLocked(app,
4766                    activity != null ? activity.shortComponentName : null,
4767                    annotation != null ? "ANR " + annotation : "ANR",
4768                    info.toString());
4769
4770            // Bring up the infamous App Not Responding dialog
4771            Message msg = Message.obtain();
4772            HashMap<String, Object> map = new HashMap<String, Object>();
4773            msg.what = SHOW_NOT_RESPONDING_MSG;
4774            msg.obj = map;
4775            msg.arg1 = aboveSystem ? 1 : 0;
4776            map.put("app", app);
4777            if (activity != null) {
4778                map.put("activity", activity);
4779            }
4780
4781            mHandler.sendMessage(msg);
4782        }
4783    }
4784
4785    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4786        if (!mLaunchWarningShown) {
4787            mLaunchWarningShown = true;
4788            mHandler.post(new Runnable() {
4789                @Override
4790                public void run() {
4791                    synchronized (ActivityManagerService.this) {
4792                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4793                        d.show();
4794                        mHandler.postDelayed(new Runnable() {
4795                            @Override
4796                            public void run() {
4797                                synchronized (ActivityManagerService.this) {
4798                                    d.dismiss();
4799                                    mLaunchWarningShown = false;
4800                                }
4801                            }
4802                        }, 4000);
4803                    }
4804                }
4805            });
4806        }
4807    }
4808
4809    @Override
4810    public boolean clearApplicationUserData(final String packageName,
4811            final IPackageDataObserver observer, int userId) {
4812        enforceNotIsolatedCaller("clearApplicationUserData");
4813        int uid = Binder.getCallingUid();
4814        int pid = Binder.getCallingPid();
4815        userId = handleIncomingUser(pid, uid,
4816                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4817        long callingId = Binder.clearCallingIdentity();
4818        try {
4819            IPackageManager pm = AppGlobals.getPackageManager();
4820            int pkgUid = -1;
4821            synchronized(this) {
4822                try {
4823                    pkgUid = pm.getPackageUid(packageName, userId);
4824                } catch (RemoteException e) {
4825                }
4826                if (pkgUid == -1) {
4827                    Slog.w(TAG, "Invalid packageName: " + packageName);
4828                    if (observer != null) {
4829                        try {
4830                            observer.onRemoveCompleted(packageName, false);
4831                        } catch (RemoteException e) {
4832                            Slog.i(TAG, "Observer no longer exists.");
4833                        }
4834                    }
4835                    return false;
4836                }
4837                if (uid == pkgUid || checkComponentPermission(
4838                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4839                        pid, uid, -1, true)
4840                        == PackageManager.PERMISSION_GRANTED) {
4841                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4842                } else {
4843                    throw new SecurityException("PID " + pid + " does not have permission "
4844                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4845                                    + " of package " + packageName);
4846                }
4847
4848                // Remove all tasks match the cleared application package and user
4849                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
4850                    final TaskRecord tr = mRecentTasks.get(i);
4851                    final String taskPackageName =
4852                            tr.getBaseIntent().getComponent().getPackageName();
4853                    if (tr.userId != userId) continue;
4854                    if (!taskPackageName.equals(packageName)) continue;
4855                    removeTaskByIdLocked(tr.taskId, false);
4856                }
4857            }
4858
4859            try {
4860                // Clear application user data
4861                pm.clearApplicationUserData(packageName, observer, userId);
4862
4863                synchronized(this) {
4864                    // Remove all permissions granted from/to this package
4865                    removeUriPermissionsForPackageLocked(packageName, userId, true);
4866                }
4867
4868                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4869                        Uri.fromParts("package", packageName, null));
4870                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4871                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4872                        null, null, 0, null, null, null, false, false, userId);
4873            } catch (RemoteException e) {
4874            }
4875        } finally {
4876            Binder.restoreCallingIdentity(callingId);
4877        }
4878        return true;
4879    }
4880
4881    @Override
4882    public void killBackgroundProcesses(final String packageName, int userId) {
4883        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4884                != PackageManager.PERMISSION_GRANTED &&
4885                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4886                        != PackageManager.PERMISSION_GRANTED) {
4887            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4888                    + Binder.getCallingPid()
4889                    + ", uid=" + Binder.getCallingUid()
4890                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4891            Slog.w(TAG, msg);
4892            throw new SecurityException(msg);
4893        }
4894
4895        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4896                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4897        long callingId = Binder.clearCallingIdentity();
4898        try {
4899            IPackageManager pm = AppGlobals.getPackageManager();
4900            synchronized(this) {
4901                int appId = -1;
4902                try {
4903                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4904                } catch (RemoteException e) {
4905                }
4906                if (appId == -1) {
4907                    Slog.w(TAG, "Invalid packageName: " + packageName);
4908                    return;
4909                }
4910                killPackageProcessesLocked(packageName, appId, userId,
4911                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4912            }
4913        } finally {
4914            Binder.restoreCallingIdentity(callingId);
4915        }
4916    }
4917
4918    @Override
4919    public void killAllBackgroundProcesses() {
4920        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4921                != PackageManager.PERMISSION_GRANTED) {
4922            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4923                    + Binder.getCallingPid()
4924                    + ", uid=" + Binder.getCallingUid()
4925                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4926            Slog.w(TAG, msg);
4927            throw new SecurityException(msg);
4928        }
4929
4930        long callingId = Binder.clearCallingIdentity();
4931        try {
4932            synchronized(this) {
4933                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4934                final int NP = mProcessNames.getMap().size();
4935                for (int ip=0; ip<NP; ip++) {
4936                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4937                    final int NA = apps.size();
4938                    for (int ia=0; ia<NA; ia++) {
4939                        ProcessRecord app = apps.valueAt(ia);
4940                        if (app.persistent) {
4941                            // we don't kill persistent processes
4942                            continue;
4943                        }
4944                        if (app.removed) {
4945                            procs.add(app);
4946                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4947                            app.removed = true;
4948                            procs.add(app);
4949                        }
4950                    }
4951                }
4952
4953                int N = procs.size();
4954                for (int i=0; i<N; i++) {
4955                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4956                }
4957                mAllowLowerMemLevel = true;
4958                updateOomAdjLocked();
4959                doLowMemReportIfNeededLocked(null);
4960            }
4961        } finally {
4962            Binder.restoreCallingIdentity(callingId);
4963        }
4964    }
4965
4966    @Override
4967    public void forceStopPackage(final String packageName, int userId) {
4968        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4969                != PackageManager.PERMISSION_GRANTED) {
4970            String msg = "Permission Denial: forceStopPackage() from pid="
4971                    + Binder.getCallingPid()
4972                    + ", uid=" + Binder.getCallingUid()
4973                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4974            Slog.w(TAG, msg);
4975            throw new SecurityException(msg);
4976        }
4977        final int callingPid = Binder.getCallingPid();
4978        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4979                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4980        long callingId = Binder.clearCallingIdentity();
4981        try {
4982            IPackageManager pm = AppGlobals.getPackageManager();
4983            synchronized(this) {
4984                int[] users = userId == UserHandle.USER_ALL
4985                        ? getUsersLocked() : new int[] { userId };
4986                for (int user : users) {
4987                    int pkgUid = -1;
4988                    try {
4989                        pkgUid = pm.getPackageUid(packageName, user);
4990                    } catch (RemoteException e) {
4991                    }
4992                    if (pkgUid == -1) {
4993                        Slog.w(TAG, "Invalid packageName: " + packageName);
4994                        continue;
4995                    }
4996                    try {
4997                        pm.setPackageStoppedState(packageName, true, user);
4998                    } catch (RemoteException e) {
4999                    } catch (IllegalArgumentException e) {
5000                        Slog.w(TAG, "Failed trying to unstop package "
5001                                + packageName + ": " + e);
5002                    }
5003                    if (isUserRunningLocked(user, false)) {
5004                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5005                    }
5006                }
5007            }
5008        } finally {
5009            Binder.restoreCallingIdentity(callingId);
5010        }
5011    }
5012
5013    @Override
5014    public void addPackageDependency(String packageName) {
5015        synchronized (this) {
5016            int callingPid = Binder.getCallingPid();
5017            if (callingPid == Process.myPid()) {
5018                //  Yeah, um, no.
5019                return;
5020            }
5021            ProcessRecord proc;
5022            synchronized (mPidsSelfLocked) {
5023                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5024            }
5025            if (proc != null) {
5026                if (proc.pkgDeps == null) {
5027                    proc.pkgDeps = new ArraySet<String>(1);
5028                }
5029                proc.pkgDeps.add(packageName);
5030            }
5031        }
5032    }
5033
5034    /*
5035     * The pkg name and app id have to be specified.
5036     */
5037    @Override
5038    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5039        if (pkg == null) {
5040            return;
5041        }
5042        // Make sure the uid is valid.
5043        if (appid < 0) {
5044            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5045            return;
5046        }
5047        int callerUid = Binder.getCallingUid();
5048        // Only the system server can kill an application
5049        if (callerUid == Process.SYSTEM_UID) {
5050            // Post an aysnc message to kill the application
5051            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5052            msg.arg1 = appid;
5053            msg.arg2 = 0;
5054            Bundle bundle = new Bundle();
5055            bundle.putString("pkg", pkg);
5056            bundle.putString("reason", reason);
5057            msg.obj = bundle;
5058            mHandler.sendMessage(msg);
5059        } else {
5060            throw new SecurityException(callerUid + " cannot kill pkg: " +
5061                    pkg);
5062        }
5063    }
5064
5065    @Override
5066    public void closeSystemDialogs(String reason) {
5067        enforceNotIsolatedCaller("closeSystemDialogs");
5068
5069        final int pid = Binder.getCallingPid();
5070        final int uid = Binder.getCallingUid();
5071        final long origId = Binder.clearCallingIdentity();
5072        try {
5073            synchronized (this) {
5074                // Only allow this from foreground processes, so that background
5075                // applications can't abuse it to prevent system UI from being shown.
5076                if (uid >= Process.FIRST_APPLICATION_UID) {
5077                    ProcessRecord proc;
5078                    synchronized (mPidsSelfLocked) {
5079                        proc = mPidsSelfLocked.get(pid);
5080                    }
5081                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5082                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5083                                + " from background process " + proc);
5084                        return;
5085                    }
5086                }
5087                closeSystemDialogsLocked(reason);
5088            }
5089        } finally {
5090            Binder.restoreCallingIdentity(origId);
5091        }
5092    }
5093
5094    void closeSystemDialogsLocked(String reason) {
5095        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5096        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5097                | Intent.FLAG_RECEIVER_FOREGROUND);
5098        if (reason != null) {
5099            intent.putExtra("reason", reason);
5100        }
5101        mWindowManager.closeSystemDialogs(reason);
5102
5103        mStackSupervisor.closeSystemDialogsLocked();
5104
5105        broadcastIntentLocked(null, null, intent, null,
5106                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5107                Process.SYSTEM_UID, UserHandle.USER_ALL);
5108    }
5109
5110    @Override
5111    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5112        enforceNotIsolatedCaller("getProcessMemoryInfo");
5113        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5114        for (int i=pids.length-1; i>=0; i--) {
5115            ProcessRecord proc;
5116            int oomAdj;
5117            synchronized (this) {
5118                synchronized (mPidsSelfLocked) {
5119                    proc = mPidsSelfLocked.get(pids[i]);
5120                    oomAdj = proc != null ? proc.setAdj : 0;
5121                }
5122            }
5123            infos[i] = new Debug.MemoryInfo();
5124            Debug.getMemoryInfo(pids[i], infos[i]);
5125            if (proc != null) {
5126                synchronized (this) {
5127                    if (proc.thread != null && proc.setAdj == oomAdj) {
5128                        // Record this for posterity if the process has been stable.
5129                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5130                                infos[i].getTotalUss(), false, proc.pkgList);
5131                    }
5132                }
5133            }
5134        }
5135        return infos;
5136    }
5137
5138    @Override
5139    public long[] getProcessPss(int[] pids) {
5140        enforceNotIsolatedCaller("getProcessPss");
5141        long[] pss = new long[pids.length];
5142        for (int i=pids.length-1; i>=0; i--) {
5143            ProcessRecord proc;
5144            int oomAdj;
5145            synchronized (this) {
5146                synchronized (mPidsSelfLocked) {
5147                    proc = mPidsSelfLocked.get(pids[i]);
5148                    oomAdj = proc != null ? proc.setAdj : 0;
5149                }
5150            }
5151            long[] tmpUss = new long[1];
5152            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5153            if (proc != null) {
5154                synchronized (this) {
5155                    if (proc.thread != null && proc.setAdj == oomAdj) {
5156                        // Record this for posterity if the process has been stable.
5157                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5158                    }
5159                }
5160            }
5161        }
5162        return pss;
5163    }
5164
5165    @Override
5166    public void killApplicationProcess(String processName, int uid) {
5167        if (processName == null) {
5168            return;
5169        }
5170
5171        int callerUid = Binder.getCallingUid();
5172        // Only the system server can kill an application
5173        if (callerUid == Process.SYSTEM_UID) {
5174            synchronized (this) {
5175                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5176                if (app != null && app.thread != null) {
5177                    try {
5178                        app.thread.scheduleSuicide();
5179                    } catch (RemoteException e) {
5180                        // If the other end already died, then our work here is done.
5181                    }
5182                } else {
5183                    Slog.w(TAG, "Process/uid not found attempting kill of "
5184                            + processName + " / " + uid);
5185                }
5186            }
5187        } else {
5188            throw new SecurityException(callerUid + " cannot kill app process: " +
5189                    processName);
5190        }
5191    }
5192
5193    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5194        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5195                false, true, false, false, UserHandle.getUserId(uid), reason);
5196        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5197                Uri.fromParts("package", packageName, null));
5198        if (!mProcessesReady) {
5199            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5200                    | Intent.FLAG_RECEIVER_FOREGROUND);
5201        }
5202        intent.putExtra(Intent.EXTRA_UID, uid);
5203        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5204        broadcastIntentLocked(null, null, intent,
5205                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5206                false, false,
5207                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5208    }
5209
5210    private void forceStopUserLocked(int userId, String reason) {
5211        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5212        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5213        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5214                | Intent.FLAG_RECEIVER_FOREGROUND);
5215        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5216        broadcastIntentLocked(null, null, intent,
5217                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5218                false, false,
5219                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5220    }
5221
5222    private final boolean killPackageProcessesLocked(String packageName, int appId,
5223            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5224            boolean doit, boolean evenPersistent, String reason) {
5225        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5226
5227        // Remove all processes this package may have touched: all with the
5228        // same UID (except for the system or root user), and all whose name
5229        // matches the package name.
5230        final int NP = mProcessNames.getMap().size();
5231        for (int ip=0; ip<NP; ip++) {
5232            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5233            final int NA = apps.size();
5234            for (int ia=0; ia<NA; ia++) {
5235                ProcessRecord app = apps.valueAt(ia);
5236                if (app.persistent && !evenPersistent) {
5237                    // we don't kill persistent processes
5238                    continue;
5239                }
5240                if (app.removed) {
5241                    if (doit) {
5242                        procs.add(app);
5243                    }
5244                    continue;
5245                }
5246
5247                // Skip process if it doesn't meet our oom adj requirement.
5248                if (app.setAdj < minOomAdj) {
5249                    continue;
5250                }
5251
5252                // If no package is specified, we call all processes under the
5253                // give user id.
5254                if (packageName == null) {
5255                    if (app.userId != userId) {
5256                        continue;
5257                    }
5258                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5259                        continue;
5260                    }
5261                // Package has been specified, we want to hit all processes
5262                // that match it.  We need to qualify this by the processes
5263                // that are running under the specified app and user ID.
5264                } else {
5265                    final boolean isDep = app.pkgDeps != null
5266                            && app.pkgDeps.contains(packageName);
5267                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5268                        continue;
5269                    }
5270                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5271                        continue;
5272                    }
5273                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5274                        continue;
5275                    }
5276                }
5277
5278                // Process has passed all conditions, kill it!
5279                if (!doit) {
5280                    return true;
5281                }
5282                app.removed = true;
5283                procs.add(app);
5284            }
5285        }
5286
5287        int N = procs.size();
5288        for (int i=0; i<N; i++) {
5289            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5290        }
5291        updateOomAdjLocked();
5292        return N > 0;
5293    }
5294
5295    private final boolean forceStopPackageLocked(String name, int appId,
5296            boolean callerWillRestart, boolean purgeCache, boolean doit,
5297            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5298        int i;
5299        int N;
5300
5301        if (userId == UserHandle.USER_ALL && name == null) {
5302            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5303        }
5304
5305        if (appId < 0 && name != null) {
5306            try {
5307                appId = UserHandle.getAppId(
5308                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5309            } catch (RemoteException e) {
5310            }
5311        }
5312
5313        if (doit) {
5314            if (name != null) {
5315                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5316                        + " user=" + userId + ": " + reason);
5317            } else {
5318                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5319            }
5320
5321            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5322            for (int ip=pmap.size()-1; ip>=0; ip--) {
5323                SparseArray<Long> ba = pmap.valueAt(ip);
5324                for (i=ba.size()-1; i>=0; i--) {
5325                    boolean remove = false;
5326                    final int entUid = ba.keyAt(i);
5327                    if (name != null) {
5328                        if (userId == UserHandle.USER_ALL) {
5329                            if (UserHandle.getAppId(entUid) == appId) {
5330                                remove = true;
5331                            }
5332                        } else {
5333                            if (entUid == UserHandle.getUid(userId, appId)) {
5334                                remove = true;
5335                            }
5336                        }
5337                    } else if (UserHandle.getUserId(entUid) == userId) {
5338                        remove = true;
5339                    }
5340                    if (remove) {
5341                        ba.removeAt(i);
5342                    }
5343                }
5344                if (ba.size() == 0) {
5345                    pmap.removeAt(ip);
5346                }
5347            }
5348        }
5349
5350        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5351                -100, callerWillRestart, true, doit, evenPersistent,
5352                name == null ? ("stop user " + userId) : ("stop " + name));
5353
5354        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5355            if (!doit) {
5356                return true;
5357            }
5358            didSomething = true;
5359        }
5360
5361        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5362            if (!doit) {
5363                return true;
5364            }
5365            didSomething = true;
5366        }
5367
5368        if (name == null) {
5369            // Remove all sticky broadcasts from this user.
5370            mStickyBroadcasts.remove(userId);
5371        }
5372
5373        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5374        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5375                userId, providers)) {
5376            if (!doit) {
5377                return true;
5378            }
5379            didSomething = true;
5380        }
5381        N = providers.size();
5382        for (i=0; i<N; i++) {
5383            removeDyingProviderLocked(null, providers.get(i), true);
5384        }
5385
5386        // Remove transient permissions granted from/to this package/user
5387        removeUriPermissionsForPackageLocked(name, userId, false);
5388
5389        if (name == null || uninstalling) {
5390            // Remove pending intents.  For now we only do this when force
5391            // stopping users, because we have some problems when doing this
5392            // for packages -- app widgets are not currently cleaned up for
5393            // such packages, so they can be left with bad pending intents.
5394            if (mIntentSenderRecords.size() > 0) {
5395                Iterator<WeakReference<PendingIntentRecord>> it
5396                        = mIntentSenderRecords.values().iterator();
5397                while (it.hasNext()) {
5398                    WeakReference<PendingIntentRecord> wpir = it.next();
5399                    if (wpir == null) {
5400                        it.remove();
5401                        continue;
5402                    }
5403                    PendingIntentRecord pir = wpir.get();
5404                    if (pir == null) {
5405                        it.remove();
5406                        continue;
5407                    }
5408                    if (name == null) {
5409                        // Stopping user, remove all objects for the user.
5410                        if (pir.key.userId != userId) {
5411                            // Not the same user, skip it.
5412                            continue;
5413                        }
5414                    } else {
5415                        if (UserHandle.getAppId(pir.uid) != appId) {
5416                            // Different app id, skip it.
5417                            continue;
5418                        }
5419                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5420                            // Different user, skip it.
5421                            continue;
5422                        }
5423                        if (!pir.key.packageName.equals(name)) {
5424                            // Different package, skip it.
5425                            continue;
5426                        }
5427                    }
5428                    if (!doit) {
5429                        return true;
5430                    }
5431                    didSomething = true;
5432                    it.remove();
5433                    pir.canceled = true;
5434                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5435                        pir.key.activity.pendingResults.remove(pir.ref);
5436                    }
5437                }
5438            }
5439        }
5440
5441        if (doit) {
5442            if (purgeCache && name != null) {
5443                AttributeCache ac = AttributeCache.instance();
5444                if (ac != null) {
5445                    ac.removePackage(name);
5446                }
5447            }
5448            if (mBooted) {
5449                mStackSupervisor.resumeTopActivitiesLocked();
5450                mStackSupervisor.scheduleIdleLocked();
5451            }
5452        }
5453
5454        return didSomething;
5455    }
5456
5457    private final boolean removeProcessLocked(ProcessRecord app,
5458            boolean callerWillRestart, boolean allowRestart, String reason) {
5459        final String name = app.processName;
5460        final int uid = app.uid;
5461        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
5462            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
5463
5464        mProcessNames.remove(name, uid);
5465        mIsolatedProcesses.remove(app.uid);
5466        if (mHeavyWeightProcess == app) {
5467            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5468                    mHeavyWeightProcess.userId, 0));
5469            mHeavyWeightProcess = null;
5470        }
5471        boolean needRestart = false;
5472        if (app.pid > 0 && app.pid != MY_PID) {
5473            int pid = app.pid;
5474            synchronized (mPidsSelfLocked) {
5475                mPidsSelfLocked.remove(pid);
5476                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5477            }
5478            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5479            if (app.isolated) {
5480                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5481            }
5482            app.kill(reason, true);
5483            handleAppDiedLocked(app, true, allowRestart);
5484            removeLruProcessLocked(app);
5485
5486            if (app.persistent && !app.isolated) {
5487                if (!callerWillRestart) {
5488                    addAppLocked(app.info, false, null /* ABI override */);
5489                } else {
5490                    needRestart = true;
5491                }
5492            }
5493        } else {
5494            mRemovedProcesses.add(app);
5495        }
5496
5497        return needRestart;
5498    }
5499
5500    private final void processStartTimedOutLocked(ProcessRecord app) {
5501        final int pid = app.pid;
5502        boolean gone = false;
5503        synchronized (mPidsSelfLocked) {
5504            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5505            if (knownApp != null && knownApp.thread == null) {
5506                mPidsSelfLocked.remove(pid);
5507                gone = true;
5508            }
5509        }
5510
5511        if (gone) {
5512            Slog.w(TAG, "Process " + app + " failed to attach");
5513            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5514                    pid, app.uid, app.processName);
5515            mProcessNames.remove(app.processName, app.uid);
5516            mIsolatedProcesses.remove(app.uid);
5517            if (mHeavyWeightProcess == app) {
5518                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5519                        mHeavyWeightProcess.userId, 0));
5520                mHeavyWeightProcess = null;
5521            }
5522            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5523            if (app.isolated) {
5524                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5525            }
5526            // Take care of any launching providers waiting for this process.
5527            checkAppInLaunchingProvidersLocked(app, true);
5528            // Take care of any services that are waiting for the process.
5529            mServices.processStartTimedOutLocked(app);
5530            app.kill("start timeout", true);
5531            removeLruProcessLocked(app);
5532            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5533                Slog.w(TAG, "Unattached app died before backup, skipping");
5534                try {
5535                    IBackupManager bm = IBackupManager.Stub.asInterface(
5536                            ServiceManager.getService(Context.BACKUP_SERVICE));
5537                    bm.agentDisconnected(app.info.packageName);
5538                } catch (RemoteException e) {
5539                    // Can't happen; the backup manager is local
5540                }
5541            }
5542            if (isPendingBroadcastProcessLocked(pid)) {
5543                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5544                skipPendingBroadcastLocked(pid);
5545            }
5546        } else {
5547            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5548        }
5549    }
5550
5551    private final boolean attachApplicationLocked(IApplicationThread thread,
5552            int pid) {
5553
5554        // Find the application record that is being attached...  either via
5555        // the pid if we are running in multiple processes, or just pull the
5556        // next app record if we are emulating process with anonymous threads.
5557        ProcessRecord app;
5558        if (pid != MY_PID && pid >= 0) {
5559            synchronized (mPidsSelfLocked) {
5560                app = mPidsSelfLocked.get(pid);
5561            }
5562        } else {
5563            app = null;
5564        }
5565
5566        if (app == null) {
5567            Slog.w(TAG, "No pending application record for pid " + pid
5568                    + " (IApplicationThread " + thread + "); dropping process");
5569            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5570            if (pid > 0 && pid != MY_PID) {
5571                Process.killProcessQuiet(pid);
5572                //TODO: Process.killProcessGroup(app.info.uid, pid);
5573            } else {
5574                try {
5575                    thread.scheduleExit();
5576                } catch (Exception e) {
5577                    // Ignore exceptions.
5578                }
5579            }
5580            return false;
5581        }
5582
5583        // If this application record is still attached to a previous
5584        // process, clean it up now.
5585        if (app.thread != null) {
5586            handleAppDiedLocked(app, true, true);
5587        }
5588
5589        // Tell the process all about itself.
5590
5591        if (DEBUG_ALL) Slog.v(
5592                TAG, "Binding process pid " + pid + " to record " + app);
5593
5594        final String processName = app.processName;
5595        try {
5596            AppDeathRecipient adr = new AppDeathRecipient(
5597                    app, pid, thread);
5598            thread.asBinder().linkToDeath(adr, 0);
5599            app.deathRecipient = adr;
5600        } catch (RemoteException e) {
5601            app.resetPackageList(mProcessStats);
5602            startProcessLocked(app, "link fail", processName);
5603            return false;
5604        }
5605
5606        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5607
5608        app.makeActive(thread, mProcessStats);
5609        app.curAdj = app.setAdj = -100;
5610        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5611        app.forcingToForeground = null;
5612        updateProcessForegroundLocked(app, false, false);
5613        app.hasShownUi = false;
5614        app.debugging = false;
5615        app.cached = false;
5616        app.killedByAm = false;
5617
5618        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5619
5620        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5621        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5622
5623        if (!normalMode) {
5624            Slog.i(TAG, "Launching preboot mode app: " + app);
5625        }
5626
5627        if (DEBUG_ALL) Slog.v(
5628            TAG, "New app record " + app
5629            + " thread=" + thread.asBinder() + " pid=" + pid);
5630        try {
5631            int testMode = IApplicationThread.DEBUG_OFF;
5632            if (mDebugApp != null && mDebugApp.equals(processName)) {
5633                testMode = mWaitForDebugger
5634                    ? IApplicationThread.DEBUG_WAIT
5635                    : IApplicationThread.DEBUG_ON;
5636                app.debugging = true;
5637                if (mDebugTransient) {
5638                    mDebugApp = mOrigDebugApp;
5639                    mWaitForDebugger = mOrigWaitForDebugger;
5640                }
5641            }
5642            String profileFile = app.instrumentationProfileFile;
5643            ParcelFileDescriptor profileFd = null;
5644            int samplingInterval = 0;
5645            boolean profileAutoStop = false;
5646            if (mProfileApp != null && mProfileApp.equals(processName)) {
5647                mProfileProc = app;
5648                profileFile = mProfileFile;
5649                profileFd = mProfileFd;
5650                samplingInterval = mSamplingInterval;
5651                profileAutoStop = mAutoStopProfiler;
5652            }
5653            boolean enableOpenGlTrace = false;
5654            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5655                enableOpenGlTrace = true;
5656                mOpenGlTraceApp = null;
5657            }
5658
5659            // If the app is being launched for restore or full backup, set it up specially
5660            boolean isRestrictedBackupMode = false;
5661            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5662                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5663                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5664                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5665            }
5666
5667            ensurePackageDexOpt(app.instrumentationInfo != null
5668                    ? app.instrumentationInfo.packageName
5669                    : app.info.packageName);
5670            if (app.instrumentationClass != null) {
5671                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5672            }
5673            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
5674                    + processName + " with config " + mConfiguration);
5675            ApplicationInfo appInfo = app.instrumentationInfo != null
5676                    ? app.instrumentationInfo : app.info;
5677            app.compat = compatibilityInfoForPackageLocked(appInfo);
5678            if (profileFd != null) {
5679                profileFd = profileFd.dup();
5680            }
5681            ProfilerInfo profilerInfo = profileFile == null ? null
5682                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5683            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5684                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5685                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5686                    isRestrictedBackupMode || !normalMode, app.persistent,
5687                    new Configuration(mConfiguration), app.compat,
5688                    getCommonServicesLocked(app.isolated),
5689                    mCoreSettingsObserver.getCoreSettingsLocked());
5690            updateLruProcessLocked(app, false, null);
5691            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5692        } catch (Exception e) {
5693            // todo: Yikes!  What should we do?  For now we will try to
5694            // start another process, but that could easily get us in
5695            // an infinite loop of restarting processes...
5696            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
5697
5698            app.resetPackageList(mProcessStats);
5699            app.unlinkDeathRecipient();
5700            startProcessLocked(app, "bind fail", processName);
5701            return false;
5702        }
5703
5704        // Remove this record from the list of starting applications.
5705        mPersistentStartingProcesses.remove(app);
5706        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
5707                "Attach application locked removing on hold: " + app);
5708        mProcessesOnHold.remove(app);
5709
5710        boolean badApp = false;
5711        boolean didSomething = false;
5712
5713        // See if the top visible activity is waiting to run in this process...
5714        if (normalMode) {
5715            try {
5716                if (mStackSupervisor.attachApplicationLocked(app)) {
5717                    didSomething = true;
5718                }
5719            } catch (Exception e) {
5720                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
5721                badApp = true;
5722            }
5723        }
5724
5725        // Find any services that should be running in this process...
5726        if (!badApp) {
5727            try {
5728                didSomething |= mServices.attachApplicationLocked(app, processName);
5729            } catch (Exception e) {
5730                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
5731                badApp = true;
5732            }
5733        }
5734
5735        // Check if a next-broadcast receiver is in this process...
5736        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5737            try {
5738                didSomething |= sendPendingBroadcastsLocked(app);
5739            } catch (Exception e) {
5740                // If the app died trying to launch the receiver we declare it 'bad'
5741                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
5742                badApp = true;
5743            }
5744        }
5745
5746        // Check whether the next backup agent is in this process...
5747        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5748            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
5749                    "New app is backup target, launching agent for " + app);
5750            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5751            try {
5752                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5753                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5754                        mBackupTarget.backupMode);
5755            } catch (Exception e) {
5756                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
5757                badApp = true;
5758            }
5759        }
5760
5761        if (badApp) {
5762            app.kill("error during init", true);
5763            handleAppDiedLocked(app, false, true);
5764            return false;
5765        }
5766
5767        if (!didSomething) {
5768            updateOomAdjLocked();
5769        }
5770
5771        return true;
5772    }
5773
5774    @Override
5775    public final void attachApplication(IApplicationThread thread) {
5776        synchronized (this) {
5777            int callingPid = Binder.getCallingPid();
5778            final long origId = Binder.clearCallingIdentity();
5779            attachApplicationLocked(thread, callingPid);
5780            Binder.restoreCallingIdentity(origId);
5781        }
5782    }
5783
5784    @Override
5785    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5786        final long origId = Binder.clearCallingIdentity();
5787        synchronized (this) {
5788            ActivityStack stack = ActivityRecord.getStackLocked(token);
5789            if (stack != null) {
5790                ActivityRecord r =
5791                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5792                if (stopProfiling) {
5793                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5794                        try {
5795                            mProfileFd.close();
5796                        } catch (IOException e) {
5797                        }
5798                        clearProfilerLocked();
5799                    }
5800                }
5801            }
5802        }
5803        Binder.restoreCallingIdentity(origId);
5804    }
5805
5806    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
5807        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
5808                finishBooting? 1 : 0, enableScreen ? 1 : 0));
5809    }
5810
5811    void enableScreenAfterBoot() {
5812        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5813                SystemClock.uptimeMillis());
5814        mWindowManager.enableScreenAfterBoot();
5815
5816        synchronized (this) {
5817            updateEventDispatchingLocked();
5818        }
5819    }
5820
5821    @Override
5822    public void showBootMessage(final CharSequence msg, final boolean always) {
5823        if (Binder.getCallingUid() != Process.myUid()) {
5824            // These days only the core system can call this, so apps can't get in
5825            // the way of what we show about running them.
5826        }
5827        mWindowManager.showBootMessage(msg, always);
5828    }
5829
5830    @Override
5831    public void keyguardWaitingForActivityDrawn() {
5832        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
5833        final long token = Binder.clearCallingIdentity();
5834        try {
5835            synchronized (this) {
5836                if (DEBUG_LOCKSCREEN) logLockScreen("");
5837                mWindowManager.keyguardWaitingForActivityDrawn();
5838                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
5839                    mLockScreenShown = LOCK_SCREEN_LEAVING;
5840                    updateSleepIfNeededLocked();
5841                }
5842            }
5843        } finally {
5844            Binder.restoreCallingIdentity(token);
5845        }
5846    }
5847
5848    final void finishBooting() {
5849        synchronized (this) {
5850            if (!mBootAnimationComplete) {
5851                mCallFinishBooting = true;
5852                return;
5853            }
5854            mCallFinishBooting = false;
5855        }
5856
5857        ArraySet<String> completedIsas = new ArraySet<String>();
5858        for (String abi : Build.SUPPORTED_ABIS) {
5859            Process.establishZygoteConnectionForAbi(abi);
5860            final String instructionSet = VMRuntime.getInstructionSet(abi);
5861            if (!completedIsas.contains(instructionSet)) {
5862                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
5863                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
5864                }
5865                completedIsas.add(instructionSet);
5866            }
5867        }
5868
5869        IntentFilter pkgFilter = new IntentFilter();
5870        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
5871        pkgFilter.addDataScheme("package");
5872        mContext.registerReceiver(new BroadcastReceiver() {
5873            @Override
5874            public void onReceive(Context context, Intent intent) {
5875                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
5876                if (pkgs != null) {
5877                    for (String pkg : pkgs) {
5878                        synchronized (ActivityManagerService.this) {
5879                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
5880                                    0, "query restart")) {
5881                                setResultCode(Activity.RESULT_OK);
5882                                return;
5883                            }
5884                        }
5885                    }
5886                }
5887            }
5888        }, pkgFilter);
5889
5890        IntentFilter dumpheapFilter = new IntentFilter();
5891        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
5892        mContext.registerReceiver(new BroadcastReceiver() {
5893            @Override
5894            public void onReceive(Context context, Intent intent) {
5895                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
5896                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
5897                } else {
5898                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
5899                }
5900            }
5901        }, dumpheapFilter);
5902
5903        // Let system services know.
5904        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
5905
5906        synchronized (this) {
5907            // Ensure that any processes we had put on hold are now started
5908            // up.
5909            final int NP = mProcessesOnHold.size();
5910            if (NP > 0) {
5911                ArrayList<ProcessRecord> procs =
5912                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5913                for (int ip=0; ip<NP; ip++) {
5914                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
5915                            + procs.get(ip));
5916                    startProcessLocked(procs.get(ip), "on-hold", null);
5917                }
5918            }
5919
5920            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5921                // Start looking for apps that are abusing wake locks.
5922                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5923                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5924                // Tell anyone interested that we are done booting!
5925                SystemProperties.set("sys.boot_completed", "1");
5926
5927                // And trigger dev.bootcomplete if we are not showing encryption progress
5928                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
5929                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
5930                    SystemProperties.set("dev.bootcomplete", "1");
5931                }
5932                for (int i=0; i<mStartedUsers.size(); i++) {
5933                    UserStartedState uss = mStartedUsers.valueAt(i);
5934                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5935                        uss.mState = UserStartedState.STATE_RUNNING;
5936                        final int userId = mStartedUsers.keyAt(i);
5937                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5938                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5939                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5940                        broadcastIntentLocked(null, null, intent, null,
5941                                new IIntentReceiver.Stub() {
5942                                    @Override
5943                                    public void performReceive(Intent intent, int resultCode,
5944                                            String data, Bundle extras, boolean ordered,
5945                                            boolean sticky, int sendingUser) {
5946                                        synchronized (ActivityManagerService.this) {
5947                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5948                                                    true, false);
5949                                        }
5950                                    }
5951                                },
5952                                0, null, null,
5953                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5954                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5955                                userId);
5956                    }
5957                }
5958                scheduleStartProfilesLocked();
5959            }
5960        }
5961    }
5962
5963    @Override
5964    public void bootAnimationComplete() {
5965        final boolean callFinishBooting;
5966        synchronized (this) {
5967            callFinishBooting = mCallFinishBooting;
5968            mBootAnimationComplete = true;
5969        }
5970        if (callFinishBooting) {
5971            finishBooting();
5972        }
5973    }
5974
5975    @Override
5976    public void systemBackupRestored() {
5977        synchronized (this) {
5978            if (mSystemReady) {
5979                mTaskPersister.restoreTasksFromOtherDeviceLocked();
5980            } else {
5981                Slog.w(TAG, "System backup restored before system is ready");
5982            }
5983        }
5984    }
5985
5986    final void ensureBootCompleted() {
5987        boolean booting;
5988        boolean enableScreen;
5989        synchronized (this) {
5990            booting = mBooting;
5991            mBooting = false;
5992            enableScreen = !mBooted;
5993            mBooted = true;
5994        }
5995
5996        if (booting) {
5997            finishBooting();
5998        }
5999
6000        if (enableScreen) {
6001            enableScreenAfterBoot();
6002        }
6003    }
6004
6005    @Override
6006    public final void activityResumed(IBinder token) {
6007        final long origId = Binder.clearCallingIdentity();
6008        synchronized(this) {
6009            ActivityStack stack = ActivityRecord.getStackLocked(token);
6010            if (stack != null) {
6011                ActivityRecord.activityResumedLocked(token);
6012            }
6013        }
6014        Binder.restoreCallingIdentity(origId);
6015    }
6016
6017    @Override
6018    public final void activityPaused(IBinder token) {
6019        final long origId = Binder.clearCallingIdentity();
6020        synchronized(this) {
6021            ActivityStack stack = ActivityRecord.getStackLocked(token);
6022            if (stack != null) {
6023                stack.activityPausedLocked(token, false);
6024            }
6025        }
6026        Binder.restoreCallingIdentity(origId);
6027    }
6028
6029    @Override
6030    public final void activityStopped(IBinder token, Bundle icicle,
6031            PersistableBundle persistentState, CharSequence description) {
6032        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6033
6034        // Refuse possible leaked file descriptors
6035        if (icicle != null && icicle.hasFileDescriptors()) {
6036            throw new IllegalArgumentException("File descriptors passed in Bundle");
6037        }
6038
6039        final long origId = Binder.clearCallingIdentity();
6040
6041        synchronized (this) {
6042            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6043            if (r != null) {
6044                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6045            }
6046        }
6047
6048        trimApplications();
6049
6050        Binder.restoreCallingIdentity(origId);
6051    }
6052
6053    @Override
6054    public final void activityDestroyed(IBinder token) {
6055        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6056        synchronized (this) {
6057            ActivityStack stack = ActivityRecord.getStackLocked(token);
6058            if (stack != null) {
6059                stack.activityDestroyedLocked(token, "activityDestroyed");
6060            }
6061        }
6062    }
6063
6064    @Override
6065    public final void backgroundResourcesReleased(IBinder token) {
6066        final long origId = Binder.clearCallingIdentity();
6067        try {
6068            synchronized (this) {
6069                ActivityStack stack = ActivityRecord.getStackLocked(token);
6070                if (stack != null) {
6071                    stack.backgroundResourcesReleased();
6072                }
6073            }
6074        } finally {
6075            Binder.restoreCallingIdentity(origId);
6076        }
6077    }
6078
6079    @Override
6080    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6081        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6082    }
6083
6084    @Override
6085    public final void notifyEnterAnimationComplete(IBinder token) {
6086        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6087    }
6088
6089    @Override
6090    public String getCallingPackage(IBinder token) {
6091        synchronized (this) {
6092            ActivityRecord r = getCallingRecordLocked(token);
6093            return r != null ? r.info.packageName : null;
6094        }
6095    }
6096
6097    @Override
6098    public ComponentName getCallingActivity(IBinder token) {
6099        synchronized (this) {
6100            ActivityRecord r = getCallingRecordLocked(token);
6101            return r != null ? r.intent.getComponent() : null;
6102        }
6103    }
6104
6105    private ActivityRecord getCallingRecordLocked(IBinder token) {
6106        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6107        if (r == null) {
6108            return null;
6109        }
6110        return r.resultTo;
6111    }
6112
6113    @Override
6114    public ComponentName getActivityClassForToken(IBinder token) {
6115        synchronized(this) {
6116            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6117            if (r == null) {
6118                return null;
6119            }
6120            return r.intent.getComponent();
6121        }
6122    }
6123
6124    @Override
6125    public String getPackageForToken(IBinder token) {
6126        synchronized(this) {
6127            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6128            if (r == null) {
6129                return null;
6130            }
6131            return r.packageName;
6132        }
6133    }
6134
6135    @Override
6136    public IIntentSender getIntentSender(int type,
6137            String packageName, IBinder token, String resultWho,
6138            int requestCode, Intent[] intents, String[] resolvedTypes,
6139            int flags, Bundle options, int userId) {
6140        enforceNotIsolatedCaller("getIntentSender");
6141        // Refuse possible leaked file descriptors
6142        if (intents != null) {
6143            if (intents.length < 1) {
6144                throw new IllegalArgumentException("Intents array length must be >= 1");
6145            }
6146            for (int i=0; i<intents.length; i++) {
6147                Intent intent = intents[i];
6148                if (intent != null) {
6149                    if (intent.hasFileDescriptors()) {
6150                        throw new IllegalArgumentException("File descriptors passed in Intent");
6151                    }
6152                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6153                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6154                        throw new IllegalArgumentException(
6155                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6156                    }
6157                    intents[i] = new Intent(intent);
6158                }
6159            }
6160            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6161                throw new IllegalArgumentException(
6162                        "Intent array length does not match resolvedTypes length");
6163            }
6164        }
6165        if (options != null) {
6166            if (options.hasFileDescriptors()) {
6167                throw new IllegalArgumentException("File descriptors passed in options");
6168            }
6169        }
6170
6171        synchronized(this) {
6172            int callingUid = Binder.getCallingUid();
6173            int origUserId = userId;
6174            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6175                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6176                    ALLOW_NON_FULL, "getIntentSender", null);
6177            if (origUserId == UserHandle.USER_CURRENT) {
6178                // We don't want to evaluate this until the pending intent is
6179                // actually executed.  However, we do want to always do the
6180                // security checking for it above.
6181                userId = UserHandle.USER_CURRENT;
6182            }
6183            try {
6184                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6185                    int uid = AppGlobals.getPackageManager()
6186                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6187                    if (!UserHandle.isSameApp(callingUid, uid)) {
6188                        String msg = "Permission Denial: getIntentSender() from pid="
6189                            + Binder.getCallingPid()
6190                            + ", uid=" + Binder.getCallingUid()
6191                            + ", (need uid=" + uid + ")"
6192                            + " is not allowed to send as package " + packageName;
6193                        Slog.w(TAG, msg);
6194                        throw new SecurityException(msg);
6195                    }
6196                }
6197
6198                return getIntentSenderLocked(type, packageName, callingUid, userId,
6199                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6200
6201            } catch (RemoteException e) {
6202                throw new SecurityException(e);
6203            }
6204        }
6205    }
6206
6207    IIntentSender getIntentSenderLocked(int type, String packageName,
6208            int callingUid, int userId, IBinder token, String resultWho,
6209            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6210            Bundle options) {
6211        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6212        ActivityRecord activity = null;
6213        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6214            activity = ActivityRecord.isInStackLocked(token);
6215            if (activity == null) {
6216                return null;
6217            }
6218            if (activity.finishing) {
6219                return null;
6220            }
6221        }
6222
6223        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6224        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6225        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6226        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6227                |PendingIntent.FLAG_UPDATE_CURRENT);
6228
6229        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6230                type, packageName, activity, resultWho,
6231                requestCode, intents, resolvedTypes, flags, options, userId);
6232        WeakReference<PendingIntentRecord> ref;
6233        ref = mIntentSenderRecords.get(key);
6234        PendingIntentRecord rec = ref != null ? ref.get() : null;
6235        if (rec != null) {
6236            if (!cancelCurrent) {
6237                if (updateCurrent) {
6238                    if (rec.key.requestIntent != null) {
6239                        rec.key.requestIntent.replaceExtras(intents != null ?
6240                                intents[intents.length - 1] : null);
6241                    }
6242                    if (intents != null) {
6243                        intents[intents.length-1] = rec.key.requestIntent;
6244                        rec.key.allIntents = intents;
6245                        rec.key.allResolvedTypes = resolvedTypes;
6246                    } else {
6247                        rec.key.allIntents = null;
6248                        rec.key.allResolvedTypes = null;
6249                    }
6250                }
6251                return rec;
6252            }
6253            rec.canceled = true;
6254            mIntentSenderRecords.remove(key);
6255        }
6256        if (noCreate) {
6257            return rec;
6258        }
6259        rec = new PendingIntentRecord(this, key, callingUid);
6260        mIntentSenderRecords.put(key, rec.ref);
6261        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6262            if (activity.pendingResults == null) {
6263                activity.pendingResults
6264                        = new HashSet<WeakReference<PendingIntentRecord>>();
6265            }
6266            activity.pendingResults.add(rec.ref);
6267        }
6268        return rec;
6269    }
6270
6271    @Override
6272    public void cancelIntentSender(IIntentSender sender) {
6273        if (!(sender instanceof PendingIntentRecord)) {
6274            return;
6275        }
6276        synchronized(this) {
6277            PendingIntentRecord rec = (PendingIntentRecord)sender;
6278            try {
6279                int uid = AppGlobals.getPackageManager()
6280                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6281                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6282                    String msg = "Permission Denial: cancelIntentSender() from pid="
6283                        + Binder.getCallingPid()
6284                        + ", uid=" + Binder.getCallingUid()
6285                        + " is not allowed to cancel packges "
6286                        + rec.key.packageName;
6287                    Slog.w(TAG, msg);
6288                    throw new SecurityException(msg);
6289                }
6290            } catch (RemoteException e) {
6291                throw new SecurityException(e);
6292            }
6293            cancelIntentSenderLocked(rec, true);
6294        }
6295    }
6296
6297    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6298        rec.canceled = true;
6299        mIntentSenderRecords.remove(rec.key);
6300        if (cleanActivity && rec.key.activity != null) {
6301            rec.key.activity.pendingResults.remove(rec.ref);
6302        }
6303    }
6304
6305    @Override
6306    public String getPackageForIntentSender(IIntentSender pendingResult) {
6307        if (!(pendingResult instanceof PendingIntentRecord)) {
6308            return null;
6309        }
6310        try {
6311            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6312            return res.key.packageName;
6313        } catch (ClassCastException e) {
6314        }
6315        return null;
6316    }
6317
6318    @Override
6319    public int getUidForIntentSender(IIntentSender sender) {
6320        if (sender instanceof PendingIntentRecord) {
6321            try {
6322                PendingIntentRecord res = (PendingIntentRecord)sender;
6323                return res.uid;
6324            } catch (ClassCastException e) {
6325            }
6326        }
6327        return -1;
6328    }
6329
6330    @Override
6331    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6332        if (!(pendingResult instanceof PendingIntentRecord)) {
6333            return false;
6334        }
6335        try {
6336            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6337            if (res.key.allIntents == null) {
6338                return false;
6339            }
6340            for (int i=0; i<res.key.allIntents.length; i++) {
6341                Intent intent = res.key.allIntents[i];
6342                if (intent.getPackage() != null && intent.getComponent() != null) {
6343                    return false;
6344                }
6345            }
6346            return true;
6347        } catch (ClassCastException e) {
6348        }
6349        return false;
6350    }
6351
6352    @Override
6353    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6354        if (!(pendingResult instanceof PendingIntentRecord)) {
6355            return false;
6356        }
6357        try {
6358            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6359            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6360                return true;
6361            }
6362            return false;
6363        } catch (ClassCastException e) {
6364        }
6365        return false;
6366    }
6367
6368    @Override
6369    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6370        if (!(pendingResult instanceof PendingIntentRecord)) {
6371            return null;
6372        }
6373        try {
6374            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6375            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6376        } catch (ClassCastException e) {
6377        }
6378        return null;
6379    }
6380
6381    @Override
6382    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6383        if (!(pendingResult instanceof PendingIntentRecord)) {
6384            return null;
6385        }
6386        try {
6387            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6388            synchronized (this) {
6389                return getTagForIntentSenderLocked(res, prefix);
6390            }
6391        } catch (ClassCastException e) {
6392        }
6393        return null;
6394    }
6395
6396    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
6397        final Intent intent = res.key.requestIntent;
6398        if (intent != null) {
6399            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6400                    || res.lastTagPrefix.equals(prefix))) {
6401                return res.lastTag;
6402            }
6403            res.lastTagPrefix = prefix;
6404            final StringBuilder sb = new StringBuilder(128);
6405            if (prefix != null) {
6406                sb.append(prefix);
6407            }
6408            if (intent.getAction() != null) {
6409                sb.append(intent.getAction());
6410            } else if (intent.getComponent() != null) {
6411                intent.getComponent().appendShortString(sb);
6412            } else {
6413                sb.append("?");
6414            }
6415            return res.lastTag = sb.toString();
6416        }
6417        return null;
6418    }
6419
6420    @Override
6421    public void setProcessLimit(int max) {
6422        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6423                "setProcessLimit()");
6424        synchronized (this) {
6425            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6426            mProcessLimitOverride = max;
6427        }
6428        trimApplications();
6429    }
6430
6431    @Override
6432    public int getProcessLimit() {
6433        synchronized (this) {
6434            return mProcessLimitOverride;
6435        }
6436    }
6437
6438    void foregroundTokenDied(ForegroundToken token) {
6439        synchronized (ActivityManagerService.this) {
6440            synchronized (mPidsSelfLocked) {
6441                ForegroundToken cur
6442                    = mForegroundProcesses.get(token.pid);
6443                if (cur != token) {
6444                    return;
6445                }
6446                mForegroundProcesses.remove(token.pid);
6447                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6448                if (pr == null) {
6449                    return;
6450                }
6451                pr.forcingToForeground = null;
6452                updateProcessForegroundLocked(pr, false, false);
6453            }
6454            updateOomAdjLocked();
6455        }
6456    }
6457
6458    @Override
6459    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6460        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6461                "setProcessForeground()");
6462        synchronized(this) {
6463            boolean changed = false;
6464
6465            synchronized (mPidsSelfLocked) {
6466                ProcessRecord pr = mPidsSelfLocked.get(pid);
6467                if (pr == null && isForeground) {
6468                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6469                    return;
6470                }
6471                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6472                if (oldToken != null) {
6473                    oldToken.token.unlinkToDeath(oldToken, 0);
6474                    mForegroundProcesses.remove(pid);
6475                    if (pr != null) {
6476                        pr.forcingToForeground = null;
6477                    }
6478                    changed = true;
6479                }
6480                if (isForeground && token != null) {
6481                    ForegroundToken newToken = new ForegroundToken() {
6482                        @Override
6483                        public void binderDied() {
6484                            foregroundTokenDied(this);
6485                        }
6486                    };
6487                    newToken.pid = pid;
6488                    newToken.token = token;
6489                    try {
6490                        token.linkToDeath(newToken, 0);
6491                        mForegroundProcesses.put(pid, newToken);
6492                        pr.forcingToForeground = token;
6493                        changed = true;
6494                    } catch (RemoteException e) {
6495                        // If the process died while doing this, we will later
6496                        // do the cleanup with the process death link.
6497                    }
6498                }
6499            }
6500
6501            if (changed) {
6502                updateOomAdjLocked();
6503            }
6504        }
6505    }
6506
6507    // =========================================================
6508    // PROCESS INFO
6509    // =========================================================
6510
6511    static class ProcessInfoService extends IProcessInfoService.Stub {
6512        final ActivityManagerService mActivityManagerService;
6513        ProcessInfoService(ActivityManagerService activityManagerService) {
6514            mActivityManagerService = activityManagerService;
6515        }
6516
6517        @Override
6518        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
6519            mActivityManagerService.getProcessStatesForPIDs(/*in*/ pids, /*out*/ states);
6520        }
6521    }
6522
6523    /**
6524     * For each PID in the given input array, write the current process state
6525     * for that process into the output array, or -1 to indicate that no
6526     * process with the given PID exists.
6527     */
6528    public void getProcessStatesForPIDs(/*in*/ int[] pids, /*out*/ int[] states) {
6529        if (pids == null) {
6530            throw new NullPointerException("pids");
6531        } else if (states == null) {
6532            throw new NullPointerException("states");
6533        } else if (pids.length != states.length) {
6534            throw new IllegalArgumentException("input and output arrays have different lengths!");
6535        }
6536
6537        synchronized (mPidsSelfLocked) {
6538            for (int i = 0; i < pids.length; i++) {
6539                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
6540                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
6541                        pr.curProcState;
6542            }
6543        }
6544    }
6545
6546    // =========================================================
6547    // PERMISSIONS
6548    // =========================================================
6549
6550    static class PermissionController extends IPermissionController.Stub {
6551        ActivityManagerService mActivityManagerService;
6552        PermissionController(ActivityManagerService activityManagerService) {
6553            mActivityManagerService = activityManagerService;
6554        }
6555
6556        @Override
6557        public boolean checkPermission(String permission, int pid, int uid) {
6558            return mActivityManagerService.checkPermission(permission, pid,
6559                    uid) == PackageManager.PERMISSION_GRANTED;
6560        }
6561    }
6562
6563    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6564        @Override
6565        public int checkComponentPermission(String permission, int pid, int uid,
6566                int owningUid, boolean exported) {
6567            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6568                    owningUid, exported);
6569        }
6570
6571        @Override
6572        public Object getAMSLock() {
6573            return ActivityManagerService.this;
6574        }
6575    }
6576
6577    /**
6578     * This can be called with or without the global lock held.
6579     */
6580    int checkComponentPermission(String permission, int pid, int uid,
6581            int owningUid, boolean exported) {
6582        if (pid == MY_PID) {
6583            return PackageManager.PERMISSION_GRANTED;
6584        }
6585        return ActivityManager.checkComponentPermission(permission, uid,
6586                owningUid, exported);
6587    }
6588
6589    /**
6590     * As the only public entry point for permissions checking, this method
6591     * can enforce the semantic that requesting a check on a null global
6592     * permission is automatically denied.  (Internally a null permission
6593     * string is used when calling {@link #checkComponentPermission} in cases
6594     * when only uid-based security is needed.)
6595     *
6596     * This can be called with or without the global lock held.
6597     */
6598    @Override
6599    public int checkPermission(String permission, int pid, int uid) {
6600        if (permission == null) {
6601            return PackageManager.PERMISSION_DENIED;
6602        }
6603        return checkComponentPermission(permission, pid, uid, -1, true);
6604    }
6605
6606    @Override
6607    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
6608        if (permission == null) {
6609            return PackageManager.PERMISSION_DENIED;
6610        }
6611
6612        // We might be performing an operation on behalf of an indirect binder
6613        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6614        // client identity accordingly before proceeding.
6615        Identity tlsIdentity = sCallerIdentity.get();
6616        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6617            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6618                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6619            uid = tlsIdentity.uid;
6620            pid = tlsIdentity.pid;
6621        }
6622
6623        return checkComponentPermission(permission, pid, uid, -1, true);
6624    }
6625
6626    /**
6627     * Binder IPC calls go through the public entry point.
6628     * This can be called with or without the global lock held.
6629     */
6630    int checkCallingPermission(String permission) {
6631        return checkPermission(permission,
6632                Binder.getCallingPid(),
6633                UserHandle.getAppId(Binder.getCallingUid()));
6634    }
6635
6636    /**
6637     * This can be called with or without the global lock held.
6638     */
6639    void enforceCallingPermission(String permission, String func) {
6640        if (checkCallingPermission(permission)
6641                == PackageManager.PERMISSION_GRANTED) {
6642            return;
6643        }
6644
6645        String msg = "Permission Denial: " + func + " from pid="
6646                + Binder.getCallingPid()
6647                + ", uid=" + Binder.getCallingUid()
6648                + " requires " + permission;
6649        Slog.w(TAG, msg);
6650        throw new SecurityException(msg);
6651    }
6652
6653    /**
6654     * Determine if UID is holding permissions required to access {@link Uri} in
6655     * the given {@link ProviderInfo}. Final permission checking is always done
6656     * in {@link ContentProvider}.
6657     */
6658    private final boolean checkHoldingPermissionsLocked(
6659            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6660        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
6661                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6662        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6663            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6664                    != PERMISSION_GRANTED) {
6665                return false;
6666            }
6667        }
6668        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6669    }
6670
6671    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6672            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6673        if (pi.applicationInfo.uid == uid) {
6674            return true;
6675        } else if (!pi.exported) {
6676            return false;
6677        }
6678
6679        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6680        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6681        try {
6682            // check if target holds top-level <provider> permissions
6683            if (!readMet && pi.readPermission != null && considerUidPermissions
6684                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6685                readMet = true;
6686            }
6687            if (!writeMet && pi.writePermission != null && considerUidPermissions
6688                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6689                writeMet = true;
6690            }
6691
6692            // track if unprotected read/write is allowed; any denied
6693            // <path-permission> below removes this ability
6694            boolean allowDefaultRead = pi.readPermission == null;
6695            boolean allowDefaultWrite = pi.writePermission == null;
6696
6697            // check if target holds any <path-permission> that match uri
6698            final PathPermission[] pps = pi.pathPermissions;
6699            if (pps != null) {
6700                final String path = grantUri.uri.getPath();
6701                int i = pps.length;
6702                while (i > 0 && (!readMet || !writeMet)) {
6703                    i--;
6704                    PathPermission pp = pps[i];
6705                    if (pp.match(path)) {
6706                        if (!readMet) {
6707                            final String pprperm = pp.getReadPermission();
6708                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
6709                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
6710                                    + ": match=" + pp.match(path)
6711                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6712                            if (pprperm != null) {
6713                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6714                                        == PERMISSION_GRANTED) {
6715                                    readMet = true;
6716                                } else {
6717                                    allowDefaultRead = false;
6718                                }
6719                            }
6720                        }
6721                        if (!writeMet) {
6722                            final String ppwperm = pp.getWritePermission();
6723                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
6724                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
6725                                    + ": match=" + pp.match(path)
6726                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6727                            if (ppwperm != null) {
6728                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6729                                        == PERMISSION_GRANTED) {
6730                                    writeMet = true;
6731                                } else {
6732                                    allowDefaultWrite = false;
6733                                }
6734                            }
6735                        }
6736                    }
6737                }
6738            }
6739
6740            // grant unprotected <provider> read/write, if not blocked by
6741            // <path-permission> above
6742            if (allowDefaultRead) readMet = true;
6743            if (allowDefaultWrite) writeMet = true;
6744
6745        } catch (RemoteException e) {
6746            return false;
6747        }
6748
6749        return readMet && writeMet;
6750    }
6751
6752    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6753        ProviderInfo pi = null;
6754        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6755        if (cpr != null) {
6756            pi = cpr.info;
6757        } else {
6758            try {
6759                pi = AppGlobals.getPackageManager().resolveContentProvider(
6760                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6761            } catch (RemoteException ex) {
6762            }
6763        }
6764        return pi;
6765    }
6766
6767    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6768        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6769        if (targetUris != null) {
6770            return targetUris.get(grantUri);
6771        }
6772        return null;
6773    }
6774
6775    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6776            String targetPkg, int targetUid, GrantUri grantUri) {
6777        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6778        if (targetUris == null) {
6779            targetUris = Maps.newArrayMap();
6780            mGrantedUriPermissions.put(targetUid, targetUris);
6781        }
6782
6783        UriPermission perm = targetUris.get(grantUri);
6784        if (perm == null) {
6785            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6786            targetUris.put(grantUri, perm);
6787        }
6788
6789        return perm;
6790    }
6791
6792    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6793            final int modeFlags) {
6794        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6795        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6796                : UriPermission.STRENGTH_OWNED;
6797
6798        // Root gets to do everything.
6799        if (uid == 0) {
6800            return true;
6801        }
6802
6803        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6804        if (perms == null) return false;
6805
6806        // First look for exact match
6807        final UriPermission exactPerm = perms.get(grantUri);
6808        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6809            return true;
6810        }
6811
6812        // No exact match, look for prefixes
6813        final int N = perms.size();
6814        for (int i = 0; i < N; i++) {
6815            final UriPermission perm = perms.valueAt(i);
6816            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6817                    && perm.getStrength(modeFlags) >= minStrength) {
6818                return true;
6819            }
6820        }
6821
6822        return false;
6823    }
6824
6825    /**
6826     * @param uri This uri must NOT contain an embedded userId.
6827     * @param userId The userId in which the uri is to be resolved.
6828     */
6829    @Override
6830    public int checkUriPermission(Uri uri, int pid, int uid,
6831            final int modeFlags, int userId, IBinder callerToken) {
6832        enforceNotIsolatedCaller("checkUriPermission");
6833
6834        // Another redirected-binder-call permissions check as in
6835        // {@link checkPermissionWithToken}.
6836        Identity tlsIdentity = sCallerIdentity.get();
6837        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6838            uid = tlsIdentity.uid;
6839            pid = tlsIdentity.pid;
6840        }
6841
6842        // Our own process gets to do everything.
6843        if (pid == MY_PID) {
6844            return PackageManager.PERMISSION_GRANTED;
6845        }
6846        synchronized (this) {
6847            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6848                    ? PackageManager.PERMISSION_GRANTED
6849                    : PackageManager.PERMISSION_DENIED;
6850        }
6851    }
6852
6853    /**
6854     * Check if the targetPkg can be granted permission to access uri by
6855     * the callingUid using the given modeFlags.  Throws a security exception
6856     * if callingUid is not allowed to do this.  Returns the uid of the target
6857     * if the URI permission grant should be performed; returns -1 if it is not
6858     * needed (for example targetPkg already has permission to access the URI).
6859     * If you already know the uid of the target, you can supply it in
6860     * lastTargetUid else set that to -1.
6861     */
6862    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6863            final int modeFlags, int lastTargetUid) {
6864        if (!Intent.isAccessUriMode(modeFlags)) {
6865            return -1;
6866        }
6867
6868        if (targetPkg != null) {
6869            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
6870                    "Checking grant " + targetPkg + " permission to " + grantUri);
6871        }
6872
6873        final IPackageManager pm = AppGlobals.getPackageManager();
6874
6875        // If this is not a content: uri, we can't do anything with it.
6876        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6877            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
6878                    "Can't grant URI permission for non-content URI: " + grantUri);
6879            return -1;
6880        }
6881
6882        final String authority = grantUri.uri.getAuthority();
6883        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6884        if (pi == null) {
6885            Slog.w(TAG, "No content provider found for permission check: " +
6886                    grantUri.uri.toSafeString());
6887            return -1;
6888        }
6889
6890        int targetUid = lastTargetUid;
6891        if (targetUid < 0 && targetPkg != null) {
6892            try {
6893                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6894                if (targetUid < 0) {
6895                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
6896                            "Can't grant URI permission no uid for: " + targetPkg);
6897                    return -1;
6898                }
6899            } catch (RemoteException ex) {
6900                return -1;
6901            }
6902        }
6903
6904        if (targetUid >= 0) {
6905            // First...  does the target actually need this permission?
6906            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6907                // No need to grant the target this permission.
6908                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
6909                        "Target " + targetPkg + " already has full permission to " + grantUri);
6910                return -1;
6911            }
6912        } else {
6913            // First...  there is no target package, so can anyone access it?
6914            boolean allowed = pi.exported;
6915            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6916                if (pi.readPermission != null) {
6917                    allowed = false;
6918                }
6919            }
6920            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6921                if (pi.writePermission != null) {
6922                    allowed = false;
6923                }
6924            }
6925            if (allowed) {
6926                return -1;
6927            }
6928        }
6929
6930        /* There is a special cross user grant if:
6931         * - The target is on another user.
6932         * - Apps on the current user can access the uri without any uid permissions.
6933         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6934         * grant uri permissions.
6935         */
6936        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6937                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6938                modeFlags, false /*without considering the uid permissions*/);
6939
6940        // Second...  is the provider allowing granting of URI permissions?
6941        if (!specialCrossUserGrant) {
6942            if (!pi.grantUriPermissions) {
6943                throw new SecurityException("Provider " + pi.packageName
6944                        + "/" + pi.name
6945                        + " does not allow granting of Uri permissions (uri "
6946                        + grantUri + ")");
6947            }
6948            if (pi.uriPermissionPatterns != null) {
6949                final int N = pi.uriPermissionPatterns.length;
6950                boolean allowed = false;
6951                for (int i=0; i<N; i++) {
6952                    if (pi.uriPermissionPatterns[i] != null
6953                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6954                        allowed = true;
6955                        break;
6956                    }
6957                }
6958                if (!allowed) {
6959                    throw new SecurityException("Provider " + pi.packageName
6960                            + "/" + pi.name
6961                            + " does not allow granting of permission to path of Uri "
6962                            + grantUri);
6963                }
6964            }
6965        }
6966
6967        // Third...  does the caller itself have permission to access
6968        // this uri?
6969        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6970            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6971                // Require they hold a strong enough Uri permission
6972                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6973                    throw new SecurityException("Uid " + callingUid
6974                            + " does not have permission to uri " + grantUri);
6975                }
6976            }
6977        }
6978        return targetUid;
6979    }
6980
6981    /**
6982     * @param uri This uri must NOT contain an embedded userId.
6983     * @param userId The userId in which the uri is to be resolved.
6984     */
6985    @Override
6986    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6987            final int modeFlags, int userId) {
6988        enforceNotIsolatedCaller("checkGrantUriPermission");
6989        synchronized(this) {
6990            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6991                    new GrantUri(userId, uri, false), modeFlags, -1);
6992        }
6993    }
6994
6995    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6996            final int modeFlags, UriPermissionOwner owner) {
6997        if (!Intent.isAccessUriMode(modeFlags)) {
6998            return;
6999        }
7000
7001        // So here we are: the caller has the assumed permission
7002        // to the uri, and the target doesn't.  Let's now give this to
7003        // the target.
7004
7005        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7006                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7007
7008        final String authority = grantUri.uri.getAuthority();
7009        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7010        if (pi == null) {
7011            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7012            return;
7013        }
7014
7015        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7016            grantUri.prefix = true;
7017        }
7018        final UriPermission perm = findOrCreateUriPermissionLocked(
7019                pi.packageName, targetPkg, targetUid, grantUri);
7020        perm.grantModes(modeFlags, owner);
7021    }
7022
7023    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7024            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7025        if (targetPkg == null) {
7026            throw new NullPointerException("targetPkg");
7027        }
7028        int targetUid;
7029        final IPackageManager pm = AppGlobals.getPackageManager();
7030        try {
7031            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7032        } catch (RemoteException ex) {
7033            return;
7034        }
7035
7036        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7037                targetUid);
7038        if (targetUid < 0) {
7039            return;
7040        }
7041
7042        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7043                owner);
7044    }
7045
7046    static class NeededUriGrants extends ArrayList<GrantUri> {
7047        final String targetPkg;
7048        final int targetUid;
7049        final int flags;
7050
7051        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7052            this.targetPkg = targetPkg;
7053            this.targetUid = targetUid;
7054            this.flags = flags;
7055        }
7056    }
7057
7058    /**
7059     * Like checkGrantUriPermissionLocked, but takes an Intent.
7060     */
7061    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7062            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7063        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7064                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7065                + " clip=" + (intent != null ? intent.getClipData() : null)
7066                + " from " + intent + "; flags=0x"
7067                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7068
7069        if (targetPkg == null) {
7070            throw new NullPointerException("targetPkg");
7071        }
7072
7073        if (intent == null) {
7074            return null;
7075        }
7076        Uri data = intent.getData();
7077        ClipData clip = intent.getClipData();
7078        if (data == null && clip == null) {
7079            return null;
7080        }
7081        // Default userId for uris in the intent (if they don't specify it themselves)
7082        int contentUserHint = intent.getContentUserHint();
7083        if (contentUserHint == UserHandle.USER_CURRENT) {
7084            contentUserHint = UserHandle.getUserId(callingUid);
7085        }
7086        final IPackageManager pm = AppGlobals.getPackageManager();
7087        int targetUid;
7088        if (needed != null) {
7089            targetUid = needed.targetUid;
7090        } else {
7091            try {
7092                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7093            } catch (RemoteException ex) {
7094                return null;
7095            }
7096            if (targetUid < 0) {
7097                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7098                        "Can't grant URI permission no uid for: " + targetPkg
7099                        + " on user " + targetUserId);
7100                return null;
7101            }
7102        }
7103        if (data != null) {
7104            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7105            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7106                    targetUid);
7107            if (targetUid > 0) {
7108                if (needed == null) {
7109                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7110                }
7111                needed.add(grantUri);
7112            }
7113        }
7114        if (clip != null) {
7115            for (int i=0; i<clip.getItemCount(); i++) {
7116                Uri uri = clip.getItemAt(i).getUri();
7117                if (uri != null) {
7118                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7119                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7120                            targetUid);
7121                    if (targetUid > 0) {
7122                        if (needed == null) {
7123                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7124                        }
7125                        needed.add(grantUri);
7126                    }
7127                } else {
7128                    Intent clipIntent = clip.getItemAt(i).getIntent();
7129                    if (clipIntent != null) {
7130                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7131                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7132                        if (newNeeded != null) {
7133                            needed = newNeeded;
7134                        }
7135                    }
7136                }
7137            }
7138        }
7139
7140        return needed;
7141    }
7142
7143    /**
7144     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7145     */
7146    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7147            UriPermissionOwner owner) {
7148        if (needed != null) {
7149            for (int i=0; i<needed.size(); i++) {
7150                GrantUri grantUri = needed.get(i);
7151                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7152                        grantUri, needed.flags, owner);
7153            }
7154        }
7155    }
7156
7157    void grantUriPermissionFromIntentLocked(int callingUid,
7158            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7159        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7160                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7161        if (needed == null) {
7162            return;
7163        }
7164
7165        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7166    }
7167
7168    /**
7169     * @param uri This uri must NOT contain an embedded userId.
7170     * @param userId The userId in which the uri is to be resolved.
7171     */
7172    @Override
7173    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7174            final int modeFlags, int userId) {
7175        enforceNotIsolatedCaller("grantUriPermission");
7176        GrantUri grantUri = new GrantUri(userId, uri, false);
7177        synchronized(this) {
7178            final ProcessRecord r = getRecordForAppLocked(caller);
7179            if (r == null) {
7180                throw new SecurityException("Unable to find app for caller "
7181                        + caller
7182                        + " when granting permission to uri " + grantUri);
7183            }
7184            if (targetPkg == null) {
7185                throw new IllegalArgumentException("null target");
7186            }
7187            if (grantUri == null) {
7188                throw new IllegalArgumentException("null uri");
7189            }
7190
7191            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7192                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7193                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7194                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7195
7196            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7197                    UserHandle.getUserId(r.uid));
7198        }
7199    }
7200
7201    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7202        if (perm.modeFlags == 0) {
7203            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7204                    perm.targetUid);
7205            if (perms != null) {
7206                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7207                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7208
7209                perms.remove(perm.uri);
7210                if (perms.isEmpty()) {
7211                    mGrantedUriPermissions.remove(perm.targetUid);
7212                }
7213            }
7214        }
7215    }
7216
7217    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7218        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7219                "Revoking all granted permissions to " + grantUri);
7220
7221        final IPackageManager pm = AppGlobals.getPackageManager();
7222        final String authority = grantUri.uri.getAuthority();
7223        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7224        if (pi == null) {
7225            Slog.w(TAG, "No content provider found for permission revoke: "
7226                    + grantUri.toSafeString());
7227            return;
7228        }
7229
7230        // Does the caller have this permission on the URI?
7231        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7232            // If they don't have direct access to the URI, then revoke any
7233            // ownerless URI permissions that have been granted to them.
7234            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7235            if (perms != null) {
7236                boolean persistChanged = false;
7237                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7238                    final UriPermission perm = it.next();
7239                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7240                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7241                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7242                                "Revoking non-owned " + perm.targetUid
7243                                + " permission to " + perm.uri);
7244                        persistChanged |= perm.revokeModes(
7245                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7246                        if (perm.modeFlags == 0) {
7247                            it.remove();
7248                        }
7249                    }
7250                }
7251                if (perms.isEmpty()) {
7252                    mGrantedUriPermissions.remove(callingUid);
7253                }
7254                if (persistChanged) {
7255                    schedulePersistUriGrants();
7256                }
7257            }
7258            return;
7259        }
7260
7261        boolean persistChanged = false;
7262
7263        // Go through all of the permissions and remove any that match.
7264        int N = mGrantedUriPermissions.size();
7265        for (int i = 0; i < N; i++) {
7266            final int targetUid = mGrantedUriPermissions.keyAt(i);
7267            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7268
7269            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7270                final UriPermission perm = it.next();
7271                if (perm.uri.sourceUserId == grantUri.sourceUserId
7272                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7273                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7274                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7275                    persistChanged |= perm.revokeModes(
7276                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7277                    if (perm.modeFlags == 0) {
7278                        it.remove();
7279                    }
7280                }
7281            }
7282
7283            if (perms.isEmpty()) {
7284                mGrantedUriPermissions.remove(targetUid);
7285                N--;
7286                i--;
7287            }
7288        }
7289
7290        if (persistChanged) {
7291            schedulePersistUriGrants();
7292        }
7293    }
7294
7295    /**
7296     * @param uri This uri must NOT contain an embedded userId.
7297     * @param userId The userId in which the uri is to be resolved.
7298     */
7299    @Override
7300    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7301            int userId) {
7302        enforceNotIsolatedCaller("revokeUriPermission");
7303        synchronized(this) {
7304            final ProcessRecord r = getRecordForAppLocked(caller);
7305            if (r == null) {
7306                throw new SecurityException("Unable to find app for caller "
7307                        + caller
7308                        + " when revoking permission to uri " + uri);
7309            }
7310            if (uri == null) {
7311                Slog.w(TAG, "revokeUriPermission: null uri");
7312                return;
7313            }
7314
7315            if (!Intent.isAccessUriMode(modeFlags)) {
7316                return;
7317            }
7318
7319            final String authority = uri.getAuthority();
7320            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7321            if (pi == null) {
7322                Slog.w(TAG, "No content provider found for permission revoke: "
7323                        + uri.toSafeString());
7324                return;
7325            }
7326
7327            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7328        }
7329    }
7330
7331    /**
7332     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7333     * given package.
7334     *
7335     * @param packageName Package name to match, or {@code null} to apply to all
7336     *            packages.
7337     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7338     *            to all users.
7339     * @param persistable If persistable grants should be removed.
7340     */
7341    private void removeUriPermissionsForPackageLocked(
7342            String packageName, int userHandle, boolean persistable) {
7343        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7344            throw new IllegalArgumentException("Must narrow by either package or user");
7345        }
7346
7347        boolean persistChanged = false;
7348
7349        int N = mGrantedUriPermissions.size();
7350        for (int i = 0; i < N; i++) {
7351            final int targetUid = mGrantedUriPermissions.keyAt(i);
7352            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7353
7354            // Only inspect grants matching user
7355            if (userHandle == UserHandle.USER_ALL
7356                    || userHandle == UserHandle.getUserId(targetUid)) {
7357                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7358                    final UriPermission perm = it.next();
7359
7360                    // Only inspect grants matching package
7361                    if (packageName == null || perm.sourcePkg.equals(packageName)
7362                            || perm.targetPkg.equals(packageName)) {
7363                        persistChanged |= perm.revokeModes(persistable
7364                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7365
7366                        // Only remove when no modes remain; any persisted grants
7367                        // will keep this alive.
7368                        if (perm.modeFlags == 0) {
7369                            it.remove();
7370                        }
7371                    }
7372                }
7373
7374                if (perms.isEmpty()) {
7375                    mGrantedUriPermissions.remove(targetUid);
7376                    N--;
7377                    i--;
7378                }
7379            }
7380        }
7381
7382        if (persistChanged) {
7383            schedulePersistUriGrants();
7384        }
7385    }
7386
7387    @Override
7388    public IBinder newUriPermissionOwner(String name) {
7389        enforceNotIsolatedCaller("newUriPermissionOwner");
7390        synchronized(this) {
7391            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7392            return owner.getExternalTokenLocked();
7393        }
7394    }
7395
7396    /**
7397     * @param uri This uri must NOT contain an embedded userId.
7398     * @param sourceUserId The userId in which the uri is to be resolved.
7399     * @param targetUserId The userId of the app that receives the grant.
7400     */
7401    @Override
7402    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7403            final int modeFlags, int sourceUserId, int targetUserId) {
7404        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7405                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7406        synchronized(this) {
7407            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7408            if (owner == null) {
7409                throw new IllegalArgumentException("Unknown owner: " + token);
7410            }
7411            if (fromUid != Binder.getCallingUid()) {
7412                if (Binder.getCallingUid() != Process.myUid()) {
7413                    // Only system code can grant URI permissions on behalf
7414                    // of other users.
7415                    throw new SecurityException("nice try");
7416                }
7417            }
7418            if (targetPkg == null) {
7419                throw new IllegalArgumentException("null target");
7420            }
7421            if (uri == null) {
7422                throw new IllegalArgumentException("null uri");
7423            }
7424
7425            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7426                    modeFlags, owner, targetUserId);
7427        }
7428    }
7429
7430    /**
7431     * @param uri This uri must NOT contain an embedded userId.
7432     * @param userId The userId in which the uri is to be resolved.
7433     */
7434    @Override
7435    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7436        synchronized(this) {
7437            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7438            if (owner == null) {
7439                throw new IllegalArgumentException("Unknown owner: " + token);
7440            }
7441
7442            if (uri == null) {
7443                owner.removeUriPermissionsLocked(mode);
7444            } else {
7445                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7446            }
7447        }
7448    }
7449
7450    private void schedulePersistUriGrants() {
7451        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7452            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7453                    10 * DateUtils.SECOND_IN_MILLIS);
7454        }
7455    }
7456
7457    private void writeGrantedUriPermissions() {
7458        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
7459
7460        // Snapshot permissions so we can persist without lock
7461        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7462        synchronized (this) {
7463            final int size = mGrantedUriPermissions.size();
7464            for (int i = 0; i < size; i++) {
7465                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7466                for (UriPermission perm : perms.values()) {
7467                    if (perm.persistedModeFlags != 0) {
7468                        persist.add(perm.snapshot());
7469                    }
7470                }
7471            }
7472        }
7473
7474        FileOutputStream fos = null;
7475        try {
7476            fos = mGrantFile.startWrite();
7477
7478            XmlSerializer out = new FastXmlSerializer();
7479            out.setOutput(fos, "utf-8");
7480            out.startDocument(null, true);
7481            out.startTag(null, TAG_URI_GRANTS);
7482            for (UriPermission.Snapshot perm : persist) {
7483                out.startTag(null, TAG_URI_GRANT);
7484                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7485                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7486                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7487                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7488                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7489                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7490                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7491                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7492                out.endTag(null, TAG_URI_GRANT);
7493            }
7494            out.endTag(null, TAG_URI_GRANTS);
7495            out.endDocument();
7496
7497            mGrantFile.finishWrite(fos);
7498        } catch (IOException e) {
7499            if (fos != null) {
7500                mGrantFile.failWrite(fos);
7501            }
7502        }
7503    }
7504
7505    private void readGrantedUriPermissionsLocked() {
7506        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
7507
7508        final long now = System.currentTimeMillis();
7509
7510        FileInputStream fis = null;
7511        try {
7512            fis = mGrantFile.openRead();
7513            final XmlPullParser in = Xml.newPullParser();
7514            in.setInput(fis, null);
7515
7516            int type;
7517            while ((type = in.next()) != END_DOCUMENT) {
7518                final String tag = in.getName();
7519                if (type == START_TAG) {
7520                    if (TAG_URI_GRANT.equals(tag)) {
7521                        final int sourceUserId;
7522                        final int targetUserId;
7523                        final int userHandle = readIntAttribute(in,
7524                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7525                        if (userHandle != UserHandle.USER_NULL) {
7526                            // For backwards compatibility.
7527                            sourceUserId = userHandle;
7528                            targetUserId = userHandle;
7529                        } else {
7530                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7531                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7532                        }
7533                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7534                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7535                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7536                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7537                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7538                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7539
7540                        // Sanity check that provider still belongs to source package
7541                        final ProviderInfo pi = getProviderInfoLocked(
7542                                uri.getAuthority(), sourceUserId);
7543                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7544                            int targetUid = -1;
7545                            try {
7546                                targetUid = AppGlobals.getPackageManager()
7547                                        .getPackageUid(targetPkg, targetUserId);
7548                            } catch (RemoteException e) {
7549                            }
7550                            if (targetUid != -1) {
7551                                final UriPermission perm = findOrCreateUriPermissionLocked(
7552                                        sourcePkg, targetPkg, targetUid,
7553                                        new GrantUri(sourceUserId, uri, prefix));
7554                                perm.initPersistedModes(modeFlags, createdTime);
7555                            }
7556                        } else {
7557                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7558                                    + " but instead found " + pi);
7559                        }
7560                    }
7561                }
7562            }
7563        } catch (FileNotFoundException e) {
7564            // Missing grants is okay
7565        } catch (IOException e) {
7566            Slog.wtf(TAG, "Failed reading Uri grants", e);
7567        } catch (XmlPullParserException e) {
7568            Slog.wtf(TAG, "Failed reading Uri grants", e);
7569        } finally {
7570            IoUtils.closeQuietly(fis);
7571        }
7572    }
7573
7574    /**
7575     * @param uri This uri must NOT contain an embedded userId.
7576     * @param userId The userId in which the uri is to be resolved.
7577     */
7578    @Override
7579    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7580        enforceNotIsolatedCaller("takePersistableUriPermission");
7581
7582        Preconditions.checkFlagsArgument(modeFlags,
7583                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7584
7585        synchronized (this) {
7586            final int callingUid = Binder.getCallingUid();
7587            boolean persistChanged = false;
7588            GrantUri grantUri = new GrantUri(userId, uri, false);
7589
7590            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7591                    new GrantUri(userId, uri, false));
7592            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7593                    new GrantUri(userId, uri, true));
7594
7595            final boolean exactValid = (exactPerm != null)
7596                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7597            final boolean prefixValid = (prefixPerm != null)
7598                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7599
7600            if (!(exactValid || prefixValid)) {
7601                throw new SecurityException("No persistable permission grants found for UID "
7602                        + callingUid + " and Uri " + grantUri.toSafeString());
7603            }
7604
7605            if (exactValid) {
7606                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7607            }
7608            if (prefixValid) {
7609                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7610            }
7611
7612            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7613
7614            if (persistChanged) {
7615                schedulePersistUriGrants();
7616            }
7617        }
7618    }
7619
7620    /**
7621     * @param uri This uri must NOT contain an embedded userId.
7622     * @param userId The userId in which the uri is to be resolved.
7623     */
7624    @Override
7625    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7626        enforceNotIsolatedCaller("releasePersistableUriPermission");
7627
7628        Preconditions.checkFlagsArgument(modeFlags,
7629                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7630
7631        synchronized (this) {
7632            final int callingUid = Binder.getCallingUid();
7633            boolean persistChanged = false;
7634
7635            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7636                    new GrantUri(userId, uri, false));
7637            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7638                    new GrantUri(userId, uri, true));
7639            if (exactPerm == null && prefixPerm == null) {
7640                throw new SecurityException("No permission grants found for UID " + callingUid
7641                        + " and Uri " + uri.toSafeString());
7642            }
7643
7644            if (exactPerm != null) {
7645                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7646                removeUriPermissionIfNeededLocked(exactPerm);
7647            }
7648            if (prefixPerm != null) {
7649                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7650                removeUriPermissionIfNeededLocked(prefixPerm);
7651            }
7652
7653            if (persistChanged) {
7654                schedulePersistUriGrants();
7655            }
7656        }
7657    }
7658
7659    /**
7660     * Prune any older {@link UriPermission} for the given UID until outstanding
7661     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7662     *
7663     * @return if any mutations occured that require persisting.
7664     */
7665    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7666        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7667        if (perms == null) return false;
7668        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7669
7670        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7671        for (UriPermission perm : perms.values()) {
7672            if (perm.persistedModeFlags != 0) {
7673                persisted.add(perm);
7674            }
7675        }
7676
7677        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7678        if (trimCount <= 0) return false;
7679
7680        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7681        for (int i = 0; i < trimCount; i++) {
7682            final UriPermission perm = persisted.get(i);
7683
7684            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7685                    "Trimming grant created at " + perm.persistedCreateTime);
7686
7687            perm.releasePersistableModes(~0);
7688            removeUriPermissionIfNeededLocked(perm);
7689        }
7690
7691        return true;
7692    }
7693
7694    @Override
7695    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7696            String packageName, boolean incoming) {
7697        enforceNotIsolatedCaller("getPersistedUriPermissions");
7698        Preconditions.checkNotNull(packageName, "packageName");
7699
7700        final int callingUid = Binder.getCallingUid();
7701        final IPackageManager pm = AppGlobals.getPackageManager();
7702        try {
7703            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7704            if (packageUid != callingUid) {
7705                throw new SecurityException(
7706                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7707            }
7708        } catch (RemoteException e) {
7709            throw new SecurityException("Failed to verify package name ownership");
7710        }
7711
7712        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7713        synchronized (this) {
7714            if (incoming) {
7715                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7716                        callingUid);
7717                if (perms == null) {
7718                    Slog.w(TAG, "No permission grants found for " + packageName);
7719                } else {
7720                    for (UriPermission perm : perms.values()) {
7721                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7722                            result.add(perm.buildPersistedPublicApiObject());
7723                        }
7724                    }
7725                }
7726            } else {
7727                final int size = mGrantedUriPermissions.size();
7728                for (int i = 0; i < size; i++) {
7729                    final ArrayMap<GrantUri, UriPermission> perms =
7730                            mGrantedUriPermissions.valueAt(i);
7731                    for (UriPermission perm : perms.values()) {
7732                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7733                            result.add(perm.buildPersistedPublicApiObject());
7734                        }
7735                    }
7736                }
7737            }
7738        }
7739        return new ParceledListSlice<android.content.UriPermission>(result);
7740    }
7741
7742    @Override
7743    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7744        synchronized (this) {
7745            ProcessRecord app =
7746                who != null ? getRecordForAppLocked(who) : null;
7747            if (app == null) return;
7748
7749            Message msg = Message.obtain();
7750            msg.what = WAIT_FOR_DEBUGGER_MSG;
7751            msg.obj = app;
7752            msg.arg1 = waiting ? 1 : 0;
7753            mHandler.sendMessage(msg);
7754        }
7755    }
7756
7757    @Override
7758    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7759        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7760        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7761        outInfo.availMem = Process.getFreeMemory();
7762        outInfo.totalMem = Process.getTotalMemory();
7763        outInfo.threshold = homeAppMem;
7764        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7765        outInfo.hiddenAppThreshold = cachedAppMem;
7766        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7767                ProcessList.SERVICE_ADJ);
7768        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7769                ProcessList.VISIBLE_APP_ADJ);
7770        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7771                ProcessList.FOREGROUND_APP_ADJ);
7772    }
7773
7774    // =========================================================
7775    // TASK MANAGEMENT
7776    // =========================================================
7777
7778    @Override
7779    public List<IAppTask> getAppTasks(String callingPackage) {
7780        int callingUid = Binder.getCallingUid();
7781        long ident = Binder.clearCallingIdentity();
7782
7783        synchronized(this) {
7784            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7785            try {
7786                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
7787
7788                final int N = mRecentTasks.size();
7789                for (int i = 0; i < N; i++) {
7790                    TaskRecord tr = mRecentTasks.get(i);
7791                    // Skip tasks that do not match the caller.  We don't need to verify
7792                    // callingPackage, because we are also limiting to callingUid and know
7793                    // that will limit to the correct security sandbox.
7794                    if (tr.effectiveUid != callingUid) {
7795                        continue;
7796                    }
7797                    Intent intent = tr.getBaseIntent();
7798                    if (intent == null ||
7799                            !callingPackage.equals(intent.getComponent().getPackageName())) {
7800                        continue;
7801                    }
7802                    ActivityManager.RecentTaskInfo taskInfo =
7803                            createRecentTaskInfoFromTaskRecord(tr);
7804                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7805                    list.add(taskImpl);
7806                }
7807            } finally {
7808                Binder.restoreCallingIdentity(ident);
7809            }
7810            return list;
7811        }
7812    }
7813
7814    @Override
7815    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7816        final int callingUid = Binder.getCallingUid();
7817        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7818
7819        synchronized(this) {
7820            if (DEBUG_ALL) Slog.v(
7821                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7822
7823            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
7824                    callingUid);
7825
7826            // TODO: Improve with MRU list from all ActivityStacks.
7827            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7828        }
7829
7830        return list;
7831    }
7832
7833    /**
7834     * Creates a new RecentTaskInfo from a TaskRecord.
7835     */
7836    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7837        // Update the task description to reflect any changes in the task stack
7838        tr.updateTaskDescription();
7839
7840        // Compose the recent task info
7841        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7842        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
7843        rti.persistentId = tr.taskId;
7844        rti.baseIntent = new Intent(tr.getBaseIntent());
7845        rti.origActivity = tr.origActivity;
7846        rti.description = tr.lastDescription;
7847        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7848        rti.userId = tr.userId;
7849        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7850        rti.firstActiveTime = tr.firstActiveTime;
7851        rti.lastActiveTime = tr.lastActiveTime;
7852        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7853        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
7854        return rti;
7855    }
7856
7857    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
7858        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
7859                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
7860        if (!allowed) {
7861            if (checkPermission(android.Manifest.permission.GET_TASKS,
7862                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
7863                // Temporary compatibility: some existing apps on the system image may
7864                // still be requesting the old permission and not switched to the new
7865                // one; if so, we'll still allow them full access.  This means we need
7866                // to see if they are holding the old permission and are a system app.
7867                try {
7868                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
7869                        allowed = true;
7870                        Slog.w(TAG, caller + ": caller " + callingUid
7871                                + " is using old GET_TASKS but privileged; allowing");
7872                    }
7873                } catch (RemoteException e) {
7874                }
7875            }
7876        }
7877        if (!allowed) {
7878            Slog.w(TAG, caller + ": caller " + callingUid
7879                    + " does not hold REAL_GET_TASKS; limiting output");
7880        }
7881        return allowed;
7882    }
7883
7884    @Override
7885    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7886        final int callingUid = Binder.getCallingUid();
7887        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7888                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7889
7890        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7891        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7892        synchronized (this) {
7893            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
7894                    callingUid);
7895            final boolean detailed = checkCallingPermission(
7896                    android.Manifest.permission.GET_DETAILED_TASKS)
7897                    == PackageManager.PERMISSION_GRANTED;
7898
7899            final int recentsCount = mRecentTasks.size();
7900            ArrayList<ActivityManager.RecentTaskInfo> res =
7901                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
7902
7903            final Set<Integer> includedUsers;
7904            if (includeProfiles) {
7905                includedUsers = getProfileIdsLocked(userId);
7906            } else {
7907                includedUsers = new HashSet<>();
7908            }
7909            includedUsers.add(Integer.valueOf(userId));
7910
7911            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
7912                TaskRecord tr = mRecentTasks.get(i);
7913                // Only add calling user or related users recent tasks
7914                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
7915                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
7916                    continue;
7917                }
7918
7919                // Return the entry if desired by the caller.  We always return
7920                // the first entry, because callers always expect this to be the
7921                // foreground app.  We may filter others if the caller has
7922                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7923                // we should exclude the entry.
7924
7925                if (i == 0
7926                        || withExcluded
7927                        || (tr.intent == null)
7928                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7929                                == 0)) {
7930                    if (!allowed) {
7931                        // If the caller doesn't have the GET_TASKS permission, then only
7932                        // allow them to see a small subset of tasks -- their own and home.
7933                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
7934                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
7935                            continue;
7936                        }
7937                    }
7938                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
7939                        if (tr.stack != null && tr.stack.isHomeStack()) {
7940                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
7941                                    "Skipping, home stack task: " + tr);
7942                            continue;
7943                        }
7944                    }
7945                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
7946                        // Don't include auto remove tasks that are finished or finishing.
7947                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
7948                                "Skipping, auto-remove without activity: " + tr);
7949                        continue;
7950                    }
7951                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
7952                            && !tr.isAvailable) {
7953                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
7954                                "Skipping, unavail real act: " + tr);
7955                        continue;
7956                    }
7957
7958                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7959                    if (!detailed) {
7960                        rti.baseIntent.replaceExtras((Bundle)null);
7961                    }
7962
7963                    res.add(rti);
7964                    maxNum--;
7965                }
7966            }
7967            return res;
7968        }
7969    }
7970
7971    @Override
7972    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7973        synchronized (this) {
7974            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7975                    "getTaskThumbnail()");
7976            TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id, false);
7977            if (tr != null) {
7978                return tr.getTaskThumbnailLocked();
7979            }
7980        }
7981        return null;
7982    }
7983
7984    @Override
7985    public int addAppTask(IBinder activityToken, Intent intent,
7986            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
7987        final int callingUid = Binder.getCallingUid();
7988        final long callingIdent = Binder.clearCallingIdentity();
7989
7990        try {
7991            synchronized (this) {
7992                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
7993                if (r == null) {
7994                    throw new IllegalArgumentException("Activity does not exist; token="
7995                            + activityToken);
7996                }
7997                ComponentName comp = intent.getComponent();
7998                if (comp == null) {
7999                    throw new IllegalArgumentException("Intent " + intent
8000                            + " must specify explicit component");
8001                }
8002                if (thumbnail.getWidth() != mThumbnailWidth
8003                        || thumbnail.getHeight() != mThumbnailHeight) {
8004                    throw new IllegalArgumentException("Bad thumbnail size: got "
8005                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8006                            + mThumbnailWidth + "x" + mThumbnailHeight);
8007                }
8008                if (intent.getSelector() != null) {
8009                    intent.setSelector(null);
8010                }
8011                if (intent.getSourceBounds() != null) {
8012                    intent.setSourceBounds(null);
8013                }
8014                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8015                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8016                        // The caller has added this as an auto-remove task...  that makes no
8017                        // sense, so turn off auto-remove.
8018                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8019                    }
8020                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8021                    // Must be a new task.
8022                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8023                }
8024                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8025                    mLastAddedTaskActivity = null;
8026                }
8027                ActivityInfo ainfo = mLastAddedTaskActivity;
8028                if (ainfo == null) {
8029                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8030                            comp, 0, UserHandle.getUserId(callingUid));
8031                    if (ainfo.applicationInfo.uid != callingUid) {
8032                        throw new SecurityException(
8033                                "Can't add task for another application: target uid="
8034                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8035                    }
8036                }
8037
8038                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8039                        intent, description);
8040
8041                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
8042                if (trimIdx >= 0) {
8043                    // If this would have caused a trim, then we'll abort because that
8044                    // means it would be added at the end of the list but then just removed.
8045                    return INVALID_TASK_ID;
8046                }
8047
8048                final int N = mRecentTasks.size();
8049                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8050                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8051                    tr.removedFromRecents();
8052                }
8053
8054                task.inRecents = true;
8055                mRecentTasks.add(task);
8056                r.task.stack.addTask(task, false, false);
8057
8058                task.setLastThumbnail(thumbnail);
8059                task.freeLastThumbnail();
8060
8061                return task.taskId;
8062            }
8063        } finally {
8064            Binder.restoreCallingIdentity(callingIdent);
8065        }
8066    }
8067
8068    @Override
8069    public Point getAppTaskThumbnailSize() {
8070        synchronized (this) {
8071            return new Point(mThumbnailWidth,  mThumbnailHeight);
8072        }
8073    }
8074
8075    @Override
8076    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8077        synchronized (this) {
8078            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8079            if (r != null) {
8080                r.setTaskDescription(td);
8081                r.task.updateTaskDescription();
8082            }
8083        }
8084    }
8085
8086    @Override
8087    public void setTaskResizeable(int taskId, boolean resizeable) {
8088        synchronized (this) {
8089            TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8090            if (task == null) {
8091                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
8092                return;
8093            }
8094            if (task.mResizeable != resizeable) {
8095                task.mResizeable = resizeable;
8096                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8097                mStackSupervisor.resumeTopActivitiesLocked();
8098            }
8099        }
8100    }
8101
8102    @Override
8103    public void resizeTask(int taskId, Rect bounds) {
8104        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8105                "resizeTask()");
8106        long ident = Binder.clearCallingIdentity();
8107        try {
8108            synchronized (this) {
8109                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8110                if (task == null) {
8111                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
8112                    return;
8113                }
8114                mStackSupervisor.resizeTaskLocked(task, bounds);
8115            }
8116        } finally {
8117            Binder.restoreCallingIdentity(ident);
8118        }
8119    }
8120
8121    @Override
8122    public Bitmap getTaskDescriptionIcon(String filename) {
8123        if (!FileUtils.isValidExtFilename(filename)
8124                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8125            throw new IllegalArgumentException("Bad filename: " + filename);
8126        }
8127        return mTaskPersister.getTaskDescriptionIcon(filename);
8128    }
8129
8130    @Override
8131    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8132            throws RemoteException {
8133        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8134                opts.getCustomInPlaceResId() == 0) {
8135            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8136                    "with valid animation");
8137        }
8138        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8139        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8140                opts.getCustomInPlaceResId());
8141        mWindowManager.executeAppTransition();
8142    }
8143
8144    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8145        mRecentTasks.remove(tr);
8146        tr.removedFromRecents();
8147        ComponentName component = tr.getBaseIntent().getComponent();
8148        if (component == null) {
8149            Slog.w(TAG, "No component for base intent of task: " + tr);
8150            return;
8151        }
8152
8153        if (!killProcess) {
8154            return;
8155        }
8156
8157        // Determine if the process(es) for this task should be killed.
8158        final String pkg = component.getPackageName();
8159        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8160        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8161        for (int i = 0; i < pmap.size(); i++) {
8162
8163            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8164            for (int j = 0; j < uids.size(); j++) {
8165                ProcessRecord proc = uids.valueAt(j);
8166                if (proc.userId != tr.userId) {
8167                    // Don't kill process for a different user.
8168                    continue;
8169                }
8170                if (proc == mHomeProcess) {
8171                    // Don't kill the home process along with tasks from the same package.
8172                    continue;
8173                }
8174                if (!proc.pkgList.containsKey(pkg)) {
8175                    // Don't kill process that is not associated with this task.
8176                    continue;
8177                }
8178
8179                for (int k = 0; k < proc.activities.size(); k++) {
8180                    TaskRecord otherTask = proc.activities.get(k).task;
8181                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8182                        // Don't kill process(es) that has an activity in a different task that is
8183                        // also in recents.
8184                        return;
8185                    }
8186                }
8187
8188                // Add process to kill list.
8189                procsToKill.add(proc);
8190            }
8191        }
8192
8193        // Find any running services associated with this app and stop if needed.
8194        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8195
8196        // Kill the running processes.
8197        for (int i = 0; i < procsToKill.size(); i++) {
8198            ProcessRecord pr = procsToKill.get(i);
8199            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8200                pr.kill("remove task", true);
8201            } else {
8202                pr.waitingToKill = "remove task";
8203            }
8204        }
8205    }
8206
8207    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8208        // Remove all tasks with activities in the specified package from the list of recent tasks
8209        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8210            TaskRecord tr = mRecentTasks.get(i);
8211            if (tr.userId != userId) continue;
8212
8213            ComponentName cn = tr.intent.getComponent();
8214            if (cn != null && cn.getPackageName().equals(packageName)) {
8215                // If the package name matches, remove the task.
8216                removeTaskByIdLocked(tr.taskId, true);
8217            }
8218        }
8219    }
8220
8221    private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) {
8222        final IPackageManager pm = AppGlobals.getPackageManager();
8223        final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
8224
8225        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8226            TaskRecord tr = mRecentTasks.get(i);
8227            if (tr.userId != userId) continue;
8228
8229            ComponentName cn = tr.intent.getComponent();
8230            if (cn != null && cn.getPackageName().equals(packageName)) {
8231                // Skip if component still exists in the package.
8232                if (componentsKnownToExist.contains(cn)) continue;
8233
8234                try {
8235                    ActivityInfo info = pm.getActivityInfo(cn, 0, userId);
8236                    if (info != null) {
8237                        componentsKnownToExist.add(cn);
8238                    } else {
8239                        removeTaskByIdLocked(tr.taskId, false);
8240                    }
8241                } catch (RemoteException e) {
8242                    Log.e(TAG, "Activity info query failed. component=" + cn, e);
8243                }
8244            }
8245        }
8246    }
8247
8248    /**
8249     * Removes the task with the specified task id.
8250     *
8251     * @param taskId Identifier of the task to be removed.
8252     * @param killProcess Kill any process associated with the task if possible.
8253     * @return Returns true if the given task was found and removed.
8254     */
8255    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8256        TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8257        if (tr != null) {
8258            tr.removeTaskActivitiesLocked();
8259            cleanUpRemovedTaskLocked(tr, killProcess);
8260            if (tr.isPersistable) {
8261                notifyTaskPersisterLocked(null, true);
8262            }
8263            return true;
8264        }
8265        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8266        return false;
8267    }
8268
8269    @Override
8270    public boolean removeTask(int taskId) {
8271        synchronized (this) {
8272            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8273                    "removeTask()");
8274            long ident = Binder.clearCallingIdentity();
8275            try {
8276                return removeTaskByIdLocked(taskId, true);
8277            } finally {
8278                Binder.restoreCallingIdentity(ident);
8279            }
8280        }
8281    }
8282
8283    /**
8284     * TODO: Add mController hook
8285     */
8286    @Override
8287    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8288        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
8289
8290        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
8291        synchronized(this) {
8292            moveTaskToFrontLocked(taskId, flags, options);
8293        }
8294    }
8295
8296    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8297        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8298                Binder.getCallingUid(), -1, -1, "Task to front")) {
8299            ActivityOptions.abort(options);
8300            return;
8301        }
8302        final long origId = Binder.clearCallingIdentity();
8303        try {
8304            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8305            if (task == null) {
8306                Slog.d(TAG, "Could not find task for id: "+ taskId);
8307                return;
8308            }
8309            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8310                mStackSupervisor.showLockTaskToast();
8311                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8312                return;
8313            }
8314            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8315            if (prev != null && prev.isRecentsActivity()) {
8316                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8317            }
8318            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
8319        } finally {
8320            Binder.restoreCallingIdentity(origId);
8321        }
8322        ActivityOptions.abort(options);
8323    }
8324
8325    /**
8326     * Moves an activity, and all of the other activities within the same task, to the bottom
8327     * of the history stack.  The activity's order within the task is unchanged.
8328     *
8329     * @param token A reference to the activity we wish to move
8330     * @param nonRoot If false then this only works if the activity is the root
8331     *                of a task; if true it will work for any activity in a task.
8332     * @return Returns true if the move completed, false if not.
8333     */
8334    @Override
8335    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8336        enforceNotIsolatedCaller("moveActivityTaskToBack");
8337        synchronized(this) {
8338            final long origId = Binder.clearCallingIdentity();
8339            try {
8340                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8341                final TaskRecord task = mRecentTasks.taskForIdLocked(taskId);
8342                if (task != null) {
8343                    if (mStackSupervisor.isLockedTask(task)) {
8344                        mStackSupervisor.showLockTaskToast();
8345                        return false;
8346                    }
8347                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
8348                }
8349            } finally {
8350                Binder.restoreCallingIdentity(origId);
8351            }
8352        }
8353        return false;
8354    }
8355
8356    @Override
8357    public void moveTaskBackwards(int task) {
8358        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8359                "moveTaskBackwards()");
8360
8361        synchronized(this) {
8362            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8363                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8364                return;
8365            }
8366            final long origId = Binder.clearCallingIdentity();
8367            moveTaskBackwardsLocked(task);
8368            Binder.restoreCallingIdentity(origId);
8369        }
8370    }
8371
8372    private final void moveTaskBackwardsLocked(int task) {
8373        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8374    }
8375
8376    @Override
8377    public IBinder getHomeActivityToken() throws RemoteException {
8378        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8379                "getHomeActivityToken()");
8380        synchronized (this) {
8381            return mStackSupervisor.getHomeActivityToken();
8382        }
8383    }
8384
8385    @Override
8386    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
8387            IActivityContainerCallback callback) throws RemoteException {
8388        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8389                "createActivityContainer()");
8390        synchronized (this) {
8391            if (parentActivityToken == null) {
8392                throw new IllegalArgumentException("parent token must not be null");
8393            }
8394            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
8395            if (r == null) {
8396                return null;
8397            }
8398            if (callback == null) {
8399                throw new IllegalArgumentException("callback must not be null");
8400            }
8401            return mStackSupervisor.createVirtualActivityContainer(r, callback);
8402        }
8403    }
8404
8405    @Override
8406    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8407        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8408                "deleteActivityContainer()");
8409        synchronized (this) {
8410            mStackSupervisor.deleteActivityContainer(container);
8411        }
8412    }
8413
8414    @Override
8415    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
8416        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8417                "createStackOnDisplay()");
8418        synchronized (this) {
8419            final int stackId = mStackSupervisor.getNextStackId();
8420            final ActivityStack stack = mStackSupervisor.createStackOnDisplay(stackId, displayId);
8421            if (stack == null) {
8422                return null;
8423            }
8424            return stack.mActivityContainer;
8425        }
8426    }
8427
8428    @Override
8429    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
8430        synchronized (this) {
8431            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8432            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
8433                return stack.mActivityContainer.getDisplayId();
8434            }
8435            return Display.DEFAULT_DISPLAY;
8436        }
8437    }
8438
8439    @Override
8440    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8441        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8442                "moveTaskToStack()");
8443        if (stackId == HOME_STACK_ID) {
8444            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8445                    new RuntimeException("here").fillInStackTrace());
8446        }
8447        synchronized (this) {
8448            long ident = Binder.clearCallingIdentity();
8449            try {
8450                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
8451                        + " to stackId=" + stackId + " toTop=" + toTop);
8452                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop);
8453            } finally {
8454                Binder.restoreCallingIdentity(ident);
8455            }
8456        }
8457    }
8458
8459    @Override
8460    public void resizeStack(int stackId, Rect bounds) {
8461        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8462                "resizeStack()");
8463        long ident = Binder.clearCallingIdentity();
8464        try {
8465            synchronized (this) {
8466                mStackSupervisor.resizeStackLocked(stackId, bounds);
8467            }
8468        } finally {
8469            Binder.restoreCallingIdentity(ident);
8470        }
8471    }
8472
8473    @Override
8474    public List<StackInfo> getAllStackInfos() {
8475        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8476                "getAllStackInfos()");
8477        long ident = Binder.clearCallingIdentity();
8478        try {
8479            synchronized (this) {
8480                return mStackSupervisor.getAllStackInfosLocked();
8481            }
8482        } finally {
8483            Binder.restoreCallingIdentity(ident);
8484        }
8485    }
8486
8487    @Override
8488    public StackInfo getStackInfo(int stackId) {
8489        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8490                "getStackInfo()");
8491        long ident = Binder.clearCallingIdentity();
8492        try {
8493            synchronized (this) {
8494                return mStackSupervisor.getStackInfoLocked(stackId);
8495            }
8496        } finally {
8497            Binder.restoreCallingIdentity(ident);
8498        }
8499    }
8500
8501    @Override
8502    public boolean isInHomeStack(int taskId) {
8503        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8504                "getStackInfo()");
8505        long ident = Binder.clearCallingIdentity();
8506        try {
8507            synchronized (this) {
8508                TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8509                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8510            }
8511        } finally {
8512            Binder.restoreCallingIdentity(ident);
8513        }
8514    }
8515
8516    @Override
8517    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8518        synchronized(this) {
8519            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8520        }
8521    }
8522
8523    @Override
8524    public void updateLockTaskPackages(int userId, String[] packages) {
8525        final int callingUid = Binder.getCallingUid();
8526        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
8527            throw new SecurityException("updateLockTaskPackage called from non-system process");
8528        }
8529        synchronized (this) {
8530            mLockTaskPackages.put(userId, packages);
8531            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
8532        }
8533    }
8534
8535
8536    void startLockTaskModeLocked(TaskRecord task) {
8537        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
8538            return;
8539        }
8540
8541        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
8542        // is initiated by system after the pinning request was shown and locked mode is initiated
8543        // by an authorized app directly
8544        final int callingUid = Binder.getCallingUid();
8545        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
8546        long ident = Binder.clearCallingIdentity();
8547        try {
8548            final ActivityStack stack = mStackSupervisor.getFocusedStack();
8549            if (!isSystemInitiated) {
8550                task.mLockTaskUid = callingUid;
8551                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
8552                    // startLockTask() called by app and task mode is lockTaskModeDefault.
8553                    StatusBarManagerInternal statusBarManager =
8554                            LocalServices.getService(StatusBarManagerInternal.class);
8555                    if (statusBarManager != null) {
8556                        statusBarManager.showScreenPinningRequest();
8557                    }
8558                    return;
8559                }
8560
8561                if (stack == null || task != stack.topTask()) {
8562                    throw new IllegalArgumentException("Invalid task, not in foreground");
8563                }
8564            }
8565            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
8566                    ActivityManager.LOCK_TASK_MODE_PINNED :
8567                    ActivityManager.LOCK_TASK_MODE_LOCKED,
8568                    "startLockTask");
8569        } finally {
8570            Binder.restoreCallingIdentity(ident);
8571        }
8572    }
8573
8574    @Override
8575    public void startLockTaskMode(int taskId) {
8576        synchronized (this) {
8577            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8578            if (task != null) {
8579                startLockTaskModeLocked(task);
8580            }
8581        }
8582    }
8583
8584    @Override
8585    public void startLockTaskMode(IBinder token) {
8586        synchronized (this) {
8587            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8588            if (r == null) {
8589                return;
8590            }
8591            final TaskRecord task = r.task;
8592            if (task != null) {
8593                startLockTaskModeLocked(task);
8594            }
8595        }
8596    }
8597
8598    @Override
8599    public void startLockTaskModeOnCurrent() throws RemoteException {
8600        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8601                "startLockTaskModeOnCurrent");
8602        long ident = Binder.clearCallingIdentity();
8603        try {
8604            synchronized (this) {
8605                ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
8606                if (r != null) {
8607                    startLockTaskModeLocked(r.task);
8608                }
8609            }
8610        } finally {
8611            Binder.restoreCallingIdentity(ident);
8612        }
8613    }
8614
8615    @Override
8616    public void stopLockTaskMode() {
8617        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
8618        if (lockTask == null) {
8619            // Our work here is done.
8620            return;
8621        }
8622        // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
8623        if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
8624                Binder.getCallingUid() != lockTask.mLockTaskUid) {
8625            throw new SecurityException("Invalid uid, expected " + lockTask.mLockTaskUid);
8626        }
8627        long ident = Binder.clearCallingIdentity();
8628        try {
8629            Log.d(TAG, "stopLockTaskMode");
8630            // Stop lock task
8631            synchronized (this) {
8632                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
8633                        "stopLockTask");
8634            }
8635        } finally {
8636            Binder.restoreCallingIdentity(ident);
8637        }
8638    }
8639
8640    @Override
8641    public void stopLockTaskModeOnCurrent() throws RemoteException {
8642        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8643                "stopLockTaskModeOnCurrent");
8644        long ident = Binder.clearCallingIdentity();
8645        try {
8646            stopLockTaskMode();
8647        } finally {
8648            Binder.restoreCallingIdentity(ident);
8649        }
8650    }
8651
8652    @Override
8653    public boolean isInLockTaskMode() {
8654        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
8655    }
8656
8657    @Override
8658    public int getLockTaskModeState() {
8659        synchronized (this) {
8660            return mStackSupervisor.getLockTaskModeState();
8661        }
8662    }
8663
8664    // =========================================================
8665    // CONTENT PROVIDERS
8666    // =========================================================
8667
8668    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8669        List<ProviderInfo> providers = null;
8670        try {
8671            providers = AppGlobals.getPackageManager().
8672                queryContentProviders(app.processName, app.uid,
8673                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8674        } catch (RemoteException ex) {
8675        }
8676        if (DEBUG_MU) Slog.v(TAG_MU,
8677                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8678        int userId = app.userId;
8679        if (providers != null) {
8680            int N = providers.size();
8681            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8682            for (int i=0; i<N; i++) {
8683                ProviderInfo cpi =
8684                    (ProviderInfo)providers.get(i);
8685                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8686                        cpi.name, cpi.flags);
8687                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_OWNER) {
8688                    // This is a singleton provider, but a user besides the
8689                    // default user is asking to initialize a process it runs
8690                    // in...  well, no, it doesn't actually run in this process,
8691                    // it runs in the process of the default user.  Get rid of it.
8692                    providers.remove(i);
8693                    N--;
8694                    i--;
8695                    continue;
8696                }
8697
8698                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8699                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8700                if (cpr == null) {
8701                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8702                    mProviderMap.putProviderByClass(comp, cpr);
8703                }
8704                if (DEBUG_MU) Slog.v(TAG_MU,
8705                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8706                app.pubProviders.put(cpi.name, cpr);
8707                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8708                    // Don't add this if it is a platform component that is marked
8709                    // to run in multiple processes, because this is actually
8710                    // part of the framework so doesn't make sense to track as a
8711                    // separate apk in the process.
8712                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8713                            mProcessStats);
8714                }
8715                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8716            }
8717        }
8718        return providers;
8719    }
8720
8721    /**
8722     * Check if {@link ProcessRecord} has a possible chance at accessing the
8723     * given {@link ProviderInfo}. Final permission checking is always done
8724     * in {@link ContentProvider}.
8725     */
8726    private final String checkContentProviderPermissionLocked(
8727            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8728        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8729        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8730        boolean checkedGrants = false;
8731        if (checkUser) {
8732            // Looking for cross-user grants before enforcing the typical cross-users permissions
8733            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8734            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8735                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8736                    return null;
8737                }
8738                checkedGrants = true;
8739            }
8740            userId = handleIncomingUser(callingPid, callingUid, userId,
8741                    false, ALLOW_NON_FULL,
8742                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8743            if (userId != tmpTargetUserId) {
8744                // When we actually went to determine the final targer user ID, this ended
8745                // up different than our initial check for the authority.  This is because
8746                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8747                // SELF.  So we need to re-check the grants again.
8748                checkedGrants = false;
8749            }
8750        }
8751        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8752                cpi.applicationInfo.uid, cpi.exported)
8753                == PackageManager.PERMISSION_GRANTED) {
8754            return null;
8755        }
8756        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8757                cpi.applicationInfo.uid, cpi.exported)
8758                == PackageManager.PERMISSION_GRANTED) {
8759            return null;
8760        }
8761
8762        PathPermission[] pps = cpi.pathPermissions;
8763        if (pps != null) {
8764            int i = pps.length;
8765            while (i > 0) {
8766                i--;
8767                PathPermission pp = pps[i];
8768                String pprperm = pp.getReadPermission();
8769                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8770                        cpi.applicationInfo.uid, cpi.exported)
8771                        == PackageManager.PERMISSION_GRANTED) {
8772                    return null;
8773                }
8774                String ppwperm = pp.getWritePermission();
8775                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8776                        cpi.applicationInfo.uid, cpi.exported)
8777                        == PackageManager.PERMISSION_GRANTED) {
8778                    return null;
8779                }
8780            }
8781        }
8782        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8783            return null;
8784        }
8785
8786        String msg;
8787        if (!cpi.exported) {
8788            msg = "Permission Denial: opening provider " + cpi.name
8789                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8790                    + ", uid=" + callingUid + ") that is not exported from uid "
8791                    + cpi.applicationInfo.uid;
8792        } else {
8793            msg = "Permission Denial: opening provider " + cpi.name
8794                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8795                    + ", uid=" + callingUid + ") requires "
8796                    + cpi.readPermission + " or " + cpi.writePermission;
8797        }
8798        Slog.w(TAG, msg);
8799        return msg;
8800    }
8801
8802    /**
8803     * Returns if the ContentProvider has granted a uri to callingUid
8804     */
8805    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8806        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8807        if (perms != null) {
8808            for (int i=perms.size()-1; i>=0; i--) {
8809                GrantUri grantUri = perms.keyAt(i);
8810                if (grantUri.sourceUserId == userId || !checkUser) {
8811                    if (matchesProvider(grantUri.uri, cpi)) {
8812                        return true;
8813                    }
8814                }
8815            }
8816        }
8817        return false;
8818    }
8819
8820    /**
8821     * Returns true if the uri authority is one of the authorities specified in the provider.
8822     */
8823    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8824        String uriAuth = uri.getAuthority();
8825        String cpiAuth = cpi.authority;
8826        if (cpiAuth.indexOf(';') == -1) {
8827            return cpiAuth.equals(uriAuth);
8828        }
8829        String[] cpiAuths = cpiAuth.split(";");
8830        int length = cpiAuths.length;
8831        for (int i = 0; i < length; i++) {
8832            if (cpiAuths[i].equals(uriAuth)) return true;
8833        }
8834        return false;
8835    }
8836
8837    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8838            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8839        if (r != null) {
8840            for (int i=0; i<r.conProviders.size(); i++) {
8841                ContentProviderConnection conn = r.conProviders.get(i);
8842                if (conn.provider == cpr) {
8843                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
8844                            "Adding provider requested by "
8845                            + r.processName + " from process "
8846                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8847                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8848                    if (stable) {
8849                        conn.stableCount++;
8850                        conn.numStableIncs++;
8851                    } else {
8852                        conn.unstableCount++;
8853                        conn.numUnstableIncs++;
8854                    }
8855                    return conn;
8856                }
8857            }
8858            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8859            if (stable) {
8860                conn.stableCount = 1;
8861                conn.numStableIncs = 1;
8862            } else {
8863                conn.unstableCount = 1;
8864                conn.numUnstableIncs = 1;
8865            }
8866            cpr.connections.add(conn);
8867            r.conProviders.add(conn);
8868            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
8869            return conn;
8870        }
8871        cpr.addExternalProcessHandleLocked(externalProcessToken);
8872        return null;
8873    }
8874
8875    boolean decProviderCountLocked(ContentProviderConnection conn,
8876            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8877        if (conn != null) {
8878            cpr = conn.provider;
8879            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
8880                    "Removing provider requested by "
8881                    + conn.client.processName + " from process "
8882                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8883                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8884            if (stable) {
8885                conn.stableCount--;
8886            } else {
8887                conn.unstableCount--;
8888            }
8889            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8890                cpr.connections.remove(conn);
8891                conn.client.conProviders.remove(conn);
8892                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
8893                return true;
8894            }
8895            return false;
8896        }
8897        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8898        return false;
8899    }
8900
8901    private void checkTime(long startTime, String where) {
8902        long now = SystemClock.elapsedRealtime();
8903        if ((now-startTime) > 1000) {
8904            // If we are taking more than a second, log about it.
8905            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
8906        }
8907    }
8908
8909    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8910            String name, IBinder token, boolean stable, int userId) {
8911        ContentProviderRecord cpr;
8912        ContentProviderConnection conn = null;
8913        ProviderInfo cpi = null;
8914
8915        synchronized(this) {
8916            long startTime = SystemClock.elapsedRealtime();
8917
8918            ProcessRecord r = null;
8919            if (caller != null) {
8920                r = getRecordForAppLocked(caller);
8921                if (r == null) {
8922                    throw new SecurityException(
8923                            "Unable to find app for caller " + caller
8924                          + " (pid=" + Binder.getCallingPid()
8925                          + ") when getting content provider " + name);
8926                }
8927            }
8928
8929            boolean checkCrossUser = true;
8930
8931            checkTime(startTime, "getContentProviderImpl: getProviderByName");
8932
8933            // First check if this content provider has been published...
8934            cpr = mProviderMap.getProviderByName(name, userId);
8935            // If that didn't work, check if it exists for user 0 and then
8936            // verify that it's a singleton provider before using it.
8937            if (cpr == null && userId != UserHandle.USER_OWNER) {
8938                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8939                if (cpr != null) {
8940                    cpi = cpr.info;
8941                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8942                            cpi.name, cpi.flags)
8943                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8944                        userId = UserHandle.USER_OWNER;
8945                        checkCrossUser = false;
8946                    } else {
8947                        cpr = null;
8948                        cpi = null;
8949                    }
8950                }
8951            }
8952
8953            boolean providerRunning = cpr != null;
8954            if (providerRunning) {
8955                cpi = cpr.info;
8956                String msg;
8957                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
8958                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8959                        != null) {
8960                    throw new SecurityException(msg);
8961                }
8962                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
8963
8964                if (r != null && cpr.canRunHere(r)) {
8965                    // This provider has been published or is in the process
8966                    // of being published...  but it is also allowed to run
8967                    // in the caller's process, so don't make a connection
8968                    // and just let the caller instantiate its own instance.
8969                    ContentProviderHolder holder = cpr.newHolder(null);
8970                    // don't give caller the provider object, it needs
8971                    // to make its own.
8972                    holder.provider = null;
8973                    return holder;
8974                }
8975
8976                final long origId = Binder.clearCallingIdentity();
8977
8978                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
8979
8980                // In this case the provider instance already exists, so we can
8981                // return it right away.
8982                conn = incProviderCountLocked(r, cpr, token, stable);
8983                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8984                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8985                        // If this is a perceptible app accessing the provider,
8986                        // make sure to count it as being accessed and thus
8987                        // back up on the LRU list.  This is good because
8988                        // content providers are often expensive to start.
8989                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
8990                        updateLruProcessLocked(cpr.proc, false, null);
8991                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
8992                    }
8993                }
8994
8995                if (cpr.proc != null) {
8996                    if (false) {
8997                        if (cpr.name.flattenToShortString().equals(
8998                                "com.android.providers.calendar/.CalendarProvider2")) {
8999                            Slog.v(TAG, "****************** KILLING "
9000                                + cpr.name.flattenToShortString());
9001                            Process.killProcess(cpr.proc.pid);
9002                        }
9003                    }
9004                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9005                    boolean success = updateOomAdjLocked(cpr.proc);
9006                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9007                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
9008                    // NOTE: there is still a race here where a signal could be
9009                    // pending on the process even though we managed to update its
9010                    // adj level.  Not sure what to do about this, but at least
9011                    // the race is now smaller.
9012                    if (!success) {
9013                        // Uh oh...  it looks like the provider's process
9014                        // has been killed on us.  We need to wait for a new
9015                        // process to be started, and make sure its death
9016                        // doesn't kill our process.
9017                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
9018                                + " is crashing; detaching " + r);
9019                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9020                        checkTime(startTime, "getContentProviderImpl: before appDied");
9021                        appDiedLocked(cpr.proc);
9022                        checkTime(startTime, "getContentProviderImpl: after appDied");
9023                        if (!lastRef) {
9024                            // This wasn't the last ref our process had on
9025                            // the provider...  we have now been killed, bail.
9026                            return null;
9027                        }
9028                        providerRunning = false;
9029                        conn = null;
9030                    }
9031                }
9032
9033                Binder.restoreCallingIdentity(origId);
9034            }
9035
9036            boolean singleton;
9037            if (!providerRunning) {
9038                try {
9039                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9040                    cpi = AppGlobals.getPackageManager().
9041                        resolveContentProvider(name,
9042                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9043                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9044                } catch (RemoteException ex) {
9045                }
9046                if (cpi == null) {
9047                    return null;
9048                }
9049                // If the provider is a singleton AND
9050                // (it's a call within the same user || the provider is a
9051                // privileged app)
9052                // Then allow connecting to the singleton provider
9053                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9054                        cpi.name, cpi.flags)
9055                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9056                if (singleton) {
9057                    userId = UserHandle.USER_OWNER;
9058                }
9059                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9060                checkTime(startTime, "getContentProviderImpl: got app info for user");
9061
9062                String msg;
9063                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9064                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9065                        != null) {
9066                    throw new SecurityException(msg);
9067                }
9068                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9069
9070                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9071                        && !cpi.processName.equals("system")) {
9072                    // If this content provider does not run in the system
9073                    // process, and the system is not yet ready to run other
9074                    // processes, then fail fast instead of hanging.
9075                    throw new IllegalArgumentException(
9076                            "Attempt to launch content provider before system ready");
9077                }
9078
9079                // Make sure that the user who owns this provider is running.  If not,
9080                // we don't want to allow it to run.
9081                if (!isUserRunningLocked(userId, false)) {
9082                    Slog.w(TAG, "Unable to launch app "
9083                            + cpi.applicationInfo.packageName + "/"
9084                            + cpi.applicationInfo.uid + " for provider "
9085                            + name + ": user " + userId + " is stopped");
9086                    return null;
9087                }
9088
9089                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9090                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9091                cpr = mProviderMap.getProviderByClass(comp, userId);
9092                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9093                final boolean firstClass = cpr == null;
9094                if (firstClass) {
9095                    final long ident = Binder.clearCallingIdentity();
9096                    try {
9097                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9098                        ApplicationInfo ai =
9099                            AppGlobals.getPackageManager().
9100                                getApplicationInfo(
9101                                        cpi.applicationInfo.packageName,
9102                                        STOCK_PM_FLAGS, userId);
9103                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9104                        if (ai == null) {
9105                            Slog.w(TAG, "No package info for content provider "
9106                                    + cpi.name);
9107                            return null;
9108                        }
9109                        ai = getAppInfoForUser(ai, userId);
9110                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9111                    } catch (RemoteException ex) {
9112                        // pm is in same process, this will never happen.
9113                    } finally {
9114                        Binder.restoreCallingIdentity(ident);
9115                    }
9116                }
9117
9118                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9119
9120                if (r != null && cpr.canRunHere(r)) {
9121                    // If this is a multiprocess provider, then just return its
9122                    // info and allow the caller to instantiate it.  Only do
9123                    // this if the provider is the same user as the caller's
9124                    // process, or can run as root (so can be in any process).
9125                    return cpr.newHolder(null);
9126                }
9127
9128                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
9129                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
9130                            + cpr.info.name + " callers=" + Debug.getCallers(6));
9131
9132                // This is single process, and our app is now connecting to it.
9133                // See if we are already in the process of launching this
9134                // provider.
9135                final int N = mLaunchingProviders.size();
9136                int i;
9137                for (i = 0; i < N; i++) {
9138                    if (mLaunchingProviders.get(i) == cpr) {
9139                        break;
9140                    }
9141                }
9142
9143                // If the provider is not already being launched, then get it
9144                // started.
9145                if (i >= N) {
9146                    final long origId = Binder.clearCallingIdentity();
9147
9148                    try {
9149                        // Content provider is now in use, its package can't be stopped.
9150                        try {
9151                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9152                            AppGlobals.getPackageManager().setPackageStoppedState(
9153                                    cpr.appInfo.packageName, false, userId);
9154                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9155                        } catch (RemoteException e) {
9156                        } catch (IllegalArgumentException e) {
9157                            Slog.w(TAG, "Failed trying to unstop package "
9158                                    + cpr.appInfo.packageName + ": " + e);
9159                        }
9160
9161                        // Use existing process if already started
9162                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9163                        ProcessRecord proc = getProcessRecordLocked(
9164                                cpi.processName, cpr.appInfo.uid, false);
9165                        if (proc != null && proc.thread != null) {
9166                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
9167                                    "Installing in existing process " + proc);
9168                            if (!proc.pubProviders.containsKey(cpi.name)) {
9169                                checkTime(startTime, "getContentProviderImpl: scheduling install");
9170                                proc.pubProviders.put(cpi.name, cpr);
9171                                try {
9172                                    proc.thread.scheduleInstallProvider(cpi);
9173                                } catch (RemoteException e) {
9174                                }
9175                            }
9176                        } else {
9177                            checkTime(startTime, "getContentProviderImpl: before start process");
9178                            proc = startProcessLocked(cpi.processName,
9179                                    cpr.appInfo, false, 0, "content provider",
9180                                    new ComponentName(cpi.applicationInfo.packageName,
9181                                            cpi.name), false, false, false);
9182                            checkTime(startTime, "getContentProviderImpl: after start process");
9183                            if (proc == null) {
9184                                Slog.w(TAG, "Unable to launch app "
9185                                        + cpi.applicationInfo.packageName + "/"
9186                                        + cpi.applicationInfo.uid + " for provider "
9187                                        + name + ": process is bad");
9188                                return null;
9189                            }
9190                        }
9191                        cpr.launchingApp = proc;
9192                        mLaunchingProviders.add(cpr);
9193                    } finally {
9194                        Binder.restoreCallingIdentity(origId);
9195                    }
9196                }
9197
9198                checkTime(startTime, "getContentProviderImpl: updating data structures");
9199
9200                // Make sure the provider is published (the same provider class
9201                // may be published under multiple names).
9202                if (firstClass) {
9203                    mProviderMap.putProviderByClass(comp, cpr);
9204                }
9205
9206                mProviderMap.putProviderByName(name, cpr);
9207                conn = incProviderCountLocked(r, cpr, token, stable);
9208                if (conn != null) {
9209                    conn.waiting = true;
9210                }
9211            }
9212            checkTime(startTime, "getContentProviderImpl: done!");
9213        }
9214
9215        // Wait for the provider to be published...
9216        synchronized (cpr) {
9217            while (cpr.provider == null) {
9218                if (cpr.launchingApp == null) {
9219                    Slog.w(TAG, "Unable to launch app "
9220                            + cpi.applicationInfo.packageName + "/"
9221                            + cpi.applicationInfo.uid + " for provider "
9222                            + name + ": launching app became null");
9223                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9224                            UserHandle.getUserId(cpi.applicationInfo.uid),
9225                            cpi.applicationInfo.packageName,
9226                            cpi.applicationInfo.uid, name);
9227                    return null;
9228                }
9229                try {
9230                    if (DEBUG_MU) Slog.v(TAG_MU,
9231                            "Waiting to start provider " + cpr
9232                            + " launchingApp=" + cpr.launchingApp);
9233                    if (conn != null) {
9234                        conn.waiting = true;
9235                    }
9236                    cpr.wait();
9237                } catch (InterruptedException ex) {
9238                } finally {
9239                    if (conn != null) {
9240                        conn.waiting = false;
9241                    }
9242                }
9243            }
9244        }
9245        return cpr != null ? cpr.newHolder(conn) : null;
9246    }
9247
9248    @Override
9249    public final ContentProviderHolder getContentProvider(
9250            IApplicationThread caller, String name, int userId, boolean stable) {
9251        enforceNotIsolatedCaller("getContentProvider");
9252        if (caller == null) {
9253            String msg = "null IApplicationThread when getting content provider "
9254                    + name;
9255            Slog.w(TAG, msg);
9256            throw new SecurityException(msg);
9257        }
9258        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9259        // with cross-user grant.
9260        return getContentProviderImpl(caller, name, null, stable, userId);
9261    }
9262
9263    public ContentProviderHolder getContentProviderExternal(
9264            String name, int userId, IBinder token) {
9265        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9266            "Do not have permission in call getContentProviderExternal()");
9267        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9268                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9269        return getContentProviderExternalUnchecked(name, token, userId);
9270    }
9271
9272    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9273            IBinder token, int userId) {
9274        return getContentProviderImpl(null, name, token, true, userId);
9275    }
9276
9277    /**
9278     * Drop a content provider from a ProcessRecord's bookkeeping
9279     */
9280    public void removeContentProvider(IBinder connection, boolean stable) {
9281        enforceNotIsolatedCaller("removeContentProvider");
9282        long ident = Binder.clearCallingIdentity();
9283        try {
9284            synchronized (this) {
9285                ContentProviderConnection conn;
9286                try {
9287                    conn = (ContentProviderConnection)connection;
9288                } catch (ClassCastException e) {
9289                    String msg ="removeContentProvider: " + connection
9290                            + " not a ContentProviderConnection";
9291                    Slog.w(TAG, msg);
9292                    throw new IllegalArgumentException(msg);
9293                }
9294                if (conn == null) {
9295                    throw new NullPointerException("connection is null");
9296                }
9297                if (decProviderCountLocked(conn, null, null, stable)) {
9298                    updateOomAdjLocked();
9299                }
9300            }
9301        } finally {
9302            Binder.restoreCallingIdentity(ident);
9303        }
9304    }
9305
9306    public void removeContentProviderExternal(String name, IBinder token) {
9307        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9308            "Do not have permission in call removeContentProviderExternal()");
9309        int userId = UserHandle.getCallingUserId();
9310        long ident = Binder.clearCallingIdentity();
9311        try {
9312            removeContentProviderExternalUnchecked(name, token, userId);
9313        } finally {
9314            Binder.restoreCallingIdentity(ident);
9315        }
9316    }
9317
9318    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9319        synchronized (this) {
9320            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9321            if(cpr == null) {
9322                //remove from mProvidersByClass
9323                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
9324                return;
9325            }
9326
9327            //update content provider record entry info
9328            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9329            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9330            if (localCpr.hasExternalProcessHandles()) {
9331                if (localCpr.removeExternalProcessHandleLocked(token)) {
9332                    updateOomAdjLocked();
9333                } else {
9334                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9335                            + " with no external reference for token: "
9336                            + token + ".");
9337                }
9338            } else {
9339                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9340                        + " with no external references.");
9341            }
9342        }
9343    }
9344
9345    public final void publishContentProviders(IApplicationThread caller,
9346            List<ContentProviderHolder> providers) {
9347        if (providers == null) {
9348            return;
9349        }
9350
9351        enforceNotIsolatedCaller("publishContentProviders");
9352        synchronized (this) {
9353            final ProcessRecord r = getRecordForAppLocked(caller);
9354            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9355            if (r == null) {
9356                throw new SecurityException(
9357                        "Unable to find app for caller " + caller
9358                      + " (pid=" + Binder.getCallingPid()
9359                      + ") when publishing content providers");
9360            }
9361
9362            final long origId = Binder.clearCallingIdentity();
9363
9364            final int N = providers.size();
9365            for (int i=0; i<N; i++) {
9366                ContentProviderHolder src = providers.get(i);
9367                if (src == null || src.info == null || src.provider == null) {
9368                    continue;
9369                }
9370                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9371                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9372                if (dst != null) {
9373                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9374                    mProviderMap.putProviderByClass(comp, dst);
9375                    String names[] = dst.info.authority.split(";");
9376                    for (int j = 0; j < names.length; j++) {
9377                        mProviderMap.putProviderByName(names[j], dst);
9378                    }
9379
9380                    int NL = mLaunchingProviders.size();
9381                    int j;
9382                    for (j=0; j<NL; j++) {
9383                        if (mLaunchingProviders.get(j) == dst) {
9384                            mLaunchingProviders.remove(j);
9385                            j--;
9386                            NL--;
9387                        }
9388                    }
9389                    synchronized (dst) {
9390                        dst.provider = src.provider;
9391                        dst.proc = r;
9392                        dst.notifyAll();
9393                    }
9394                    updateOomAdjLocked(r);
9395                }
9396            }
9397
9398            Binder.restoreCallingIdentity(origId);
9399        }
9400    }
9401
9402    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9403        ContentProviderConnection conn;
9404        try {
9405            conn = (ContentProviderConnection)connection;
9406        } catch (ClassCastException e) {
9407            String msg ="refContentProvider: " + connection
9408                    + " not a ContentProviderConnection";
9409            Slog.w(TAG, msg);
9410            throw new IllegalArgumentException(msg);
9411        }
9412        if (conn == null) {
9413            throw new NullPointerException("connection is null");
9414        }
9415
9416        synchronized (this) {
9417            if (stable > 0) {
9418                conn.numStableIncs += stable;
9419            }
9420            stable = conn.stableCount + stable;
9421            if (stable < 0) {
9422                throw new IllegalStateException("stableCount < 0: " + stable);
9423            }
9424
9425            if (unstable > 0) {
9426                conn.numUnstableIncs += unstable;
9427            }
9428            unstable = conn.unstableCount + unstable;
9429            if (unstable < 0) {
9430                throw new IllegalStateException("unstableCount < 0: " + unstable);
9431            }
9432
9433            if ((stable+unstable) <= 0) {
9434                throw new IllegalStateException("ref counts can't go to zero here: stable="
9435                        + stable + " unstable=" + unstable);
9436            }
9437            conn.stableCount = stable;
9438            conn.unstableCount = unstable;
9439            return !conn.dead;
9440        }
9441    }
9442
9443    public void unstableProviderDied(IBinder connection) {
9444        ContentProviderConnection conn;
9445        try {
9446            conn = (ContentProviderConnection)connection;
9447        } catch (ClassCastException e) {
9448            String msg ="refContentProvider: " + connection
9449                    + " not a ContentProviderConnection";
9450            Slog.w(TAG, msg);
9451            throw new IllegalArgumentException(msg);
9452        }
9453        if (conn == null) {
9454            throw new NullPointerException("connection is null");
9455        }
9456
9457        // Safely retrieve the content provider associated with the connection.
9458        IContentProvider provider;
9459        synchronized (this) {
9460            provider = conn.provider.provider;
9461        }
9462
9463        if (provider == null) {
9464            // Um, yeah, we're way ahead of you.
9465            return;
9466        }
9467
9468        // Make sure the caller is being honest with us.
9469        if (provider.asBinder().pingBinder()) {
9470            // Er, no, still looks good to us.
9471            synchronized (this) {
9472                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9473                        + " says " + conn + " died, but we don't agree");
9474                return;
9475            }
9476        }
9477
9478        // Well look at that!  It's dead!
9479        synchronized (this) {
9480            if (conn.provider.provider != provider) {
9481                // But something changed...  good enough.
9482                return;
9483            }
9484
9485            ProcessRecord proc = conn.provider.proc;
9486            if (proc == null || proc.thread == null) {
9487                // Seems like the process is already cleaned up.
9488                return;
9489            }
9490
9491            // As far as we're concerned, this is just like receiving a
9492            // death notification...  just a bit prematurely.
9493            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9494                    + ") early provider death");
9495            final long ident = Binder.clearCallingIdentity();
9496            try {
9497                appDiedLocked(proc);
9498            } finally {
9499                Binder.restoreCallingIdentity(ident);
9500            }
9501        }
9502    }
9503
9504    @Override
9505    public void appNotRespondingViaProvider(IBinder connection) {
9506        enforceCallingPermission(
9507                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9508
9509        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9510        if (conn == null) {
9511            Slog.w(TAG, "ContentProviderConnection is null");
9512            return;
9513        }
9514
9515        final ProcessRecord host = conn.provider.proc;
9516        if (host == null) {
9517            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9518            return;
9519        }
9520
9521        final long token = Binder.clearCallingIdentity();
9522        try {
9523            appNotResponding(host, null, null, false, "ContentProvider not responding");
9524        } finally {
9525            Binder.restoreCallingIdentity(token);
9526        }
9527    }
9528
9529    public final void installSystemProviders() {
9530        List<ProviderInfo> providers;
9531        synchronized (this) {
9532            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9533            providers = generateApplicationProvidersLocked(app);
9534            if (providers != null) {
9535                for (int i=providers.size()-1; i>=0; i--) {
9536                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9537                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9538                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9539                                + ": not system .apk");
9540                        providers.remove(i);
9541                    }
9542                }
9543            }
9544        }
9545        if (providers != null) {
9546            mSystemThread.installSystemProviders(providers);
9547        }
9548
9549        mCoreSettingsObserver = new CoreSettingsObserver(this);
9550
9551        //mUsageStatsService.monitorPackages();
9552    }
9553
9554    /**
9555     * Allows apps to retrieve the MIME type of a URI.
9556     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9557     * users, then it does not need permission to access the ContentProvider.
9558     * Either, it needs cross-user uri grants.
9559     *
9560     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9561     *
9562     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9563     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9564     */
9565    public String getProviderMimeType(Uri uri, int userId) {
9566        enforceNotIsolatedCaller("getProviderMimeType");
9567        final String name = uri.getAuthority();
9568        int callingUid = Binder.getCallingUid();
9569        int callingPid = Binder.getCallingPid();
9570        long ident = 0;
9571        boolean clearedIdentity = false;
9572        userId = unsafeConvertIncomingUser(userId);
9573        if (canClearIdentity(callingPid, callingUid, userId)) {
9574            clearedIdentity = true;
9575            ident = Binder.clearCallingIdentity();
9576        }
9577        ContentProviderHolder holder = null;
9578        try {
9579            holder = getContentProviderExternalUnchecked(name, null, userId);
9580            if (holder != null) {
9581                return holder.provider.getType(uri);
9582            }
9583        } catch (RemoteException e) {
9584            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9585            return null;
9586        } finally {
9587            // We need to clear the identity to call removeContentProviderExternalUnchecked
9588            if (!clearedIdentity) {
9589                ident = Binder.clearCallingIdentity();
9590            }
9591            try {
9592                if (holder != null) {
9593                    removeContentProviderExternalUnchecked(name, null, userId);
9594                }
9595            } finally {
9596                Binder.restoreCallingIdentity(ident);
9597            }
9598        }
9599
9600        return null;
9601    }
9602
9603    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9604        if (UserHandle.getUserId(callingUid) == userId) {
9605            return true;
9606        }
9607        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9608                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9609                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9610                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9611                return true;
9612        }
9613        return false;
9614    }
9615
9616    // =========================================================
9617    // GLOBAL MANAGEMENT
9618    // =========================================================
9619
9620    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9621            boolean isolated, int isolatedUid) {
9622        String proc = customProcess != null ? customProcess : info.processName;
9623        BatteryStatsImpl.Uid.Proc ps = null;
9624        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9625        int uid = info.uid;
9626        if (isolated) {
9627            if (isolatedUid == 0) {
9628                int userId = UserHandle.getUserId(uid);
9629                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9630                while (true) {
9631                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9632                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9633                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9634                    }
9635                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9636                    mNextIsolatedProcessUid++;
9637                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9638                        // No process for this uid, use it.
9639                        break;
9640                    }
9641                    stepsLeft--;
9642                    if (stepsLeft <= 0) {
9643                        return null;
9644                    }
9645                }
9646            } else {
9647                // Special case for startIsolatedProcess (internal only), where
9648                // the uid of the isolated process is specified by the caller.
9649                uid = isolatedUid;
9650            }
9651        }
9652        return new ProcessRecord(stats, info, proc, uid);
9653    }
9654
9655    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9656            String abiOverride) {
9657        ProcessRecord app;
9658        if (!isolated) {
9659            app = getProcessRecordLocked(info.processName, info.uid, true);
9660        } else {
9661            app = null;
9662        }
9663
9664        if (app == null) {
9665            app = newProcessRecordLocked(info, null, isolated, 0);
9666            mProcessNames.put(info.processName, app.uid, app);
9667            if (isolated) {
9668                mIsolatedProcesses.put(app.uid, app);
9669            }
9670            updateLruProcessLocked(app, false, null);
9671            updateOomAdjLocked();
9672        }
9673
9674        // This package really, really can not be stopped.
9675        try {
9676            AppGlobals.getPackageManager().setPackageStoppedState(
9677                    info.packageName, false, UserHandle.getUserId(app.uid));
9678        } catch (RemoteException e) {
9679        } catch (IllegalArgumentException e) {
9680            Slog.w(TAG, "Failed trying to unstop package "
9681                    + info.packageName + ": " + e);
9682        }
9683
9684        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9685                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9686            app.persistent = true;
9687            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9688        }
9689        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9690            mPersistentStartingProcesses.add(app);
9691            startProcessLocked(app, "added application", app.processName, abiOverride,
9692                    null /* entryPoint */, null /* entryPointArgs */);
9693        }
9694
9695        return app;
9696    }
9697
9698    public void unhandledBack() {
9699        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9700                "unhandledBack()");
9701
9702        synchronized(this) {
9703            final long origId = Binder.clearCallingIdentity();
9704            try {
9705                getFocusedStack().unhandledBackLocked();
9706            } finally {
9707                Binder.restoreCallingIdentity(origId);
9708            }
9709        }
9710    }
9711
9712    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9713        enforceNotIsolatedCaller("openContentUri");
9714        final int userId = UserHandle.getCallingUserId();
9715        String name = uri.getAuthority();
9716        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9717        ParcelFileDescriptor pfd = null;
9718        if (cph != null) {
9719            // We record the binder invoker's uid in thread-local storage before
9720            // going to the content provider to open the file.  Later, in the code
9721            // that handles all permissions checks, we look for this uid and use
9722            // that rather than the Activity Manager's own uid.  The effect is that
9723            // we do the check against the caller's permissions even though it looks
9724            // to the content provider like the Activity Manager itself is making
9725            // the request.
9726            Binder token = new Binder();
9727            sCallerIdentity.set(new Identity(
9728                    token, Binder.getCallingPid(), Binder.getCallingUid()));
9729            try {
9730                pfd = cph.provider.openFile(null, uri, "r", null, token);
9731            } catch (FileNotFoundException e) {
9732                // do nothing; pfd will be returned null
9733            } finally {
9734                // Ensure that whatever happens, we clean up the identity state
9735                sCallerIdentity.remove();
9736                // Ensure we're done with the provider.
9737                removeContentProviderExternalUnchecked(name, null, userId);
9738            }
9739        } else {
9740            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9741        }
9742        return pfd;
9743    }
9744
9745    // Actually is sleeping or shutting down or whatever else in the future
9746    // is an inactive state.
9747    public boolean isSleepingOrShuttingDown() {
9748        return isSleeping() || mShuttingDown;
9749    }
9750
9751    public boolean isSleeping() {
9752        return mSleeping;
9753    }
9754
9755    void onWakefulnessChanged(int wakefulness) {
9756        synchronized(this) {
9757            mWakefulness = wakefulness;
9758            updateSleepIfNeededLocked();
9759        }
9760    }
9761
9762    void finishRunningVoiceLocked() {
9763        if (mRunningVoice != null) {
9764            mRunningVoice = null;
9765            updateSleepIfNeededLocked();
9766        }
9767    }
9768
9769    void updateSleepIfNeededLocked() {
9770        if (mSleeping && !shouldSleepLocked()) {
9771            mSleeping = false;
9772            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
9773            mStackSupervisor.comeOutOfSleepIfNeededLocked();
9774            updateOomAdjLocked();
9775        } else if (!mSleeping && shouldSleepLocked()) {
9776            mSleeping = true;
9777            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
9778            mStackSupervisor.goingToSleepLocked();
9779            updateOomAdjLocked();
9780
9781            // Initialize the wake times of all processes.
9782            checkExcessivePowerUsageLocked(false);
9783            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9784            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9785            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9786        }
9787    }
9788
9789    private boolean shouldSleepLocked() {
9790        // Resume applications while running a voice interactor.
9791        if (mRunningVoice != null) {
9792            return false;
9793        }
9794
9795        switch (mWakefulness) {
9796            case PowerManagerInternal.WAKEFULNESS_AWAKE:
9797            case PowerManagerInternal.WAKEFULNESS_DREAMING:
9798                // If we're interactive but applications are already paused then defer
9799                // resuming them until the lock screen is hidden.
9800                return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN;
9801            case PowerManagerInternal.WAKEFULNESS_DOZING:
9802                // If we're dozing then pause applications whenever the lock screen is shown.
9803                return mLockScreenShown != LOCK_SCREEN_HIDDEN;
9804            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
9805            default:
9806                // If we're asleep then pause applications unconditionally.
9807                return true;
9808        }
9809    }
9810
9811    /** Pokes the task persister. */
9812    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9813        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9814            // Never persist the home stack.
9815            return;
9816        }
9817        mTaskPersister.wakeup(task, flush);
9818    }
9819
9820    /** Notifies all listeners when the task stack has changed. */
9821    void notifyTaskStackChangedLocked() {
9822        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
9823        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
9824        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
9825    }
9826
9827    @Override
9828    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
9829        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
9830    }
9831
9832    @Override
9833    public boolean shutdown(int timeout) {
9834        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9835                != PackageManager.PERMISSION_GRANTED) {
9836            throw new SecurityException("Requires permission "
9837                    + android.Manifest.permission.SHUTDOWN);
9838        }
9839
9840        boolean timedout = false;
9841
9842        synchronized(this) {
9843            mShuttingDown = true;
9844            updateEventDispatchingLocked();
9845            timedout = mStackSupervisor.shutdownLocked(timeout);
9846        }
9847
9848        mAppOpsService.shutdown();
9849        if (mUsageStatsService != null) {
9850            mUsageStatsService.prepareShutdown();
9851        }
9852        mBatteryStatsService.shutdown();
9853        synchronized (this) {
9854            mProcessStats.shutdownLocked();
9855            notifyTaskPersisterLocked(null, true);
9856        }
9857
9858        return timedout;
9859    }
9860
9861    public final void activitySlept(IBinder token) {
9862        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
9863
9864        final long origId = Binder.clearCallingIdentity();
9865
9866        synchronized (this) {
9867            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9868            if (r != null) {
9869                mStackSupervisor.activitySleptLocked(r);
9870            }
9871        }
9872
9873        Binder.restoreCallingIdentity(origId);
9874    }
9875
9876    private String lockScreenShownToString() {
9877        switch (mLockScreenShown) {
9878            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
9879            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
9880            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
9881            default: return "Unknown=" + mLockScreenShown;
9882        }
9883    }
9884
9885    void logLockScreen(String msg) {
9886        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
9887                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
9888                + PowerManagerInternal.wakefulnessToString(mWakefulness)
9889                + " mSleeping=" + mSleeping);
9890    }
9891
9892    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
9893        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
9894        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
9895            if (mRunningVoice == null) {
9896                mVoiceWakeLock.acquire();
9897                updateSleepIfNeededLocked();
9898            }
9899            mRunningVoice = session;
9900        }
9901    }
9902
9903    private void updateEventDispatchingLocked() {
9904        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
9905    }
9906
9907    public void setLockScreenShown(boolean shown) {
9908        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9909                != PackageManager.PERMISSION_GRANTED) {
9910            throw new SecurityException("Requires permission "
9911                    + android.Manifest.permission.DEVICE_POWER);
9912        }
9913
9914        synchronized(this) {
9915            long ident = Binder.clearCallingIdentity();
9916            try {
9917                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9918                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
9919                updateSleepIfNeededLocked();
9920            } finally {
9921                Binder.restoreCallingIdentity(ident);
9922            }
9923        }
9924    }
9925
9926    @Override
9927    public void stopAppSwitches() {
9928        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9929                != PackageManager.PERMISSION_GRANTED) {
9930            throw new SecurityException("Requires permission "
9931                    + android.Manifest.permission.STOP_APP_SWITCHES);
9932        }
9933
9934        synchronized(this) {
9935            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9936                    + APP_SWITCH_DELAY_TIME;
9937            mDidAppSwitch = false;
9938            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9939            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9940            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9941        }
9942    }
9943
9944    public void resumeAppSwitches() {
9945        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9946                != PackageManager.PERMISSION_GRANTED) {
9947            throw new SecurityException("Requires permission "
9948                    + android.Manifest.permission.STOP_APP_SWITCHES);
9949        }
9950
9951        synchronized(this) {
9952            // Note that we don't execute any pending app switches... we will
9953            // let those wait until either the timeout, or the next start
9954            // activity request.
9955            mAppSwitchesAllowedTime = 0;
9956        }
9957    }
9958
9959    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
9960            int callingPid, int callingUid, String name) {
9961        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9962            return true;
9963        }
9964
9965        int perm = checkComponentPermission(
9966                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
9967                sourceUid, -1, true);
9968        if (perm == PackageManager.PERMISSION_GRANTED) {
9969            return true;
9970        }
9971
9972        // If the actual IPC caller is different from the logical source, then
9973        // also see if they are allowed to control app switches.
9974        if (callingUid != -1 && callingUid != sourceUid) {
9975            perm = checkComponentPermission(
9976                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9977                    callingUid, -1, true);
9978            if (perm == PackageManager.PERMISSION_GRANTED) {
9979                return true;
9980            }
9981        }
9982
9983        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
9984        return false;
9985    }
9986
9987    public void setDebugApp(String packageName, boolean waitForDebugger,
9988            boolean persistent) {
9989        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9990                "setDebugApp()");
9991
9992        long ident = Binder.clearCallingIdentity();
9993        try {
9994            // Note that this is not really thread safe if there are multiple
9995            // callers into it at the same time, but that's not a situation we
9996            // care about.
9997            if (persistent) {
9998                final ContentResolver resolver = mContext.getContentResolver();
9999                Settings.Global.putString(
10000                    resolver, Settings.Global.DEBUG_APP,
10001                    packageName);
10002                Settings.Global.putInt(
10003                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10004                    waitForDebugger ? 1 : 0);
10005            }
10006
10007            synchronized (this) {
10008                if (!persistent) {
10009                    mOrigDebugApp = mDebugApp;
10010                    mOrigWaitForDebugger = mWaitForDebugger;
10011                }
10012                mDebugApp = packageName;
10013                mWaitForDebugger = waitForDebugger;
10014                mDebugTransient = !persistent;
10015                if (packageName != null) {
10016                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10017                            false, UserHandle.USER_ALL, "set debug app");
10018                }
10019            }
10020        } finally {
10021            Binder.restoreCallingIdentity(ident);
10022        }
10023    }
10024
10025    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10026        synchronized (this) {
10027            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10028            if (!isDebuggable) {
10029                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10030                    throw new SecurityException("Process not debuggable: " + app.packageName);
10031                }
10032            }
10033
10034            mOpenGlTraceApp = processName;
10035        }
10036    }
10037
10038    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10039        synchronized (this) {
10040            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10041            if (!isDebuggable) {
10042                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10043                    throw new SecurityException("Process not debuggable: " + app.packageName);
10044                }
10045            }
10046            mProfileApp = processName;
10047            mProfileFile = profilerInfo.profileFile;
10048            if (mProfileFd != null) {
10049                try {
10050                    mProfileFd.close();
10051                } catch (IOException e) {
10052                }
10053                mProfileFd = null;
10054            }
10055            mProfileFd = profilerInfo.profileFd;
10056            mSamplingInterval = profilerInfo.samplingInterval;
10057            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10058            mProfileType = 0;
10059        }
10060    }
10061
10062    @Override
10063    public void setAlwaysFinish(boolean enabled) {
10064        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10065                "setAlwaysFinish()");
10066
10067        Settings.Global.putInt(
10068                mContext.getContentResolver(),
10069                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10070
10071        synchronized (this) {
10072            mAlwaysFinishActivities = enabled;
10073        }
10074    }
10075
10076    @Override
10077    public void setActivityController(IActivityController controller) {
10078        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10079                "setActivityController()");
10080        synchronized (this) {
10081            mController = controller;
10082            Watchdog.getInstance().setActivityController(controller);
10083        }
10084    }
10085
10086    @Override
10087    public void setUserIsMonkey(boolean userIsMonkey) {
10088        synchronized (this) {
10089            synchronized (mPidsSelfLocked) {
10090                final int callingPid = Binder.getCallingPid();
10091                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10092                if (precessRecord == null) {
10093                    throw new SecurityException("Unknown process: " + callingPid);
10094                }
10095                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10096                    throw new SecurityException("Only an instrumentation process "
10097                            + "with a UiAutomation can call setUserIsMonkey");
10098                }
10099            }
10100            mUserIsMonkey = userIsMonkey;
10101        }
10102    }
10103
10104    @Override
10105    public boolean isUserAMonkey() {
10106        synchronized (this) {
10107            // If there is a controller also implies the user is a monkey.
10108            return (mUserIsMonkey || mController != null);
10109        }
10110    }
10111
10112    public void requestBugReport() {
10113        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10114        SystemProperties.set("ctl.start", "bugreport");
10115    }
10116
10117    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10118        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10119    }
10120
10121    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10122        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10123            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10124        }
10125        return KEY_DISPATCHING_TIMEOUT;
10126    }
10127
10128    @Override
10129    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10130        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10131                != PackageManager.PERMISSION_GRANTED) {
10132            throw new SecurityException("Requires permission "
10133                    + android.Manifest.permission.FILTER_EVENTS);
10134        }
10135        ProcessRecord proc;
10136        long timeout;
10137        synchronized (this) {
10138            synchronized (mPidsSelfLocked) {
10139                proc = mPidsSelfLocked.get(pid);
10140            }
10141            timeout = getInputDispatchingTimeoutLocked(proc);
10142        }
10143
10144        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10145            return -1;
10146        }
10147
10148        return timeout;
10149    }
10150
10151    /**
10152     * Handle input dispatching timeouts.
10153     * Returns whether input dispatching should be aborted or not.
10154     */
10155    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10156            final ActivityRecord activity, final ActivityRecord parent,
10157            final boolean aboveSystem, String reason) {
10158        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10159                != PackageManager.PERMISSION_GRANTED) {
10160            throw new SecurityException("Requires permission "
10161                    + android.Manifest.permission.FILTER_EVENTS);
10162        }
10163
10164        final String annotation;
10165        if (reason == null) {
10166            annotation = "Input dispatching timed out";
10167        } else {
10168            annotation = "Input dispatching timed out (" + reason + ")";
10169        }
10170
10171        if (proc != null) {
10172            synchronized (this) {
10173                if (proc.debugging) {
10174                    return false;
10175                }
10176
10177                if (mDidDexOpt) {
10178                    // Give more time since we were dexopting.
10179                    mDidDexOpt = false;
10180                    return false;
10181                }
10182
10183                if (proc.instrumentationClass != null) {
10184                    Bundle info = new Bundle();
10185                    info.putString("shortMsg", "keyDispatchingTimedOut");
10186                    info.putString("longMsg", annotation);
10187                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10188                    return true;
10189                }
10190            }
10191            mHandler.post(new Runnable() {
10192                @Override
10193                public void run() {
10194                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10195                }
10196            });
10197        }
10198
10199        return true;
10200    }
10201
10202    @Override
10203    public Bundle getAssistContextExtras(int requestType) {
10204        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
10205                UserHandle.getCallingUserId());
10206        if (pae == null) {
10207            return null;
10208        }
10209        synchronized (pae) {
10210            while (!pae.haveResult) {
10211                try {
10212                    pae.wait();
10213                } catch (InterruptedException e) {
10214                }
10215            }
10216        }
10217        synchronized (this) {
10218            buildAssistBundleLocked(pae, pae.result);
10219            mPendingAssistExtras.remove(pae);
10220            mHandler.removeCallbacks(pae);
10221        }
10222        return pae.extras;
10223    }
10224
10225    @Override
10226    public void requestAssistContextExtras(int requestType, IResultReceiver receiver) {
10227        enqueueAssistContext(requestType, null, null, receiver, UserHandle.getCallingUserId());
10228    }
10229
10230    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10231            IResultReceiver receiver, int userHandle) {
10232        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10233                "enqueueAssistContext()");
10234        synchronized (this) {
10235            ActivityRecord activity = getFocusedStack().topActivity();
10236            if (activity == null) {
10237                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
10238                return null;
10239            }
10240            if (activity.app == null || activity.app.thread == null) {
10241                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10242                return null;
10243            }
10244            if (activity.app.pid == Binder.getCallingPid()) {
10245                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10246                return null;
10247            }
10248            PendingAssistExtras pae;
10249            Bundle extras = new Bundle();
10250            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10251            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
10252            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
10253            try {
10254                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10255                        requestType);
10256                mPendingAssistExtras.add(pae);
10257                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10258            } catch (RemoteException e) {
10259                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10260                return null;
10261            }
10262            return pae;
10263        }
10264    }
10265
10266    void pendingAssistExtrasTimedOutLocked(PendingAssistExtras pae) {
10267        mPendingAssistExtras.remove(pae);
10268        if (pae.receiver != null) {
10269            // Caller wants result sent back to them.
10270            try {
10271                pae.receiver.send(0, null);
10272            } catch (RemoteException e) {
10273            }
10274        }
10275    }
10276
10277    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
10278        if (result != null) {
10279            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
10280        }
10281        if (pae.hint != null) {
10282            pae.extras.putBoolean(pae.hint, true);
10283        }
10284    }
10285
10286    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10287        PendingAssistExtras pae = (PendingAssistExtras)token;
10288        synchronized (pae) {
10289            pae.result = extras;
10290            pae.haveResult = true;
10291            pae.notifyAll();
10292            if (pae.intent == null && pae.receiver == null) {
10293                // Caller is just waiting for the result.
10294                return;
10295            }
10296        }
10297
10298        // We are now ready to launch the assist activity.
10299        synchronized (this) {
10300            buildAssistBundleLocked(pae, extras);
10301            boolean exists = mPendingAssistExtras.remove(pae);
10302            mHandler.removeCallbacks(pae);
10303            if (!exists) {
10304                // Timed out.
10305                return;
10306            }
10307            if (pae.receiver != null) {
10308                // Caller wants result sent back to them.
10309                try {
10310                    pae.receiver.send(0, pae.extras);
10311                } catch (RemoteException e) {
10312                }
10313                return;
10314            }
10315        }
10316        pae.intent.replaceExtras(pae.extras);
10317        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10318                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10319                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10320        closeSystemDialogs("assist");
10321        try {
10322            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10323        } catch (ActivityNotFoundException e) {
10324            Slog.w(TAG, "No activity to handle assist action.", e);
10325        }
10326    }
10327
10328    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10329        return enqueueAssistContext(requestType, intent, hint, null, userHandle) != null;
10330    }
10331
10332    public void registerProcessObserver(IProcessObserver observer) {
10333        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10334                "registerProcessObserver()");
10335        synchronized (this) {
10336            mProcessObservers.register(observer);
10337        }
10338    }
10339
10340    @Override
10341    public void unregisterProcessObserver(IProcessObserver observer) {
10342        synchronized (this) {
10343            mProcessObservers.unregister(observer);
10344        }
10345    }
10346
10347    @Override
10348    public boolean convertFromTranslucent(IBinder token) {
10349        final long origId = Binder.clearCallingIdentity();
10350        try {
10351            synchronized (this) {
10352                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10353                if (r == null) {
10354                    return false;
10355                }
10356                final boolean translucentChanged = r.changeWindowTranslucency(true);
10357                if (translucentChanged) {
10358                    r.task.stack.releaseBackgroundResources(r);
10359                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10360                }
10361                mWindowManager.setAppFullscreen(token, true);
10362                return translucentChanged;
10363            }
10364        } finally {
10365            Binder.restoreCallingIdentity(origId);
10366        }
10367    }
10368
10369    @Override
10370    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10371        final long origId = Binder.clearCallingIdentity();
10372        try {
10373            synchronized (this) {
10374                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10375                if (r == null) {
10376                    return false;
10377                }
10378                int index = r.task.mActivities.lastIndexOf(r);
10379                if (index > 0) {
10380                    ActivityRecord under = r.task.mActivities.get(index - 1);
10381                    under.returningOptions = options;
10382                }
10383                final boolean translucentChanged = r.changeWindowTranslucency(false);
10384                if (translucentChanged) {
10385                    r.task.stack.convertActivityToTranslucent(r);
10386                }
10387                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10388                mWindowManager.setAppFullscreen(token, false);
10389                return translucentChanged;
10390            }
10391        } finally {
10392            Binder.restoreCallingIdentity(origId);
10393        }
10394    }
10395
10396    @Override
10397    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10398        final long origId = Binder.clearCallingIdentity();
10399        try {
10400            synchronized (this) {
10401                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10402                if (r != null) {
10403                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10404                }
10405            }
10406            return false;
10407        } finally {
10408            Binder.restoreCallingIdentity(origId);
10409        }
10410    }
10411
10412    @Override
10413    public boolean isBackgroundVisibleBehind(IBinder token) {
10414        final long origId = Binder.clearCallingIdentity();
10415        try {
10416            synchronized (this) {
10417                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10418                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10419                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10420                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10421                return visible;
10422            }
10423        } finally {
10424            Binder.restoreCallingIdentity(origId);
10425        }
10426    }
10427
10428    @Override
10429    public ActivityOptions getActivityOptions(IBinder token) {
10430        final long origId = Binder.clearCallingIdentity();
10431        try {
10432            synchronized (this) {
10433                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10434                if (r != null) {
10435                    final ActivityOptions activityOptions = r.pendingOptions;
10436                    r.pendingOptions = null;
10437                    return activityOptions;
10438                }
10439                return null;
10440            }
10441        } finally {
10442            Binder.restoreCallingIdentity(origId);
10443        }
10444    }
10445
10446    @Override
10447    public void setImmersive(IBinder token, boolean immersive) {
10448        synchronized(this) {
10449            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10450            if (r == null) {
10451                throw new IllegalArgumentException();
10452            }
10453            r.immersive = immersive;
10454
10455            // update associated state if we're frontmost
10456            if (r == mFocusedActivity) {
10457                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
10458                applyUpdateLockStateLocked(r);
10459            }
10460        }
10461    }
10462
10463    @Override
10464    public boolean isImmersive(IBinder token) {
10465        synchronized (this) {
10466            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10467            if (r == null) {
10468                throw new IllegalArgumentException();
10469            }
10470            return r.immersive;
10471        }
10472    }
10473
10474    public boolean isTopActivityImmersive() {
10475        enforceNotIsolatedCaller("startActivity");
10476        synchronized (this) {
10477            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10478            return (r != null) ? r.immersive : false;
10479        }
10480    }
10481
10482    @Override
10483    public boolean isTopOfTask(IBinder token) {
10484        synchronized (this) {
10485            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10486            if (r == null) {
10487                throw new IllegalArgumentException();
10488            }
10489            return r.task.getTopActivity() == r;
10490        }
10491    }
10492
10493    public final void enterSafeMode() {
10494        synchronized(this) {
10495            // It only makes sense to do this before the system is ready
10496            // and started launching other packages.
10497            if (!mSystemReady) {
10498                try {
10499                    AppGlobals.getPackageManager().enterSafeMode();
10500                } catch (RemoteException e) {
10501                }
10502            }
10503
10504            mSafeMode = true;
10505        }
10506    }
10507
10508    public final void showSafeModeOverlay() {
10509        View v = LayoutInflater.from(mContext).inflate(
10510                com.android.internal.R.layout.safe_mode, null);
10511        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10512        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10513        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10514        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10515        lp.gravity = Gravity.BOTTOM | Gravity.START;
10516        lp.format = v.getBackground().getOpacity();
10517        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10518                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10519        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10520        ((WindowManager)mContext.getSystemService(
10521                Context.WINDOW_SERVICE)).addView(v, lp);
10522    }
10523
10524    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
10525        if (!(sender instanceof PendingIntentRecord)) {
10526            return;
10527        }
10528        final PendingIntentRecord rec = (PendingIntentRecord)sender;
10529        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10530        synchronized (stats) {
10531            if (mBatteryStatsService.isOnBattery()) {
10532                mBatteryStatsService.enforceCallingPermission();
10533                int MY_UID = Binder.getCallingUid();
10534                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10535                BatteryStatsImpl.Uid.Pkg pkg =
10536                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10537                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10538                pkg.noteWakeupAlarmLocked(tag);
10539            }
10540        }
10541    }
10542
10543    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
10544        if (!(sender instanceof PendingIntentRecord)) {
10545            return;
10546        }
10547        final PendingIntentRecord rec = (PendingIntentRecord)sender;
10548        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10549        synchronized (stats) {
10550            mBatteryStatsService.enforceCallingPermission();
10551            int MY_UID = Binder.getCallingUid();
10552            int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10553            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
10554        }
10555    }
10556
10557    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
10558        if (!(sender instanceof PendingIntentRecord)) {
10559            return;
10560        }
10561        final PendingIntentRecord rec = (PendingIntentRecord)sender;
10562        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10563        synchronized (stats) {
10564            mBatteryStatsService.enforceCallingPermission();
10565            int MY_UID = Binder.getCallingUid();
10566            int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10567            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
10568        }
10569    }
10570
10571    public boolean killPids(int[] pids, String pReason, boolean secure) {
10572        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10573            throw new SecurityException("killPids only available to the system");
10574        }
10575        String reason = (pReason == null) ? "Unknown" : pReason;
10576        // XXX Note: don't acquire main activity lock here, because the window
10577        // manager calls in with its locks held.
10578
10579        boolean killed = false;
10580        synchronized (mPidsSelfLocked) {
10581            int[] types = new int[pids.length];
10582            int worstType = 0;
10583            for (int i=0; i<pids.length; i++) {
10584                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10585                if (proc != null) {
10586                    int type = proc.setAdj;
10587                    types[i] = type;
10588                    if (type > worstType) {
10589                        worstType = type;
10590                    }
10591                }
10592            }
10593
10594            // If the worst oom_adj is somewhere in the cached proc LRU range,
10595            // then constrain it so we will kill all cached procs.
10596            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10597                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10598                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10599            }
10600
10601            // If this is not a secure call, don't let it kill processes that
10602            // are important.
10603            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10604                worstType = ProcessList.SERVICE_ADJ;
10605            }
10606
10607            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10608            for (int i=0; i<pids.length; i++) {
10609                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10610                if (proc == null) {
10611                    continue;
10612                }
10613                int adj = proc.setAdj;
10614                if (adj >= worstType && !proc.killedByAm) {
10615                    proc.kill(reason, true);
10616                    killed = true;
10617                }
10618            }
10619        }
10620        return killed;
10621    }
10622
10623    @Override
10624    public void killUid(int uid, String reason) {
10625        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10626            throw new SecurityException("killUid only available to the system");
10627        }
10628        synchronized (this) {
10629            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10630                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10631                    reason != null ? reason : "kill uid");
10632        }
10633    }
10634
10635    @Override
10636    public boolean killProcessesBelowForeground(String reason) {
10637        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10638            throw new SecurityException("killProcessesBelowForeground() only available to system");
10639        }
10640
10641        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10642    }
10643
10644    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10645        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10646            throw new SecurityException("killProcessesBelowAdj() only available to system");
10647        }
10648
10649        boolean killed = false;
10650        synchronized (mPidsSelfLocked) {
10651            final int size = mPidsSelfLocked.size();
10652            for (int i = 0; i < size; i++) {
10653                final int pid = mPidsSelfLocked.keyAt(i);
10654                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10655                if (proc == null) continue;
10656
10657                final int adj = proc.setAdj;
10658                if (adj > belowAdj && !proc.killedByAm) {
10659                    proc.kill(reason, true);
10660                    killed = true;
10661                }
10662            }
10663        }
10664        return killed;
10665    }
10666
10667    @Override
10668    public void hang(final IBinder who, boolean allowRestart) {
10669        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10670                != PackageManager.PERMISSION_GRANTED) {
10671            throw new SecurityException("Requires permission "
10672                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10673        }
10674
10675        final IBinder.DeathRecipient death = new DeathRecipient() {
10676            @Override
10677            public void binderDied() {
10678                synchronized (this) {
10679                    notifyAll();
10680                }
10681            }
10682        };
10683
10684        try {
10685            who.linkToDeath(death, 0);
10686        } catch (RemoteException e) {
10687            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10688            return;
10689        }
10690
10691        synchronized (this) {
10692            Watchdog.getInstance().setAllowRestart(allowRestart);
10693            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10694            synchronized (death) {
10695                while (who.isBinderAlive()) {
10696                    try {
10697                        death.wait();
10698                    } catch (InterruptedException e) {
10699                    }
10700                }
10701            }
10702            Watchdog.getInstance().setAllowRestart(true);
10703        }
10704    }
10705
10706    @Override
10707    public void restart() {
10708        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10709                != PackageManager.PERMISSION_GRANTED) {
10710            throw new SecurityException("Requires permission "
10711                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10712        }
10713
10714        Log.i(TAG, "Sending shutdown broadcast...");
10715
10716        BroadcastReceiver br = new BroadcastReceiver() {
10717            @Override public void onReceive(Context context, Intent intent) {
10718                // Now the broadcast is done, finish up the low-level shutdown.
10719                Log.i(TAG, "Shutting down activity manager...");
10720                shutdown(10000);
10721                Log.i(TAG, "Shutdown complete, restarting!");
10722                Process.killProcess(Process.myPid());
10723                System.exit(10);
10724            }
10725        };
10726
10727        // First send the high-level shut down broadcast.
10728        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10729        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10730        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10731        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10732        mContext.sendOrderedBroadcastAsUser(intent,
10733                UserHandle.ALL, null, br, mHandler, 0, null, null);
10734        */
10735        br.onReceive(mContext, intent);
10736    }
10737
10738    private long getLowRamTimeSinceIdle(long now) {
10739        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10740    }
10741
10742    @Override
10743    public void performIdleMaintenance() {
10744        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10745                != PackageManager.PERMISSION_GRANTED) {
10746            throw new SecurityException("Requires permission "
10747                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10748        }
10749
10750        synchronized (this) {
10751            final long now = SystemClock.uptimeMillis();
10752            final long timeSinceLastIdle = now - mLastIdleTime;
10753            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10754            mLastIdleTime = now;
10755            mLowRamTimeSinceLastIdle = 0;
10756            if (mLowRamStartTime != 0) {
10757                mLowRamStartTime = now;
10758            }
10759
10760            StringBuilder sb = new StringBuilder(128);
10761            sb.append("Idle maintenance over ");
10762            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10763            sb.append(" low RAM for ");
10764            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10765            Slog.i(TAG, sb.toString());
10766
10767            // If at least 1/3 of our time since the last idle period has been spent
10768            // with RAM low, then we want to kill processes.
10769            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10770
10771            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10772                ProcessRecord proc = mLruProcesses.get(i);
10773                if (proc.notCachedSinceIdle) {
10774                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP
10775                            && proc.setProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
10776                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10777                        if (doKilling && proc.initialIdlePss != 0
10778                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10779                            sb = new StringBuilder(128);
10780                            sb.append("Kill");
10781                            sb.append(proc.processName);
10782                            sb.append(" in idle maint: pss=");
10783                            sb.append(proc.lastPss);
10784                            sb.append(", initialPss=");
10785                            sb.append(proc.initialIdlePss);
10786                            sb.append(", period=");
10787                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10788                            sb.append(", lowRamPeriod=");
10789                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10790                            Slog.wtfQuiet(TAG, sb.toString());
10791                            proc.kill("idle maint (pss " + proc.lastPss
10792                                    + " from " + proc.initialIdlePss + ")", true);
10793                        }
10794                    }
10795                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10796                    proc.notCachedSinceIdle = true;
10797                    proc.initialIdlePss = 0;
10798                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10799                            mTestPssMode, isSleeping(), now);
10800                }
10801            }
10802
10803            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10804            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10805        }
10806    }
10807
10808    private void retrieveSettings() {
10809        final ContentResolver resolver = mContext.getContentResolver();
10810        String debugApp = Settings.Global.getString(
10811            resolver, Settings.Global.DEBUG_APP);
10812        boolean waitForDebugger = Settings.Global.getInt(
10813            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10814        boolean alwaysFinishActivities = Settings.Global.getInt(
10815            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10816        boolean forceRtl = Settings.Global.getInt(
10817                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10818        // Transfer any global setting for forcing RTL layout, into a System Property
10819        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10820
10821        Configuration configuration = new Configuration();
10822        Settings.System.getConfiguration(resolver, configuration);
10823        if (forceRtl) {
10824            // This will take care of setting the correct layout direction flags
10825            configuration.setLayoutDirection(configuration.locale);
10826        }
10827
10828        synchronized (this) {
10829            mDebugApp = mOrigDebugApp = debugApp;
10830            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10831            mAlwaysFinishActivities = alwaysFinishActivities;
10832            // This happens before any activities are started, so we can
10833            // change mConfiguration in-place.
10834            updateConfigurationLocked(configuration, null, false, true);
10835            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
10836                    "Initial config: " + mConfiguration);
10837        }
10838    }
10839
10840    /** Loads resources after the current configuration has been set. */
10841    private void loadResourcesOnSystemReady() {
10842        final Resources res = mContext.getResources();
10843        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10844        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10845        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10846    }
10847
10848    public boolean testIsSystemReady() {
10849        // no need to synchronize(this) just to read & return the value
10850        return mSystemReady;
10851    }
10852
10853    private static File getCalledPreBootReceiversFile() {
10854        File dataDir = Environment.getDataDirectory();
10855        File systemDir = new File(dataDir, "system");
10856        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10857        return fname;
10858    }
10859
10860    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10861        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10862        File file = getCalledPreBootReceiversFile();
10863        FileInputStream fis = null;
10864        try {
10865            fis = new FileInputStream(file);
10866            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10867            int fvers = dis.readInt();
10868            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10869                String vers = dis.readUTF();
10870                String codename = dis.readUTF();
10871                String build = dis.readUTF();
10872                if (android.os.Build.VERSION.RELEASE.equals(vers)
10873                        && android.os.Build.VERSION.CODENAME.equals(codename)
10874                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10875                    int num = dis.readInt();
10876                    while (num > 0) {
10877                        num--;
10878                        String pkg = dis.readUTF();
10879                        String cls = dis.readUTF();
10880                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10881                    }
10882                }
10883            }
10884        } catch (FileNotFoundException e) {
10885        } catch (IOException e) {
10886            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10887        } finally {
10888            if (fis != null) {
10889                try {
10890                    fis.close();
10891                } catch (IOException e) {
10892                }
10893            }
10894        }
10895        return lastDoneReceivers;
10896    }
10897
10898    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10899        File file = getCalledPreBootReceiversFile();
10900        FileOutputStream fos = null;
10901        DataOutputStream dos = null;
10902        try {
10903            fos = new FileOutputStream(file);
10904            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10905            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10906            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10907            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10908            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10909            dos.writeInt(list.size());
10910            for (int i=0; i<list.size(); i++) {
10911                dos.writeUTF(list.get(i).getPackageName());
10912                dos.writeUTF(list.get(i).getClassName());
10913            }
10914        } catch (IOException e) {
10915            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10916            file.delete();
10917        } finally {
10918            FileUtils.sync(fos);
10919            if (dos != null) {
10920                try {
10921                    dos.close();
10922                } catch (IOException e) {
10923                    // TODO Auto-generated catch block
10924                    e.printStackTrace();
10925                }
10926            }
10927        }
10928    }
10929
10930    final class PreBootContinuation extends IIntentReceiver.Stub {
10931        final Intent intent;
10932        final Runnable onFinishCallback;
10933        final ArrayList<ComponentName> doneReceivers;
10934        final List<ResolveInfo> ris;
10935        final int[] users;
10936        int lastRi = -1;
10937        int curRi = 0;
10938        int curUser = 0;
10939
10940        PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
10941                ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
10942            intent = _intent;
10943            onFinishCallback = _onFinishCallback;
10944            doneReceivers = _doneReceivers;
10945            ris = _ris;
10946            users = _users;
10947        }
10948
10949        void go() {
10950            if (lastRi != curRi) {
10951                ActivityInfo ai = ris.get(curRi).activityInfo;
10952                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10953                intent.setComponent(comp);
10954                doneReceivers.add(comp);
10955                lastRi = curRi;
10956                CharSequence label = ai.loadLabel(mContext.getPackageManager());
10957                showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
10958            }
10959            Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
10960                    + " for user " + users[curUser]);
10961            EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
10962            broadcastIntentLocked(null, null, intent, null, this,
10963                    0, null, null, null, AppOpsManager.OP_NONE,
10964                    true, false, MY_PID, Process.SYSTEM_UID,
10965                    users[curUser]);
10966        }
10967
10968        public void performReceive(Intent intent, int resultCode,
10969                String data, Bundle extras, boolean ordered,
10970                boolean sticky, int sendingUser) {
10971            curUser++;
10972            if (curUser >= users.length) {
10973                curUser = 0;
10974                curRi++;
10975                if (curRi >= ris.size()) {
10976                    // All done sending broadcasts!
10977                    if (onFinishCallback != null) {
10978                        // The raw IIntentReceiver interface is called
10979                        // with the AM lock held, so redispatch to
10980                        // execute our code without the lock.
10981                        mHandler.post(onFinishCallback);
10982                    }
10983                    return;
10984                }
10985            }
10986            go();
10987        }
10988    }
10989
10990    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10991            ArrayList<ComponentName> doneReceivers, int userId) {
10992        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10993        List<ResolveInfo> ris = null;
10994        try {
10995            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10996                    intent, null, 0, userId);
10997        } catch (RemoteException e) {
10998        }
10999        if (ris == null) {
11000            return false;
11001        }
11002        for (int i=ris.size()-1; i>=0; i--) {
11003            if ((ris.get(i).activityInfo.applicationInfo.flags
11004                    &ApplicationInfo.FLAG_SYSTEM) == 0) {
11005                ris.remove(i);
11006            }
11007        }
11008        intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11009
11010        // For User 0, load the version number. When delivering to a new user, deliver
11011        // to all receivers.
11012        if (userId == UserHandle.USER_OWNER) {
11013            ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11014            for (int i=0; i<ris.size(); i++) {
11015                ActivityInfo ai = ris.get(i).activityInfo;
11016                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11017                if (false && lastDoneReceivers.contains(comp)) {
11018                    // We already did the pre boot receiver for this app with the current
11019                    // platform version, so don't do it again...
11020                    ris.remove(i);
11021                    i--;
11022                    // ...however, do keep it as one that has been done, so we don't
11023                    // forget about it when rewriting the file of last done receivers.
11024                    doneReceivers.add(comp);
11025                }
11026            }
11027        }
11028
11029        if (ris.size() <= 0) {
11030            return false;
11031        }
11032
11033        // If primary user, send broadcast to all available users, else just to userId
11034        final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11035                : new int[] { userId };
11036        if (users.length <= 0) {
11037            return false;
11038        }
11039
11040        PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
11041                ris, users);
11042        cont.go();
11043        return true;
11044    }
11045
11046    public void systemReady(final Runnable goingCallback) {
11047        synchronized(this) {
11048            if (mSystemReady) {
11049                // If we're done calling all the receivers, run the next "boot phase" passed in
11050                // by the SystemServer
11051                if (goingCallback != null) {
11052                    goingCallback.run();
11053                }
11054                return;
11055            }
11056
11057            // Make sure we have the current profile info, since it is needed for
11058            // security checks.
11059            updateCurrentProfileIdsLocked();
11060
11061            mRecentTasks.clear();
11062            mRecentTasks.addAll(mTaskPersister.restoreTasksLocked());
11063            mTaskPersister.restoreTasksFromOtherDeviceLocked();
11064            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
11065            mTaskPersister.startPersisting();
11066
11067            // Check to see if there are any update receivers to run.
11068            if (!mDidUpdate) {
11069                if (mWaitingUpdate) {
11070                    return;
11071                }
11072                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11073                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11074                    public void run() {
11075                        synchronized (ActivityManagerService.this) {
11076                            mDidUpdate = true;
11077                        }
11078                        showBootMessage(mContext.getText(
11079                                R.string.android_upgrading_complete),
11080                                false);
11081                        writeLastDonePreBootReceivers(doneReceivers);
11082                        systemReady(goingCallback);
11083                    }
11084                }, doneReceivers, UserHandle.USER_OWNER);
11085
11086                if (mWaitingUpdate) {
11087                    return;
11088                }
11089                mDidUpdate = true;
11090            }
11091
11092            mAppOpsService.systemReady();
11093            mSystemReady = true;
11094        }
11095
11096        ArrayList<ProcessRecord> procsToKill = null;
11097        synchronized(mPidsSelfLocked) {
11098            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11099                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11100                if (!isAllowedWhileBooting(proc.info)){
11101                    if (procsToKill == null) {
11102                        procsToKill = new ArrayList<ProcessRecord>();
11103                    }
11104                    procsToKill.add(proc);
11105                }
11106            }
11107        }
11108
11109        synchronized(this) {
11110            if (procsToKill != null) {
11111                for (int i=procsToKill.size()-1; i>=0; i--) {
11112                    ProcessRecord proc = procsToKill.get(i);
11113                    Slog.i(TAG, "Removing system update proc: " + proc);
11114                    removeProcessLocked(proc, true, false, "system update done");
11115                }
11116            }
11117
11118            // Now that we have cleaned up any update processes, we
11119            // are ready to start launching real processes and know that
11120            // we won't trample on them any more.
11121            mProcessesReady = true;
11122        }
11123
11124        Slog.i(TAG, "System now ready");
11125        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11126            SystemClock.uptimeMillis());
11127
11128        synchronized(this) {
11129            // Make sure we have no pre-ready processes sitting around.
11130
11131            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11132                ResolveInfo ri = mContext.getPackageManager()
11133                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11134                                STOCK_PM_FLAGS);
11135                CharSequence errorMsg = null;
11136                if (ri != null) {
11137                    ActivityInfo ai = ri.activityInfo;
11138                    ApplicationInfo app = ai.applicationInfo;
11139                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11140                        mTopAction = Intent.ACTION_FACTORY_TEST;
11141                        mTopData = null;
11142                        mTopComponent = new ComponentName(app.packageName,
11143                                ai.name);
11144                    } else {
11145                        errorMsg = mContext.getResources().getText(
11146                                com.android.internal.R.string.factorytest_not_system);
11147                    }
11148                } else {
11149                    errorMsg = mContext.getResources().getText(
11150                            com.android.internal.R.string.factorytest_no_action);
11151                }
11152                if (errorMsg != null) {
11153                    mTopAction = null;
11154                    mTopData = null;
11155                    mTopComponent = null;
11156                    Message msg = Message.obtain();
11157                    msg.what = SHOW_FACTORY_ERROR_MSG;
11158                    msg.getData().putCharSequence("msg", errorMsg);
11159                    mHandler.sendMessage(msg);
11160                }
11161            }
11162        }
11163
11164        retrieveSettings();
11165        loadResourcesOnSystemReady();
11166
11167        synchronized (this) {
11168            readGrantedUriPermissionsLocked();
11169        }
11170
11171        if (goingCallback != null) goingCallback.run();
11172
11173        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11174                Integer.toString(mCurrentUserId), mCurrentUserId);
11175        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11176                Integer.toString(mCurrentUserId), mCurrentUserId);
11177        mSystemServiceManager.startUser(mCurrentUserId);
11178
11179        synchronized (this) {
11180            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11181                try {
11182                    List apps = AppGlobals.getPackageManager().
11183                        getPersistentApplications(STOCK_PM_FLAGS);
11184                    if (apps != null) {
11185                        int N = apps.size();
11186                        int i;
11187                        for (i=0; i<N; i++) {
11188                            ApplicationInfo info
11189                                = (ApplicationInfo)apps.get(i);
11190                            if (info != null &&
11191                                    !info.packageName.equals("android")) {
11192                                addAppLocked(info, false, null /* ABI override */);
11193                            }
11194                        }
11195                    }
11196                } catch (RemoteException ex) {
11197                    // pm is in same process, this will never happen.
11198                }
11199            }
11200
11201            // Start up initial activity.
11202            mBooting = true;
11203            startHomeActivityLocked(mCurrentUserId, "systemReady");
11204
11205            try {
11206                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11207                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11208                            + " data partition or your device will be unstable.");
11209                    mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11210                }
11211            } catch (RemoteException e) {
11212            }
11213
11214            if (!Build.isBuildConsistent()) {
11215                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11216                mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11217            }
11218
11219            long ident = Binder.clearCallingIdentity();
11220            try {
11221                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11222                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11223                        | Intent.FLAG_RECEIVER_FOREGROUND);
11224                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11225                broadcastIntentLocked(null, null, intent,
11226                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11227                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11228                intent = new Intent(Intent.ACTION_USER_STARTING);
11229                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11230                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11231                broadcastIntentLocked(null, null, intent,
11232                        null, new IIntentReceiver.Stub() {
11233                            @Override
11234                            public void performReceive(Intent intent, int resultCode, String data,
11235                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11236                                    throws RemoteException {
11237                            }
11238                        }, 0, null, null,
11239                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11240                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11241            } catch (Throwable t) {
11242                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11243            } finally {
11244                Binder.restoreCallingIdentity(ident);
11245            }
11246            mStackSupervisor.resumeTopActivitiesLocked();
11247            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11248        }
11249    }
11250
11251    private boolean makeAppCrashingLocked(ProcessRecord app,
11252            String shortMsg, String longMsg, String stackTrace) {
11253        app.crashing = true;
11254        app.crashingReport = generateProcessError(app,
11255                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11256        startAppProblemLocked(app);
11257        app.stopFreezingAllLocked();
11258        return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
11259    }
11260
11261    private void makeAppNotRespondingLocked(ProcessRecord app,
11262            String activity, String shortMsg, String longMsg) {
11263        app.notResponding = true;
11264        app.notRespondingReport = generateProcessError(app,
11265                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11266                activity, shortMsg, longMsg, null);
11267        startAppProblemLocked(app);
11268        app.stopFreezingAllLocked();
11269    }
11270
11271    /**
11272     * Generate a process error record, suitable for attachment to a ProcessRecord.
11273     *
11274     * @param app The ProcessRecord in which the error occurred.
11275     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11276     *                      ActivityManager.AppErrorStateInfo
11277     * @param activity The activity associated with the crash, if known.
11278     * @param shortMsg Short message describing the crash.
11279     * @param longMsg Long message describing the crash.
11280     * @param stackTrace Full crash stack trace, may be null.
11281     *
11282     * @return Returns a fully-formed AppErrorStateInfo record.
11283     */
11284    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11285            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11286        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11287
11288        report.condition = condition;
11289        report.processName = app.processName;
11290        report.pid = app.pid;
11291        report.uid = app.info.uid;
11292        report.tag = activity;
11293        report.shortMsg = shortMsg;
11294        report.longMsg = longMsg;
11295        report.stackTrace = stackTrace;
11296
11297        return report;
11298    }
11299
11300    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11301        synchronized (this) {
11302            app.crashing = false;
11303            app.crashingReport = null;
11304            app.notResponding = false;
11305            app.notRespondingReport = null;
11306            if (app.anrDialog == fromDialog) {
11307                app.anrDialog = null;
11308            }
11309            if (app.waitDialog == fromDialog) {
11310                app.waitDialog = null;
11311            }
11312            if (app.pid > 0 && app.pid != MY_PID) {
11313                handleAppCrashLocked(app, "user-terminated" /*reason*/,
11314                        null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
11315                app.kill("user request after error", true);
11316            }
11317        }
11318    }
11319
11320    private boolean handleAppCrashLocked(ProcessRecord app, String reason,
11321            String shortMsg, String longMsg, String stackTrace) {
11322        long now = SystemClock.uptimeMillis();
11323
11324        Long crashTime;
11325        if (!app.isolated) {
11326            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11327        } else {
11328            crashTime = null;
11329        }
11330        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11331            // This process loses!
11332            Slog.w(TAG, "Process " + app.info.processName
11333                    + " has crashed too many times: killing!");
11334            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11335                    app.userId, app.info.processName, app.uid);
11336            mStackSupervisor.handleAppCrashLocked(app);
11337            if (!app.persistent) {
11338                // We don't want to start this process again until the user
11339                // explicitly does so...  but for persistent process, we really
11340                // need to keep it running.  If a persistent process is actually
11341                // repeatedly crashing, then badness for everyone.
11342                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11343                        app.info.processName);
11344                if (!app.isolated) {
11345                    // XXX We don't have a way to mark isolated processes
11346                    // as bad, since they don't have a peristent identity.
11347                    mBadProcesses.put(app.info.processName, app.uid,
11348                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11349                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11350                }
11351                app.bad = true;
11352                app.removed = true;
11353                // Don't let services in this process be restarted and potentially
11354                // annoy the user repeatedly.  Unless it is persistent, since those
11355                // processes run critical code.
11356                removeProcessLocked(app, false, false, "crash");
11357                mStackSupervisor.resumeTopActivitiesLocked();
11358                return false;
11359            }
11360            mStackSupervisor.resumeTopActivitiesLocked();
11361        } else {
11362            mStackSupervisor.finishTopRunningActivityLocked(app, reason);
11363        }
11364
11365        // Bump up the crash count of any services currently running in the proc.
11366        for (int i=app.services.size()-1; i>=0; i--) {
11367            // Any services running in the application need to be placed
11368            // back in the pending list.
11369            ServiceRecord sr = app.services.valueAt(i);
11370            sr.crashCount++;
11371        }
11372
11373        // If the crashing process is what we consider to be the "home process" and it has been
11374        // replaced by a third-party app, clear the package preferred activities from packages
11375        // with a home activity running in the process to prevent a repeatedly crashing app
11376        // from blocking the user to manually clear the list.
11377        final ArrayList<ActivityRecord> activities = app.activities;
11378        if (app == mHomeProcess && activities.size() > 0
11379                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11380            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11381                final ActivityRecord r = activities.get(activityNdx);
11382                if (r.isHomeActivity()) {
11383                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11384                    try {
11385                        ActivityThread.getPackageManager()
11386                                .clearPackagePreferredActivities(r.packageName);
11387                    } catch (RemoteException c) {
11388                        // pm is in same process, this will never happen.
11389                    }
11390                }
11391            }
11392        }
11393
11394        if (!app.isolated) {
11395            // XXX Can't keep track of crash times for isolated processes,
11396            // because they don't have a perisistent identity.
11397            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11398        }
11399
11400        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11401        return true;
11402    }
11403
11404    void startAppProblemLocked(ProcessRecord app) {
11405        // If this app is not running under the current user, then we
11406        // can't give it a report button because that would require
11407        // launching the report UI under a different user.
11408        app.errorReportReceiver = null;
11409
11410        for (int userId : mCurrentProfileIds) {
11411            if (app.userId == userId) {
11412                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11413                        mContext, app.info.packageName, app.info.flags);
11414            }
11415        }
11416        skipCurrentReceiverLocked(app);
11417    }
11418
11419    void skipCurrentReceiverLocked(ProcessRecord app) {
11420        for (BroadcastQueue queue : mBroadcastQueues) {
11421            queue.skipCurrentReceiverLocked(app);
11422        }
11423    }
11424
11425    /**
11426     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11427     * The application process will exit immediately after this call returns.
11428     * @param app object of the crashing app, null for the system server
11429     * @param crashInfo describing the exception
11430     */
11431    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11432        ProcessRecord r = findAppProcess(app, "Crash");
11433        final String processName = app == null ? "system_server"
11434                : (r == null ? "unknown" : r.processName);
11435
11436        handleApplicationCrashInner("crash", r, processName, crashInfo);
11437    }
11438
11439    /* Native crash reporting uses this inner version because it needs to be somewhat
11440     * decoupled from the AM-managed cleanup lifecycle
11441     */
11442    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11443            ApplicationErrorReport.CrashInfo crashInfo) {
11444        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11445                UserHandle.getUserId(Binder.getCallingUid()), processName,
11446                r == null ? -1 : r.info.flags,
11447                crashInfo.exceptionClassName,
11448                crashInfo.exceptionMessage,
11449                crashInfo.throwFileName,
11450                crashInfo.throwLineNumber);
11451
11452        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11453
11454        crashApplication(r, crashInfo);
11455    }
11456
11457    public void handleApplicationStrictModeViolation(
11458            IBinder app,
11459            int violationMask,
11460            StrictMode.ViolationInfo info) {
11461        ProcessRecord r = findAppProcess(app, "StrictMode");
11462        if (r == null) {
11463            return;
11464        }
11465
11466        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11467            Integer stackFingerprint = info.hashCode();
11468            boolean logIt = true;
11469            synchronized (mAlreadyLoggedViolatedStacks) {
11470                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11471                    logIt = false;
11472                    // TODO: sub-sample into EventLog for these, with
11473                    // the info.durationMillis?  Then we'd get
11474                    // the relative pain numbers, without logging all
11475                    // the stack traces repeatedly.  We'd want to do
11476                    // likewise in the client code, which also does
11477                    // dup suppression, before the Binder call.
11478                } else {
11479                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11480                        mAlreadyLoggedViolatedStacks.clear();
11481                    }
11482                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11483                }
11484            }
11485            if (logIt) {
11486                logStrictModeViolationToDropBox(r, info);
11487            }
11488        }
11489
11490        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11491            AppErrorResult result = new AppErrorResult();
11492            synchronized (this) {
11493                final long origId = Binder.clearCallingIdentity();
11494
11495                Message msg = Message.obtain();
11496                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11497                HashMap<String, Object> data = new HashMap<String, Object>();
11498                data.put("result", result);
11499                data.put("app", r);
11500                data.put("violationMask", violationMask);
11501                data.put("info", info);
11502                msg.obj = data;
11503                mHandler.sendMessage(msg);
11504
11505                Binder.restoreCallingIdentity(origId);
11506            }
11507            int res = result.get();
11508            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11509        }
11510    }
11511
11512    // Depending on the policy in effect, there could be a bunch of
11513    // these in quick succession so we try to batch these together to
11514    // minimize disk writes, number of dropbox entries, and maximize
11515    // compression, by having more fewer, larger records.
11516    private void logStrictModeViolationToDropBox(
11517            ProcessRecord process,
11518            StrictMode.ViolationInfo info) {
11519        if (info == null) {
11520            return;
11521        }
11522        final boolean isSystemApp = process == null ||
11523                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11524                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11525        final String processName = process == null ? "unknown" : process.processName;
11526        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11527        final DropBoxManager dbox = (DropBoxManager)
11528                mContext.getSystemService(Context.DROPBOX_SERVICE);
11529
11530        // Exit early if the dropbox isn't configured to accept this report type.
11531        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11532
11533        boolean bufferWasEmpty;
11534        boolean needsFlush;
11535        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11536        synchronized (sb) {
11537            bufferWasEmpty = sb.length() == 0;
11538            appendDropBoxProcessHeaders(process, processName, sb);
11539            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11540            sb.append("System-App: ").append(isSystemApp).append("\n");
11541            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11542            if (info.violationNumThisLoop != 0) {
11543                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11544            }
11545            if (info.numAnimationsRunning != 0) {
11546                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11547            }
11548            if (info.broadcastIntentAction != null) {
11549                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11550            }
11551            if (info.durationMillis != -1) {
11552                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11553            }
11554            if (info.numInstances != -1) {
11555                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11556            }
11557            if (info.tags != null) {
11558                for (String tag : info.tags) {
11559                    sb.append("Span-Tag: ").append(tag).append("\n");
11560                }
11561            }
11562            sb.append("\n");
11563            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11564                sb.append(info.crashInfo.stackTrace);
11565                sb.append("\n");
11566            }
11567            if (info.message != null) {
11568                sb.append(info.message);
11569                sb.append("\n");
11570            }
11571
11572            // Only buffer up to ~64k.  Various logging bits truncate
11573            // things at 128k.
11574            needsFlush = (sb.length() > 64 * 1024);
11575        }
11576
11577        // Flush immediately if the buffer's grown too large, or this
11578        // is a non-system app.  Non-system apps are isolated with a
11579        // different tag & policy and not batched.
11580        //
11581        // Batching is useful during internal testing with
11582        // StrictMode settings turned up high.  Without batching,
11583        // thousands of separate files could be created on boot.
11584        if (!isSystemApp || needsFlush) {
11585            new Thread("Error dump: " + dropboxTag) {
11586                @Override
11587                public void run() {
11588                    String report;
11589                    synchronized (sb) {
11590                        report = sb.toString();
11591                        sb.delete(0, sb.length());
11592                        sb.trimToSize();
11593                    }
11594                    if (report.length() != 0) {
11595                        dbox.addText(dropboxTag, report);
11596                    }
11597                }
11598            }.start();
11599            return;
11600        }
11601
11602        // System app batching:
11603        if (!bufferWasEmpty) {
11604            // An existing dropbox-writing thread is outstanding, so
11605            // we don't need to start it up.  The existing thread will
11606            // catch the buffer appends we just did.
11607            return;
11608        }
11609
11610        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11611        // (After this point, we shouldn't access AMS internal data structures.)
11612        new Thread("Error dump: " + dropboxTag) {
11613            @Override
11614            public void run() {
11615                // 5 second sleep to let stacks arrive and be batched together
11616                try {
11617                    Thread.sleep(5000);  // 5 seconds
11618                } catch (InterruptedException e) {}
11619
11620                String errorReport;
11621                synchronized (mStrictModeBuffer) {
11622                    errorReport = mStrictModeBuffer.toString();
11623                    if (errorReport.length() == 0) {
11624                        return;
11625                    }
11626                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11627                    mStrictModeBuffer.trimToSize();
11628                }
11629                dbox.addText(dropboxTag, errorReport);
11630            }
11631        }.start();
11632    }
11633
11634    /**
11635     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11636     * @param app object of the crashing app, null for the system server
11637     * @param tag reported by the caller
11638     * @param system whether this wtf is coming from the system
11639     * @param crashInfo describing the context of the error
11640     * @return true if the process should exit immediately (WTF is fatal)
11641     */
11642    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11643            final ApplicationErrorReport.CrashInfo crashInfo) {
11644        final int callingUid = Binder.getCallingUid();
11645        final int callingPid = Binder.getCallingPid();
11646
11647        if (system) {
11648            // If this is coming from the system, we could very well have low-level
11649            // system locks held, so we want to do this all asynchronously.  And we
11650            // never want this to become fatal, so there is that too.
11651            mHandler.post(new Runnable() {
11652                @Override public void run() {
11653                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11654                }
11655            });
11656            return false;
11657        }
11658
11659        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11660                crashInfo);
11661
11662        if (r != null && r.pid != Process.myPid() &&
11663                Settings.Global.getInt(mContext.getContentResolver(),
11664                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11665            crashApplication(r, crashInfo);
11666            return true;
11667        } else {
11668            return false;
11669        }
11670    }
11671
11672    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11673            final ApplicationErrorReport.CrashInfo crashInfo) {
11674        final ProcessRecord r = findAppProcess(app, "WTF");
11675        final String processName = app == null ? "system_server"
11676                : (r == null ? "unknown" : r.processName);
11677
11678        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11679                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11680
11681        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11682
11683        return r;
11684    }
11685
11686    /**
11687     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11688     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11689     */
11690    private ProcessRecord findAppProcess(IBinder app, String reason) {
11691        if (app == null) {
11692            return null;
11693        }
11694
11695        synchronized (this) {
11696            final int NP = mProcessNames.getMap().size();
11697            for (int ip=0; ip<NP; ip++) {
11698                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11699                final int NA = apps.size();
11700                for (int ia=0; ia<NA; ia++) {
11701                    ProcessRecord p = apps.valueAt(ia);
11702                    if (p.thread != null && p.thread.asBinder() == app) {
11703                        return p;
11704                    }
11705                }
11706            }
11707
11708            Slog.w(TAG, "Can't find mystery application for " + reason
11709                    + " from pid=" + Binder.getCallingPid()
11710                    + " uid=" + Binder.getCallingUid() + ": " + app);
11711            return null;
11712        }
11713    }
11714
11715    /**
11716     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11717     * to append various headers to the dropbox log text.
11718     */
11719    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11720            StringBuilder sb) {
11721        // Watchdog thread ends up invoking this function (with
11722        // a null ProcessRecord) to add the stack file to dropbox.
11723        // Do not acquire a lock on this (am) in such cases, as it
11724        // could cause a potential deadlock, if and when watchdog
11725        // is invoked due to unavailability of lock on am and it
11726        // would prevent watchdog from killing system_server.
11727        if (process == null) {
11728            sb.append("Process: ").append(processName).append("\n");
11729            return;
11730        }
11731        // Note: ProcessRecord 'process' is guarded by the service
11732        // instance.  (notably process.pkgList, which could otherwise change
11733        // concurrently during execution of this method)
11734        synchronized (this) {
11735            sb.append("Process: ").append(processName).append("\n");
11736            int flags = process.info.flags;
11737            IPackageManager pm = AppGlobals.getPackageManager();
11738            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11739            for (int ip=0; ip<process.pkgList.size(); ip++) {
11740                String pkg = process.pkgList.keyAt(ip);
11741                sb.append("Package: ").append(pkg);
11742                try {
11743                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11744                    if (pi != null) {
11745                        sb.append(" v").append(pi.versionCode);
11746                        if (pi.versionName != null) {
11747                            sb.append(" (").append(pi.versionName).append(")");
11748                        }
11749                    }
11750                } catch (RemoteException e) {
11751                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11752                }
11753                sb.append("\n");
11754            }
11755        }
11756    }
11757
11758    private static String processClass(ProcessRecord process) {
11759        if (process == null || process.pid == MY_PID) {
11760            return "system_server";
11761        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11762            return "system_app";
11763        } else {
11764            return "data_app";
11765        }
11766    }
11767
11768    /**
11769     * Write a description of an error (crash, WTF, ANR) to the drop box.
11770     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11771     * @param process which caused the error, null means the system server
11772     * @param activity which triggered the error, null if unknown
11773     * @param parent activity related to the error, null if unknown
11774     * @param subject line related to the error, null if absent
11775     * @param report in long form describing the error, null if absent
11776     * @param logFile to include in the report, null if none
11777     * @param crashInfo giving an application stack trace, null if absent
11778     */
11779    public void addErrorToDropBox(String eventType,
11780            ProcessRecord process, String processName, ActivityRecord activity,
11781            ActivityRecord parent, String subject,
11782            final String report, final File logFile,
11783            final ApplicationErrorReport.CrashInfo crashInfo) {
11784        // NOTE -- this must never acquire the ActivityManagerService lock,
11785        // otherwise the watchdog may be prevented from resetting the system.
11786
11787        final String dropboxTag = processClass(process) + "_" + eventType;
11788        final DropBoxManager dbox = (DropBoxManager)
11789                mContext.getSystemService(Context.DROPBOX_SERVICE);
11790
11791        // Exit early if the dropbox isn't configured to accept this report type.
11792        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11793
11794        final StringBuilder sb = new StringBuilder(1024);
11795        appendDropBoxProcessHeaders(process, processName, sb);
11796        if (activity != null) {
11797            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11798        }
11799        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11800            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11801        }
11802        if (parent != null && parent != activity) {
11803            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11804        }
11805        if (subject != null) {
11806            sb.append("Subject: ").append(subject).append("\n");
11807        }
11808        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11809        if (Debug.isDebuggerConnected()) {
11810            sb.append("Debugger: Connected\n");
11811        }
11812        sb.append("\n");
11813
11814        // Do the rest in a worker thread to avoid blocking the caller on I/O
11815        // (After this point, we shouldn't access AMS internal data structures.)
11816        Thread worker = new Thread("Error dump: " + dropboxTag) {
11817            @Override
11818            public void run() {
11819                if (report != null) {
11820                    sb.append(report);
11821                }
11822                if (logFile != null) {
11823                    try {
11824                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11825                                    "\n\n[[TRUNCATED]]"));
11826                    } catch (IOException e) {
11827                        Slog.e(TAG, "Error reading " + logFile, e);
11828                    }
11829                }
11830                if (crashInfo != null && crashInfo.stackTrace != null) {
11831                    sb.append(crashInfo.stackTrace);
11832                }
11833
11834                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11835                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11836                if (lines > 0) {
11837                    sb.append("\n");
11838
11839                    // Merge several logcat streams, and take the last N lines
11840                    InputStreamReader input = null;
11841                    try {
11842                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11843                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11844                                "-b", "crash",
11845                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11846
11847                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11848                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11849                        input = new InputStreamReader(logcat.getInputStream());
11850
11851                        int num;
11852                        char[] buf = new char[8192];
11853                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11854                    } catch (IOException e) {
11855                        Slog.e(TAG, "Error running logcat", e);
11856                    } finally {
11857                        if (input != null) try { input.close(); } catch (IOException e) {}
11858                    }
11859                }
11860
11861                dbox.addText(dropboxTag, sb.toString());
11862            }
11863        };
11864
11865        if (process == null) {
11866            // If process is null, we are being called from some internal code
11867            // and may be about to die -- run this synchronously.
11868            worker.run();
11869        } else {
11870            worker.start();
11871        }
11872    }
11873
11874    /**
11875     * Bring up the "unexpected error" dialog box for a crashing app.
11876     * Deal with edge cases (intercepts from instrumented applications,
11877     * ActivityController, error intent receivers, that sort of thing).
11878     * @param r the application crashing
11879     * @param crashInfo describing the failure
11880     */
11881    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11882        long timeMillis = System.currentTimeMillis();
11883        String shortMsg = crashInfo.exceptionClassName;
11884        String longMsg = crashInfo.exceptionMessage;
11885        String stackTrace = crashInfo.stackTrace;
11886        if (shortMsg != null && longMsg != null) {
11887            longMsg = shortMsg + ": " + longMsg;
11888        } else if (shortMsg != null) {
11889            longMsg = shortMsg;
11890        }
11891
11892        AppErrorResult result = new AppErrorResult();
11893        synchronized (this) {
11894            if (mController != null) {
11895                try {
11896                    String name = r != null ? r.processName : null;
11897                    int pid = r != null ? r.pid : Binder.getCallingPid();
11898                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11899                    if (!mController.appCrashed(name, pid,
11900                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11901                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11902                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11903                            Slog.w(TAG, "Skip killing native crashed app " + name
11904                                    + "(" + pid + ") during testing");
11905                        } else {
11906                            Slog.w(TAG, "Force-killing crashed app " + name
11907                                    + " at watcher's request");
11908                            if (r != null) {
11909                                r.kill("crash", true);
11910                            } else {
11911                                // Huh.
11912                                Process.killProcess(pid);
11913                                Process.killProcessGroup(uid, pid);
11914                            }
11915                        }
11916                        return;
11917                    }
11918                } catch (RemoteException e) {
11919                    mController = null;
11920                    Watchdog.getInstance().setActivityController(null);
11921                }
11922            }
11923
11924            final long origId = Binder.clearCallingIdentity();
11925
11926            // If this process is running instrumentation, finish it.
11927            if (r != null && r.instrumentationClass != null) {
11928                Slog.w(TAG, "Error in app " + r.processName
11929                      + " running instrumentation " + r.instrumentationClass + ":");
11930                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11931                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11932                Bundle info = new Bundle();
11933                info.putString("shortMsg", shortMsg);
11934                info.putString("longMsg", longMsg);
11935                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11936                Binder.restoreCallingIdentity(origId);
11937                return;
11938            }
11939
11940            // Log crash in battery stats.
11941            if (r != null) {
11942                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
11943            }
11944
11945            // If we can't identify the process or it's already exceeded its crash quota,
11946            // quit right away without showing a crash dialog.
11947            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11948                Binder.restoreCallingIdentity(origId);
11949                return;
11950            }
11951
11952            Message msg = Message.obtain();
11953            msg.what = SHOW_ERROR_MSG;
11954            HashMap data = new HashMap();
11955            data.put("result", result);
11956            data.put("app", r);
11957            msg.obj = data;
11958            mHandler.sendMessage(msg);
11959
11960            Binder.restoreCallingIdentity(origId);
11961        }
11962
11963        int res = result.get();
11964
11965        Intent appErrorIntent = null;
11966        synchronized (this) {
11967            if (r != null && !r.isolated) {
11968                // XXX Can't keep track of crash time for isolated processes,
11969                // since they don't have a persistent identity.
11970                mProcessCrashTimes.put(r.info.processName, r.uid,
11971                        SystemClock.uptimeMillis());
11972            }
11973            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11974                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11975            }
11976        }
11977
11978        if (appErrorIntent != null) {
11979            try {
11980                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11981            } catch (ActivityNotFoundException e) {
11982                Slog.w(TAG, "bug report receiver dissappeared", e);
11983            }
11984        }
11985    }
11986
11987    Intent createAppErrorIntentLocked(ProcessRecord r,
11988            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11989        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11990        if (report == null) {
11991            return null;
11992        }
11993        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11994        result.setComponent(r.errorReportReceiver);
11995        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11996        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11997        return result;
11998    }
11999
12000    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12001            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12002        if (r.errorReportReceiver == null) {
12003            return null;
12004        }
12005
12006        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12007            return null;
12008        }
12009
12010        ApplicationErrorReport report = new ApplicationErrorReport();
12011        report.packageName = r.info.packageName;
12012        report.installerPackageName = r.errorReportReceiver.getPackageName();
12013        report.processName = r.processName;
12014        report.time = timeMillis;
12015        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12016
12017        if (r.crashing || r.forceCrashReport) {
12018            report.type = ApplicationErrorReport.TYPE_CRASH;
12019            report.crashInfo = crashInfo;
12020        } else if (r.notResponding) {
12021            report.type = ApplicationErrorReport.TYPE_ANR;
12022            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12023
12024            report.anrInfo.activity = r.notRespondingReport.tag;
12025            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12026            report.anrInfo.info = r.notRespondingReport.longMsg;
12027        }
12028
12029        return report;
12030    }
12031
12032    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12033        enforceNotIsolatedCaller("getProcessesInErrorState");
12034        // assume our apps are happy - lazy create the list
12035        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12036
12037        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12038                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12039        int userId = UserHandle.getUserId(Binder.getCallingUid());
12040
12041        synchronized (this) {
12042
12043            // iterate across all processes
12044            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12045                ProcessRecord app = mLruProcesses.get(i);
12046                if (!allUsers && app.userId != userId) {
12047                    continue;
12048                }
12049                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12050                    // This one's in trouble, so we'll generate a report for it
12051                    // crashes are higher priority (in case there's a crash *and* an anr)
12052                    ActivityManager.ProcessErrorStateInfo report = null;
12053                    if (app.crashing) {
12054                        report = app.crashingReport;
12055                    } else if (app.notResponding) {
12056                        report = app.notRespondingReport;
12057                    }
12058
12059                    if (report != null) {
12060                        if (errList == null) {
12061                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12062                        }
12063                        errList.add(report);
12064                    } else {
12065                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12066                                " crashing = " + app.crashing +
12067                                " notResponding = " + app.notResponding);
12068                    }
12069                }
12070            }
12071        }
12072
12073        return errList;
12074    }
12075
12076    static int procStateToImportance(int procState, int memAdj,
12077            ActivityManager.RunningAppProcessInfo currApp) {
12078        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12079        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12080            currApp.lru = memAdj;
12081        } else {
12082            currApp.lru = 0;
12083        }
12084        return imp;
12085    }
12086
12087    private void fillInProcMemInfo(ProcessRecord app,
12088            ActivityManager.RunningAppProcessInfo outInfo) {
12089        outInfo.pid = app.pid;
12090        outInfo.uid = app.info.uid;
12091        if (mHeavyWeightProcess == app) {
12092            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12093        }
12094        if (app.persistent) {
12095            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12096        }
12097        if (app.activities.size() > 0) {
12098            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12099        }
12100        outInfo.lastTrimLevel = app.trimMemoryLevel;
12101        int adj = app.curAdj;
12102        int procState = app.curProcState;
12103        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12104        outInfo.importanceReasonCode = app.adjTypeCode;
12105        outInfo.processState = app.curProcState;
12106    }
12107
12108    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12109        enforceNotIsolatedCaller("getRunningAppProcesses");
12110
12111        final int callingUid = Binder.getCallingUid();
12112
12113        // Lazy instantiation of list
12114        List<ActivityManager.RunningAppProcessInfo> runList = null;
12115        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12116                callingUid) == PackageManager.PERMISSION_GRANTED;
12117        final int userId = UserHandle.getUserId(callingUid);
12118        final boolean allUids = isGetTasksAllowed(
12119                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
12120
12121        synchronized (this) {
12122            // Iterate across all processes
12123            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
12124                ProcessRecord app = mLruProcesses.get(i);
12125                if ((!allUsers && app.userId != userId)
12126                        || (!allUids && app.uid != callingUid)) {
12127                    continue;
12128                }
12129                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12130                    // Generate process state info for running application
12131                    ActivityManager.RunningAppProcessInfo currApp =
12132                        new ActivityManager.RunningAppProcessInfo(app.processName,
12133                                app.pid, app.getPackageList());
12134                    fillInProcMemInfo(app, currApp);
12135                    if (app.adjSource instanceof ProcessRecord) {
12136                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12137                        currApp.importanceReasonImportance =
12138                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12139                                        app.adjSourceProcState);
12140                    } else if (app.adjSource instanceof ActivityRecord) {
12141                        ActivityRecord r = (ActivityRecord)app.adjSource;
12142                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12143                    }
12144                    if (app.adjTarget instanceof ComponentName) {
12145                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12146                    }
12147                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12148                    //        + " lru=" + currApp.lru);
12149                    if (runList == null) {
12150                        runList = new ArrayList<>();
12151                    }
12152                    runList.add(currApp);
12153                }
12154            }
12155        }
12156        return runList;
12157    }
12158
12159    public List<ApplicationInfo> getRunningExternalApplications() {
12160        enforceNotIsolatedCaller("getRunningExternalApplications");
12161        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12162        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12163        if (runningApps != null && runningApps.size() > 0) {
12164            Set<String> extList = new HashSet<String>();
12165            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12166                if (app.pkgList != null) {
12167                    for (String pkg : app.pkgList) {
12168                        extList.add(pkg);
12169                    }
12170                }
12171            }
12172            IPackageManager pm = AppGlobals.getPackageManager();
12173            for (String pkg : extList) {
12174                try {
12175                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12176                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12177                        retList.add(info);
12178                    }
12179                } catch (RemoteException e) {
12180                }
12181            }
12182        }
12183        return retList;
12184    }
12185
12186    @Override
12187    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12188        enforceNotIsolatedCaller("getMyMemoryState");
12189        synchronized (this) {
12190            ProcessRecord proc;
12191            synchronized (mPidsSelfLocked) {
12192                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12193            }
12194            fillInProcMemInfo(proc, outInfo);
12195        }
12196    }
12197
12198    @Override
12199    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12200        if (checkCallingPermission(android.Manifest.permission.DUMP)
12201                != PackageManager.PERMISSION_GRANTED) {
12202            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12203                    + Binder.getCallingPid()
12204                    + ", uid=" + Binder.getCallingUid()
12205                    + " without permission "
12206                    + android.Manifest.permission.DUMP);
12207            return;
12208        }
12209
12210        boolean dumpAll = false;
12211        boolean dumpClient = false;
12212        String dumpPackage = null;
12213
12214        int opti = 0;
12215        while (opti < args.length) {
12216            String opt = args[opti];
12217            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12218                break;
12219            }
12220            opti++;
12221            if ("-a".equals(opt)) {
12222                dumpAll = true;
12223            } else if ("-c".equals(opt)) {
12224                dumpClient = true;
12225            } else if ("-p".equals(opt)) {
12226                if (opti < args.length) {
12227                    dumpPackage = args[opti];
12228                    opti++;
12229                } else {
12230                    pw.println("Error: -p option requires package argument");
12231                    return;
12232                }
12233                dumpClient = true;
12234            } else if ("-h".equals(opt)) {
12235                pw.println("Activity manager dump options:");
12236                pw.println("  [-a] [-c] [-p package] [-h] [cmd] ...");
12237                pw.println("  cmd may be one of:");
12238                pw.println("    a[ctivities]: activity stack state");
12239                pw.println("    r[recents]: recent activities state");
12240                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12241                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12242                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12243                pw.println("    o[om]: out of memory management");
12244                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12245                pw.println("    provider [COMP_SPEC]: provider client-side state");
12246                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12247                pw.println("    as[sociations]: tracked app associations");
12248                pw.println("    service [COMP_SPEC]: service client-side state");
12249                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12250                pw.println("    all: dump all activities");
12251                pw.println("    top: dump the top activity");
12252                pw.println("    write: write all pending state to storage");
12253                pw.println("    track-associations: enable association tracking");
12254                pw.println("    untrack-associations: disable and clear association tracking");
12255                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12256                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12257                pw.println("    a partial substring in a component name, a");
12258                pw.println("    hex object identifier.");
12259                pw.println("  -a: include all available server state.");
12260                pw.println("  -c: include client state.");
12261                pw.println("  -p: limit output to given package.");
12262                return;
12263            } else {
12264                pw.println("Unknown argument: " + opt + "; use -h for help");
12265            }
12266        }
12267
12268        long origId = Binder.clearCallingIdentity();
12269        boolean more = false;
12270        // Is the caller requesting to dump a particular piece of data?
12271        if (opti < args.length) {
12272            String cmd = args[opti];
12273            opti++;
12274            if ("activities".equals(cmd) || "a".equals(cmd)) {
12275                synchronized (this) {
12276                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12277                }
12278            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12279                synchronized (this) {
12280                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
12281                }
12282            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12283                String[] newArgs;
12284                String name;
12285                if (opti >= args.length) {
12286                    name = null;
12287                    newArgs = EMPTY_STRING_ARRAY;
12288                } else {
12289                    dumpPackage = args[opti];
12290                    opti++;
12291                    newArgs = new String[args.length - opti];
12292                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12293                            args.length - opti);
12294                }
12295                synchronized (this) {
12296                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
12297                }
12298            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12299                String[] newArgs;
12300                String name;
12301                if (opti >= args.length) {
12302                    name = null;
12303                    newArgs = EMPTY_STRING_ARRAY;
12304                } else {
12305                    dumpPackage = args[opti];
12306                    opti++;
12307                    newArgs = new String[args.length - opti];
12308                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12309                            args.length - opti);
12310                }
12311                synchronized (this) {
12312                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
12313                }
12314            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12315                String[] newArgs;
12316                String name;
12317                if (opti >= args.length) {
12318                    name = null;
12319                    newArgs = EMPTY_STRING_ARRAY;
12320                } else {
12321                    dumpPackage = args[opti];
12322                    opti++;
12323                    newArgs = new String[args.length - opti];
12324                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12325                            args.length - opti);
12326                }
12327                synchronized (this) {
12328                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
12329                }
12330            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12331                synchronized (this) {
12332                    dumpOomLocked(fd, pw, args, opti, true);
12333                }
12334            } else if ("provider".equals(cmd)) {
12335                String[] newArgs;
12336                String name;
12337                if (opti >= args.length) {
12338                    name = null;
12339                    newArgs = EMPTY_STRING_ARRAY;
12340                } else {
12341                    name = args[opti];
12342                    opti++;
12343                    newArgs = new String[args.length - opti];
12344                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12345                }
12346                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12347                    pw.println("No providers match: " + name);
12348                    pw.println("Use -h for help.");
12349                }
12350            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12351                synchronized (this) {
12352                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12353                }
12354            } else if ("service".equals(cmd)) {
12355                String[] newArgs;
12356                String name;
12357                if (opti >= args.length) {
12358                    name = null;
12359                    newArgs = EMPTY_STRING_ARRAY;
12360                } else {
12361                    name = args[opti];
12362                    opti++;
12363                    newArgs = new String[args.length - opti];
12364                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12365                            args.length - opti);
12366                }
12367                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12368                    pw.println("No services match: " + name);
12369                    pw.println("Use -h for help.");
12370                }
12371            } else if ("package".equals(cmd)) {
12372                String[] newArgs;
12373                if (opti >= args.length) {
12374                    pw.println("package: no package name specified");
12375                    pw.println("Use -h for help.");
12376                } else {
12377                    dumpPackage = args[opti];
12378                    opti++;
12379                    newArgs = new String[args.length - opti];
12380                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12381                            args.length - opti);
12382                    args = newArgs;
12383                    opti = 0;
12384                    more = true;
12385                }
12386            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
12387                synchronized (this) {
12388                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12389                }
12390            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12391                synchronized (this) {
12392                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12393                }
12394            } else if ("write".equals(cmd)) {
12395                mTaskPersister.flush();
12396                pw.println("All tasks persisted.");
12397                return;
12398            } else if ("track-associations".equals(cmd)) {
12399                synchronized (this) {
12400                    if (!mTrackingAssociations) {
12401                        mTrackingAssociations = true;
12402                        pw.println("Association tracking started.");
12403                    } else {
12404                        pw.println("Association tracking already enabled.");
12405                    }
12406                }
12407                return;
12408            } else if ("untrack-associations".equals(cmd)) {
12409                synchronized (this) {
12410                    if (mTrackingAssociations) {
12411                        mTrackingAssociations = false;
12412                        mAssociations.clear();
12413                        pw.println("Association tracking stopped.");
12414                    } else {
12415                        pw.println("Association tracking not running.");
12416                    }
12417                }
12418                return;
12419            } else {
12420                // Dumping a single activity?
12421                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12422                    pw.println("Bad activity command, or no activities match: " + cmd);
12423                    pw.println("Use -h for help.");
12424                }
12425            }
12426            if (!more) {
12427                Binder.restoreCallingIdentity(origId);
12428                return;
12429            }
12430        }
12431
12432        // No piece of data specified, dump everything.
12433        synchronized (this) {
12434            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12435            pw.println();
12436            if (dumpAll) {
12437                pw.println("-------------------------------------------------------------------------------");
12438            }
12439            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12440            pw.println();
12441            if (dumpAll) {
12442                pw.println("-------------------------------------------------------------------------------");
12443            }
12444            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12445            pw.println();
12446            if (dumpAll) {
12447                pw.println("-------------------------------------------------------------------------------");
12448            }
12449            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12450            pw.println();
12451            if (dumpAll) {
12452                pw.println("-------------------------------------------------------------------------------");
12453            }
12454            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12455            pw.println();
12456            if (dumpAll) {
12457                pw.println("-------------------------------------------------------------------------------");
12458            }
12459            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12460            if (mAssociations.size() > 0) {
12461                pw.println();
12462                if (dumpAll) {
12463                    pw.println("-------------------------------------------------------------------------------");
12464                }
12465                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12466            }
12467            pw.println();
12468            if (dumpAll) {
12469                pw.println("-------------------------------------------------------------------------------");
12470            }
12471            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12472        }
12473        Binder.restoreCallingIdentity(origId);
12474    }
12475
12476    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12477            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12478        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12479
12480        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12481                dumpPackage);
12482        boolean needSep = printedAnything;
12483
12484        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12485                dumpPackage, needSep, "  mFocusedActivity: ");
12486        if (printed) {
12487            printedAnything = true;
12488            needSep = false;
12489        }
12490
12491        if (dumpPackage == null) {
12492            if (needSep) {
12493                pw.println();
12494            }
12495            needSep = true;
12496            printedAnything = true;
12497            mStackSupervisor.dump(pw, "  ");
12498        }
12499
12500        if (!printedAnything) {
12501            pw.println("  (nothing)");
12502        }
12503    }
12504
12505    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12506            int opti, boolean dumpAll, String dumpPackage) {
12507        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12508
12509        boolean printedAnything = false;
12510
12511        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12512            boolean printedHeader = false;
12513
12514            final int N = mRecentTasks.size();
12515            for (int i=0; i<N; i++) {
12516                TaskRecord tr = mRecentTasks.get(i);
12517                if (dumpPackage != null) {
12518                    if (tr.realActivity == null ||
12519                            !dumpPackage.equals(tr.realActivity)) {
12520                        continue;
12521                    }
12522                }
12523                if (!printedHeader) {
12524                    pw.println("  Recent tasks:");
12525                    printedHeader = true;
12526                    printedAnything = true;
12527                }
12528                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12529                        pw.println(tr);
12530                if (dumpAll) {
12531                    mRecentTasks.get(i).dump(pw, "    ");
12532                }
12533            }
12534        }
12535
12536        if (!printedAnything) {
12537            pw.println("  (nothing)");
12538        }
12539    }
12540
12541    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12542            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12543        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
12544
12545        int dumpUid = 0;
12546        if (dumpPackage != null) {
12547            IPackageManager pm = AppGlobals.getPackageManager();
12548            try {
12549                dumpUid = pm.getPackageUid(dumpPackage, 0);
12550            } catch (RemoteException e) {
12551            }
12552        }
12553
12554        boolean printedAnything = false;
12555
12556        final long now = SystemClock.uptimeMillis();
12557
12558        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
12559            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
12560                    = mAssociations.valueAt(i1);
12561            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
12562                SparseArray<ArrayMap<String, Association>> sourceUids
12563                        = targetComponents.valueAt(i2);
12564                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
12565                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
12566                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
12567                        Association ass = sourceProcesses.valueAt(i4);
12568                        if (dumpPackage != null) {
12569                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
12570                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
12571                                continue;
12572                            }
12573                        }
12574                        printedAnything = true;
12575                        pw.print("  ");
12576                        pw.print(ass.mTargetProcess);
12577                        pw.print("/");
12578                        UserHandle.formatUid(pw, ass.mTargetUid);
12579                        pw.print(" <- ");
12580                        pw.print(ass.mSourceProcess);
12581                        pw.print("/");
12582                        UserHandle.formatUid(pw, ass.mSourceUid);
12583                        pw.println();
12584                        pw.print("    via ");
12585                        pw.print(ass.mTargetComponent.flattenToShortString());
12586                        pw.println();
12587                        pw.print("    ");
12588                        long dur = ass.mTime;
12589                        if (ass.mNesting > 0) {
12590                            dur += now - ass.mStartTime;
12591                        }
12592                        TimeUtils.formatDuration(dur, pw);
12593                        pw.print(" (");
12594                        pw.print(ass.mCount);
12595                        pw.println(" times)");
12596                        if (ass.mNesting > 0) {
12597                            pw.print("    ");
12598                            pw.print(" Currently active: ");
12599                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
12600                            pw.println();
12601                        }
12602                    }
12603                }
12604            }
12605
12606        }
12607
12608        if (!printedAnything) {
12609            pw.println("  (nothing)");
12610        }
12611    }
12612
12613    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12614            int opti, boolean dumpAll, String dumpPackage) {
12615        boolean needSep = false;
12616        boolean printedAnything = false;
12617        int numPers = 0;
12618
12619        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12620
12621        if (dumpAll) {
12622            final int NP = mProcessNames.getMap().size();
12623            for (int ip=0; ip<NP; ip++) {
12624                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12625                final int NA = procs.size();
12626                for (int ia=0; ia<NA; ia++) {
12627                    ProcessRecord r = procs.valueAt(ia);
12628                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12629                        continue;
12630                    }
12631                    if (!needSep) {
12632                        pw.println("  All known processes:");
12633                        needSep = true;
12634                        printedAnything = true;
12635                    }
12636                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12637                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12638                        pw.print(" "); pw.println(r);
12639                    r.dump(pw, "    ");
12640                    if (r.persistent) {
12641                        numPers++;
12642                    }
12643                }
12644            }
12645        }
12646
12647        if (mIsolatedProcesses.size() > 0) {
12648            boolean printed = false;
12649            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12650                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12651                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12652                    continue;
12653                }
12654                if (!printed) {
12655                    if (needSep) {
12656                        pw.println();
12657                    }
12658                    pw.println("  Isolated process list (sorted by uid):");
12659                    printedAnything = true;
12660                    printed = true;
12661                    needSep = true;
12662                }
12663                pw.println(String.format("%sIsolated #%2d: %s",
12664                        "    ", i, r.toString()));
12665            }
12666        }
12667
12668        if (mLruProcesses.size() > 0) {
12669            if (needSep) {
12670                pw.println();
12671            }
12672            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12673                    pw.print(" total, non-act at ");
12674                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12675                    pw.print(", non-svc at ");
12676                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12677                    pw.println("):");
12678            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12679            needSep = true;
12680            printedAnything = true;
12681        }
12682
12683        if (dumpAll || dumpPackage != null) {
12684            synchronized (mPidsSelfLocked) {
12685                boolean printed = false;
12686                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12687                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12688                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12689                        continue;
12690                    }
12691                    if (!printed) {
12692                        if (needSep) pw.println();
12693                        needSep = true;
12694                        pw.println("  PID mappings:");
12695                        printed = true;
12696                        printedAnything = true;
12697                    }
12698                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12699                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12700                }
12701            }
12702        }
12703
12704        if (mForegroundProcesses.size() > 0) {
12705            synchronized (mPidsSelfLocked) {
12706                boolean printed = false;
12707                for (int i=0; i<mForegroundProcesses.size(); i++) {
12708                    ProcessRecord r = mPidsSelfLocked.get(
12709                            mForegroundProcesses.valueAt(i).pid);
12710                    if (dumpPackage != null && (r == null
12711                            || !r.pkgList.containsKey(dumpPackage))) {
12712                        continue;
12713                    }
12714                    if (!printed) {
12715                        if (needSep) pw.println();
12716                        needSep = true;
12717                        pw.println("  Foreground Processes:");
12718                        printed = true;
12719                        printedAnything = true;
12720                    }
12721                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12722                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12723                }
12724            }
12725        }
12726
12727        if (mPersistentStartingProcesses.size() > 0) {
12728            if (needSep) pw.println();
12729            needSep = true;
12730            printedAnything = true;
12731            pw.println("  Persisent processes that are starting:");
12732            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12733                    "Starting Norm", "Restarting PERS", dumpPackage);
12734        }
12735
12736        if (mRemovedProcesses.size() > 0) {
12737            if (needSep) pw.println();
12738            needSep = true;
12739            printedAnything = true;
12740            pw.println("  Processes that are being removed:");
12741            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12742                    "Removed Norm", "Removed PERS", dumpPackage);
12743        }
12744
12745        if (mProcessesOnHold.size() > 0) {
12746            if (needSep) pw.println();
12747            needSep = true;
12748            printedAnything = true;
12749            pw.println("  Processes that are on old until the system is ready:");
12750            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12751                    "OnHold Norm", "OnHold PERS", dumpPackage);
12752        }
12753
12754        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12755
12756        if (mProcessCrashTimes.getMap().size() > 0) {
12757            boolean printed = false;
12758            long now = SystemClock.uptimeMillis();
12759            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12760            final int NP = pmap.size();
12761            for (int ip=0; ip<NP; ip++) {
12762                String pname = pmap.keyAt(ip);
12763                SparseArray<Long> uids = pmap.valueAt(ip);
12764                final int N = uids.size();
12765                for (int i=0; i<N; i++) {
12766                    int puid = uids.keyAt(i);
12767                    ProcessRecord r = mProcessNames.get(pname, puid);
12768                    if (dumpPackage != null && (r == null
12769                            || !r.pkgList.containsKey(dumpPackage))) {
12770                        continue;
12771                    }
12772                    if (!printed) {
12773                        if (needSep) pw.println();
12774                        needSep = true;
12775                        pw.println("  Time since processes crashed:");
12776                        printed = true;
12777                        printedAnything = true;
12778                    }
12779                    pw.print("    Process "); pw.print(pname);
12780                            pw.print(" uid "); pw.print(puid);
12781                            pw.print(": last crashed ");
12782                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12783                            pw.println(" ago");
12784                }
12785            }
12786        }
12787
12788        if (mBadProcesses.getMap().size() > 0) {
12789            boolean printed = false;
12790            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12791            final int NP = pmap.size();
12792            for (int ip=0; ip<NP; ip++) {
12793                String pname = pmap.keyAt(ip);
12794                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12795                final int N = uids.size();
12796                for (int i=0; i<N; i++) {
12797                    int puid = uids.keyAt(i);
12798                    ProcessRecord r = mProcessNames.get(pname, puid);
12799                    if (dumpPackage != null && (r == null
12800                            || !r.pkgList.containsKey(dumpPackage))) {
12801                        continue;
12802                    }
12803                    if (!printed) {
12804                        if (needSep) pw.println();
12805                        needSep = true;
12806                        pw.println("  Bad processes:");
12807                        printedAnything = true;
12808                    }
12809                    BadProcessInfo info = uids.valueAt(i);
12810                    pw.print("    Bad process "); pw.print(pname);
12811                            pw.print(" uid "); pw.print(puid);
12812                            pw.print(": crashed at time "); pw.println(info.time);
12813                    if (info.shortMsg != null) {
12814                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12815                    }
12816                    if (info.longMsg != null) {
12817                        pw.print("      Long msg: "); pw.println(info.longMsg);
12818                    }
12819                    if (info.stack != null) {
12820                        pw.println("      Stack:");
12821                        int lastPos = 0;
12822                        for (int pos=0; pos<info.stack.length(); pos++) {
12823                            if (info.stack.charAt(pos) == '\n') {
12824                                pw.print("        ");
12825                                pw.write(info.stack, lastPos, pos-lastPos);
12826                                pw.println();
12827                                lastPos = pos+1;
12828                            }
12829                        }
12830                        if (lastPos < info.stack.length()) {
12831                            pw.print("        ");
12832                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12833                            pw.println();
12834                        }
12835                    }
12836                }
12837            }
12838        }
12839
12840        if (dumpPackage == null) {
12841            pw.println();
12842            needSep = false;
12843            pw.println("  mStartedUsers:");
12844            for (int i=0; i<mStartedUsers.size(); i++) {
12845                UserStartedState uss = mStartedUsers.valueAt(i);
12846                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12847                        pw.print(": "); uss.dump("", pw);
12848            }
12849            pw.print("  mStartedUserArray: [");
12850            for (int i=0; i<mStartedUserArray.length; i++) {
12851                if (i > 0) pw.print(", ");
12852                pw.print(mStartedUserArray[i]);
12853            }
12854            pw.println("]");
12855            pw.print("  mUserLru: [");
12856            for (int i=0; i<mUserLru.size(); i++) {
12857                if (i > 0) pw.print(", ");
12858                pw.print(mUserLru.get(i));
12859            }
12860            pw.println("]");
12861            if (dumpAll) {
12862                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12863            }
12864            synchronized (mUserProfileGroupIdsSelfLocked) {
12865                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12866                    pw.println("  mUserProfileGroupIds:");
12867                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12868                        pw.print("    User #");
12869                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12870                        pw.print(" -> profile #");
12871                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12872                    }
12873                }
12874            }
12875        }
12876        if (mHomeProcess != null && (dumpPackage == null
12877                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12878            if (needSep) {
12879                pw.println();
12880                needSep = false;
12881            }
12882            pw.println("  mHomeProcess: " + mHomeProcess);
12883        }
12884        if (mPreviousProcess != null && (dumpPackage == null
12885                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12886            if (needSep) {
12887                pw.println();
12888                needSep = false;
12889            }
12890            pw.println("  mPreviousProcess: " + mPreviousProcess);
12891        }
12892        if (dumpAll) {
12893            StringBuilder sb = new StringBuilder(128);
12894            sb.append("  mPreviousProcessVisibleTime: ");
12895            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12896            pw.println(sb);
12897        }
12898        if (mHeavyWeightProcess != null && (dumpPackage == null
12899                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12900            if (needSep) {
12901                pw.println();
12902                needSep = false;
12903            }
12904            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12905        }
12906        if (dumpPackage == null) {
12907            pw.println("  mConfiguration: " + mConfiguration);
12908        }
12909        if (dumpAll) {
12910            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12911            if (mCompatModePackages.getPackages().size() > 0) {
12912                boolean printed = false;
12913                for (Map.Entry<String, Integer> entry
12914                        : mCompatModePackages.getPackages().entrySet()) {
12915                    String pkg = entry.getKey();
12916                    int mode = entry.getValue();
12917                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12918                        continue;
12919                    }
12920                    if (!printed) {
12921                        pw.println("  mScreenCompatPackages:");
12922                        printed = true;
12923                    }
12924                    pw.print("    "); pw.print(pkg); pw.print(": ");
12925                            pw.print(mode); pw.println();
12926                }
12927            }
12928        }
12929        if (dumpPackage == null) {
12930            pw.println("  mWakefulness="
12931                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
12932            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
12933                    + lockScreenShownToString());
12934            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
12935            if (mRunningVoice != null) {
12936                pw.println("  mRunningVoice=" + mRunningVoice);
12937                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
12938            }
12939        }
12940        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12941                || mOrigWaitForDebugger) {
12942            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12943                    || dumpPackage.equals(mOrigDebugApp)) {
12944                if (needSep) {
12945                    pw.println();
12946                    needSep = false;
12947                }
12948                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12949                        + " mDebugTransient=" + mDebugTransient
12950                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12951            }
12952        }
12953        if (mMemWatchProcesses.getMap().size() > 0) {
12954            pw.println("  Mem watch processes:");
12955            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
12956                    = mMemWatchProcesses.getMap();
12957            for (int i=0; i<procs.size(); i++) {
12958                final String proc = procs.keyAt(i);
12959                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
12960                for (int j=0; j<uids.size(); j++) {
12961                    if (needSep) {
12962                        pw.println();
12963                        needSep = false;
12964                    }
12965                    StringBuilder sb = new StringBuilder();
12966                    sb.append("    ").append(proc).append('/');
12967                    UserHandle.formatUid(sb, uids.keyAt(j));
12968                    Pair<Long, String> val = uids.valueAt(j);
12969                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
12970                    if (val.second != null) {
12971                        sb.append(", report to ").append(val.second);
12972                    }
12973                    pw.println(sb.toString());
12974                }
12975            }
12976            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
12977            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
12978            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
12979                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
12980        }
12981        if (mOpenGlTraceApp != null) {
12982            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12983                if (needSep) {
12984                    pw.println();
12985                    needSep = false;
12986                }
12987                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12988            }
12989        }
12990        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12991                || mProfileFd != null) {
12992            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12993                if (needSep) {
12994                    pw.println();
12995                    needSep = false;
12996                }
12997                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12998                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12999                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13000                        + mAutoStopProfiler);
13001                pw.println("  mProfileType=" + mProfileType);
13002            }
13003        }
13004        if (dumpPackage == null) {
13005            if (mAlwaysFinishActivities || mController != null) {
13006                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
13007                        + " mController=" + mController);
13008            }
13009            if (dumpAll) {
13010                pw.println("  Total persistent processes: " + numPers);
13011                pw.println("  mProcessesReady=" + mProcessesReady
13012                        + " mSystemReady=" + mSystemReady
13013                        + " mBooted=" + mBooted
13014                        + " mFactoryTest=" + mFactoryTest);
13015                pw.println("  mBooting=" + mBooting
13016                        + " mCallFinishBooting=" + mCallFinishBooting
13017                        + " mBootAnimationComplete=" + mBootAnimationComplete);
13018                pw.print("  mLastPowerCheckRealtime=");
13019                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13020                        pw.println("");
13021                pw.print("  mLastPowerCheckUptime=");
13022                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13023                        pw.println("");
13024                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13025                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13026                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13027                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
13028                        + " (" + mLruProcesses.size() + " total)"
13029                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13030                        + " mNumServiceProcs=" + mNumServiceProcs
13031                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13032                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
13033                        + " mLastMemoryLevel" + mLastMemoryLevel
13034                        + " mLastNumProcesses" + mLastNumProcesses);
13035                long now = SystemClock.uptimeMillis();
13036                pw.print("  mLastIdleTime=");
13037                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
13038                        pw.print(" mLowRamSinceLastIdle=");
13039                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13040                        pw.println();
13041            }
13042        }
13043
13044        if (!printedAnything) {
13045            pw.println("  (nothing)");
13046        }
13047    }
13048
13049    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13050            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13051        if (mProcessesToGc.size() > 0) {
13052            boolean printed = false;
13053            long now = SystemClock.uptimeMillis();
13054            for (int i=0; i<mProcessesToGc.size(); i++) {
13055                ProcessRecord proc = mProcessesToGc.get(i);
13056                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13057                    continue;
13058                }
13059                if (!printed) {
13060                    if (needSep) pw.println();
13061                    needSep = true;
13062                    pw.println("  Processes that are waiting to GC:");
13063                    printed = true;
13064                }
13065                pw.print("    Process "); pw.println(proc);
13066                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13067                        pw.print(", last gced=");
13068                        pw.print(now-proc.lastRequestedGc);
13069                        pw.print(" ms ago, last lowMem=");
13070                        pw.print(now-proc.lastLowMemory);
13071                        pw.println(" ms ago");
13072
13073            }
13074        }
13075        return needSep;
13076    }
13077
13078    void printOomLevel(PrintWriter pw, String name, int adj) {
13079        pw.print("    ");
13080        if (adj >= 0) {
13081            pw.print(' ');
13082            if (adj < 10) pw.print(' ');
13083        } else {
13084            if (adj > -10) pw.print(' ');
13085        }
13086        pw.print(adj);
13087        pw.print(": ");
13088        pw.print(name);
13089        pw.print(" (");
13090        pw.print(mProcessList.getMemLevel(adj)/1024);
13091        pw.println(" kB)");
13092    }
13093
13094    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13095            int opti, boolean dumpAll) {
13096        boolean needSep = false;
13097
13098        if (mLruProcesses.size() > 0) {
13099            if (needSep) pw.println();
13100            needSep = true;
13101            pw.println("  OOM levels:");
13102            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13103            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13104            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13105            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13106            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13107            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13108            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13109            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13110            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13111            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13112            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13113            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13114            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13115            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13116
13117            if (needSep) pw.println();
13118            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13119                    pw.print(" total, non-act at ");
13120                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13121                    pw.print(", non-svc at ");
13122                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13123                    pw.println("):");
13124            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13125            needSep = true;
13126        }
13127
13128        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13129
13130        pw.println();
13131        pw.println("  mHomeProcess: " + mHomeProcess);
13132        pw.println("  mPreviousProcess: " + mPreviousProcess);
13133        if (mHeavyWeightProcess != null) {
13134            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13135        }
13136
13137        return true;
13138    }
13139
13140    /**
13141     * There are three ways to call this:
13142     *  - no provider specified: dump all the providers
13143     *  - a flattened component name that matched an existing provider was specified as the
13144     *    first arg: dump that one provider
13145     *  - the first arg isn't the flattened component name of an existing provider:
13146     *    dump all providers whose component contains the first arg as a substring
13147     */
13148    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13149            int opti, boolean dumpAll) {
13150        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13151    }
13152
13153    static class ItemMatcher {
13154        ArrayList<ComponentName> components;
13155        ArrayList<String> strings;
13156        ArrayList<Integer> objects;
13157        boolean all;
13158
13159        ItemMatcher() {
13160            all = true;
13161        }
13162
13163        void build(String name) {
13164            ComponentName componentName = ComponentName.unflattenFromString(name);
13165            if (componentName != null) {
13166                if (components == null) {
13167                    components = new ArrayList<ComponentName>();
13168                }
13169                components.add(componentName);
13170                all = false;
13171            } else {
13172                int objectId = 0;
13173                // Not a '/' separated full component name; maybe an object ID?
13174                try {
13175                    objectId = Integer.parseInt(name, 16);
13176                    if (objects == null) {
13177                        objects = new ArrayList<Integer>();
13178                    }
13179                    objects.add(objectId);
13180                    all = false;
13181                } catch (RuntimeException e) {
13182                    // Not an integer; just do string match.
13183                    if (strings == null) {
13184                        strings = new ArrayList<String>();
13185                    }
13186                    strings.add(name);
13187                    all = false;
13188                }
13189            }
13190        }
13191
13192        int build(String[] args, int opti) {
13193            for (; opti<args.length; opti++) {
13194                String name = args[opti];
13195                if ("--".equals(name)) {
13196                    return opti+1;
13197                }
13198                build(name);
13199            }
13200            return opti;
13201        }
13202
13203        boolean match(Object object, ComponentName comp) {
13204            if (all) {
13205                return true;
13206            }
13207            if (components != null) {
13208                for (int i=0; i<components.size(); i++) {
13209                    if (components.get(i).equals(comp)) {
13210                        return true;
13211                    }
13212                }
13213            }
13214            if (objects != null) {
13215                for (int i=0; i<objects.size(); i++) {
13216                    if (System.identityHashCode(object) == objects.get(i)) {
13217                        return true;
13218                    }
13219                }
13220            }
13221            if (strings != null) {
13222                String flat = comp.flattenToString();
13223                for (int i=0; i<strings.size(); i++) {
13224                    if (flat.contains(strings.get(i))) {
13225                        return true;
13226                    }
13227                }
13228            }
13229            return false;
13230        }
13231    }
13232
13233    /**
13234     * There are three things that cmd can be:
13235     *  - a flattened component name that matches an existing activity
13236     *  - the cmd arg isn't the flattened component name of an existing activity:
13237     *    dump all activity whose component contains the cmd as a substring
13238     *  - A hex number of the ActivityRecord object instance.
13239     */
13240    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13241            int opti, boolean dumpAll) {
13242        ArrayList<ActivityRecord> activities;
13243
13244        synchronized (this) {
13245            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13246        }
13247
13248        if (activities.size() <= 0) {
13249            return false;
13250        }
13251
13252        String[] newArgs = new String[args.length - opti];
13253        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13254
13255        TaskRecord lastTask = null;
13256        boolean needSep = false;
13257        for (int i=activities.size()-1; i>=0; i--) {
13258            ActivityRecord r = activities.get(i);
13259            if (needSep) {
13260                pw.println();
13261            }
13262            needSep = true;
13263            synchronized (this) {
13264                if (lastTask != r.task) {
13265                    lastTask = r.task;
13266                    pw.print("TASK "); pw.print(lastTask.affinity);
13267                            pw.print(" id="); pw.println(lastTask.taskId);
13268                    if (dumpAll) {
13269                        lastTask.dump(pw, "  ");
13270                    }
13271                }
13272            }
13273            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13274        }
13275        return true;
13276    }
13277
13278    /**
13279     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13280     * there is a thread associated with the activity.
13281     */
13282    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13283            final ActivityRecord r, String[] args, boolean dumpAll) {
13284        String innerPrefix = prefix + "  ";
13285        synchronized (this) {
13286            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13287                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13288                    pw.print(" pid=");
13289                    if (r.app != null) pw.println(r.app.pid);
13290                    else pw.println("(not running)");
13291            if (dumpAll) {
13292                r.dump(pw, innerPrefix);
13293            }
13294        }
13295        if (r.app != null && r.app.thread != null) {
13296            // flush anything that is already in the PrintWriter since the thread is going
13297            // to write to the file descriptor directly
13298            pw.flush();
13299            try {
13300                TransferPipe tp = new TransferPipe();
13301                try {
13302                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13303                            r.appToken, innerPrefix, args);
13304                    tp.go(fd);
13305                } finally {
13306                    tp.kill();
13307                }
13308            } catch (IOException e) {
13309                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13310            } catch (RemoteException e) {
13311                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13312            }
13313        }
13314    }
13315
13316    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13317            int opti, boolean dumpAll, String dumpPackage) {
13318        boolean needSep = false;
13319        boolean onlyHistory = false;
13320        boolean printedAnything = false;
13321
13322        if ("history".equals(dumpPackage)) {
13323            if (opti < args.length && "-s".equals(args[opti])) {
13324                dumpAll = false;
13325            }
13326            onlyHistory = true;
13327            dumpPackage = null;
13328        }
13329
13330        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13331        if (!onlyHistory && dumpAll) {
13332            if (mRegisteredReceivers.size() > 0) {
13333                boolean printed = false;
13334                Iterator it = mRegisteredReceivers.values().iterator();
13335                while (it.hasNext()) {
13336                    ReceiverList r = (ReceiverList)it.next();
13337                    if (dumpPackage != null && (r.app == null ||
13338                            !dumpPackage.equals(r.app.info.packageName))) {
13339                        continue;
13340                    }
13341                    if (!printed) {
13342                        pw.println("  Registered Receivers:");
13343                        needSep = true;
13344                        printed = true;
13345                        printedAnything = true;
13346                    }
13347                    pw.print("  * "); pw.println(r);
13348                    r.dump(pw, "    ");
13349                }
13350            }
13351
13352            if (mReceiverResolver.dump(pw, needSep ?
13353                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13354                    "    ", dumpPackage, false, false)) {
13355                needSep = true;
13356                printedAnything = true;
13357            }
13358        }
13359
13360        for (BroadcastQueue q : mBroadcastQueues) {
13361            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13362            printedAnything |= needSep;
13363        }
13364
13365        needSep = true;
13366
13367        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13368            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13369                if (needSep) {
13370                    pw.println();
13371                }
13372                needSep = true;
13373                printedAnything = true;
13374                pw.print("  Sticky broadcasts for user ");
13375                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13376                StringBuilder sb = new StringBuilder(128);
13377                for (Map.Entry<String, ArrayList<Intent>> ent
13378                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13379                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13380                    if (dumpAll) {
13381                        pw.println(":");
13382                        ArrayList<Intent> intents = ent.getValue();
13383                        final int N = intents.size();
13384                        for (int i=0; i<N; i++) {
13385                            sb.setLength(0);
13386                            sb.append("    Intent: ");
13387                            intents.get(i).toShortString(sb, false, true, false, false);
13388                            pw.println(sb.toString());
13389                            Bundle bundle = intents.get(i).getExtras();
13390                            if (bundle != null) {
13391                                pw.print("      ");
13392                                pw.println(bundle.toString());
13393                            }
13394                        }
13395                    } else {
13396                        pw.println("");
13397                    }
13398                }
13399            }
13400        }
13401
13402        if (!onlyHistory && dumpAll) {
13403            pw.println();
13404            for (BroadcastQueue queue : mBroadcastQueues) {
13405                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13406                        + queue.mBroadcastsScheduled);
13407            }
13408            pw.println("  mHandler:");
13409            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13410            needSep = true;
13411            printedAnything = true;
13412        }
13413
13414        if (!printedAnything) {
13415            pw.println("  (nothing)");
13416        }
13417    }
13418
13419    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13420            int opti, boolean dumpAll, String dumpPackage) {
13421        boolean needSep;
13422        boolean printedAnything = false;
13423
13424        ItemMatcher matcher = new ItemMatcher();
13425        matcher.build(args, opti);
13426
13427        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13428
13429        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13430        printedAnything |= needSep;
13431
13432        if (mLaunchingProviders.size() > 0) {
13433            boolean printed = false;
13434            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13435                ContentProviderRecord r = mLaunchingProviders.get(i);
13436                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13437                    continue;
13438                }
13439                if (!printed) {
13440                    if (needSep) pw.println();
13441                    needSep = true;
13442                    pw.println("  Launching content providers:");
13443                    printed = true;
13444                    printedAnything = true;
13445                }
13446                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13447                        pw.println(r);
13448            }
13449        }
13450
13451        if (mGrantedUriPermissions.size() > 0) {
13452            boolean printed = false;
13453            int dumpUid = -2;
13454            if (dumpPackage != null) {
13455                try {
13456                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13457                } catch (NameNotFoundException e) {
13458                    dumpUid = -1;
13459                }
13460            }
13461            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13462                int uid = mGrantedUriPermissions.keyAt(i);
13463                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13464                    continue;
13465                }
13466                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13467                if (!printed) {
13468                    if (needSep) pw.println();
13469                    needSep = true;
13470                    pw.println("  Granted Uri Permissions:");
13471                    printed = true;
13472                    printedAnything = true;
13473                }
13474                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13475                for (UriPermission perm : perms.values()) {
13476                    pw.print("    "); pw.println(perm);
13477                    if (dumpAll) {
13478                        perm.dump(pw, "      ");
13479                    }
13480                }
13481            }
13482        }
13483
13484        if (!printedAnything) {
13485            pw.println("  (nothing)");
13486        }
13487    }
13488
13489    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13490            int opti, boolean dumpAll, String dumpPackage) {
13491        boolean printed = false;
13492
13493        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13494
13495        if (mIntentSenderRecords.size() > 0) {
13496            Iterator<WeakReference<PendingIntentRecord>> it
13497                    = mIntentSenderRecords.values().iterator();
13498            while (it.hasNext()) {
13499                WeakReference<PendingIntentRecord> ref = it.next();
13500                PendingIntentRecord rec = ref != null ? ref.get(): null;
13501                if (dumpPackage != null && (rec == null
13502                        || !dumpPackage.equals(rec.key.packageName))) {
13503                    continue;
13504                }
13505                printed = true;
13506                if (rec != null) {
13507                    pw.print("  * "); pw.println(rec);
13508                    if (dumpAll) {
13509                        rec.dump(pw, "    ");
13510                    }
13511                } else {
13512                    pw.print("  * "); pw.println(ref);
13513                }
13514            }
13515        }
13516
13517        if (!printed) {
13518            pw.println("  (nothing)");
13519        }
13520    }
13521
13522    private static final int dumpProcessList(PrintWriter pw,
13523            ActivityManagerService service, List list,
13524            String prefix, String normalLabel, String persistentLabel,
13525            String dumpPackage) {
13526        int numPers = 0;
13527        final int N = list.size()-1;
13528        for (int i=N; i>=0; i--) {
13529            ProcessRecord r = (ProcessRecord)list.get(i);
13530            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13531                continue;
13532            }
13533            pw.println(String.format("%s%s #%2d: %s",
13534                    prefix, (r.persistent ? persistentLabel : normalLabel),
13535                    i, r.toString()));
13536            if (r.persistent) {
13537                numPers++;
13538            }
13539        }
13540        return numPers;
13541    }
13542
13543    private static final boolean dumpProcessOomList(PrintWriter pw,
13544            ActivityManagerService service, List<ProcessRecord> origList,
13545            String prefix, String normalLabel, String persistentLabel,
13546            boolean inclDetails, String dumpPackage) {
13547
13548        ArrayList<Pair<ProcessRecord, Integer>> list
13549                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13550        for (int i=0; i<origList.size(); i++) {
13551            ProcessRecord r = origList.get(i);
13552            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13553                continue;
13554            }
13555            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13556        }
13557
13558        if (list.size() <= 0) {
13559            return false;
13560        }
13561
13562        Comparator<Pair<ProcessRecord, Integer>> comparator
13563                = new Comparator<Pair<ProcessRecord, Integer>>() {
13564            @Override
13565            public int compare(Pair<ProcessRecord, Integer> object1,
13566                    Pair<ProcessRecord, Integer> object2) {
13567                if (object1.first.setAdj != object2.first.setAdj) {
13568                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13569                }
13570                if (object1.second.intValue() != object2.second.intValue()) {
13571                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13572                }
13573                return 0;
13574            }
13575        };
13576
13577        Collections.sort(list, comparator);
13578
13579        final long curRealtime = SystemClock.elapsedRealtime();
13580        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13581        final long curUptime = SystemClock.uptimeMillis();
13582        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13583
13584        for (int i=list.size()-1; i>=0; i--) {
13585            ProcessRecord r = list.get(i).first;
13586            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13587            char schedGroup;
13588            switch (r.setSchedGroup) {
13589                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13590                    schedGroup = 'B';
13591                    break;
13592                case Process.THREAD_GROUP_DEFAULT:
13593                    schedGroup = 'F';
13594                    break;
13595                default:
13596                    schedGroup = '?';
13597                    break;
13598            }
13599            char foreground;
13600            if (r.foregroundActivities) {
13601                foreground = 'A';
13602            } else if (r.foregroundServices) {
13603                foreground = 'S';
13604            } else {
13605                foreground = ' ';
13606            }
13607            String procState = ProcessList.makeProcStateString(r.curProcState);
13608            pw.print(prefix);
13609            pw.print(r.persistent ? persistentLabel : normalLabel);
13610            pw.print(" #");
13611            int num = (origList.size()-1)-list.get(i).second;
13612            if (num < 10) pw.print(' ');
13613            pw.print(num);
13614            pw.print(": ");
13615            pw.print(oomAdj);
13616            pw.print(' ');
13617            pw.print(schedGroup);
13618            pw.print('/');
13619            pw.print(foreground);
13620            pw.print('/');
13621            pw.print(procState);
13622            pw.print(" trm:");
13623            if (r.trimMemoryLevel < 10) pw.print(' ');
13624            pw.print(r.trimMemoryLevel);
13625            pw.print(' ');
13626            pw.print(r.toShortString());
13627            pw.print(" (");
13628            pw.print(r.adjType);
13629            pw.println(')');
13630            if (r.adjSource != null || r.adjTarget != null) {
13631                pw.print(prefix);
13632                pw.print("    ");
13633                if (r.adjTarget instanceof ComponentName) {
13634                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13635                } else if (r.adjTarget != null) {
13636                    pw.print(r.adjTarget.toString());
13637                } else {
13638                    pw.print("{null}");
13639                }
13640                pw.print("<=");
13641                if (r.adjSource instanceof ProcessRecord) {
13642                    pw.print("Proc{");
13643                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13644                    pw.println("}");
13645                } else if (r.adjSource != null) {
13646                    pw.println(r.adjSource.toString());
13647                } else {
13648                    pw.println("{null}");
13649                }
13650            }
13651            if (inclDetails) {
13652                pw.print(prefix);
13653                pw.print("    ");
13654                pw.print("oom: max="); pw.print(r.maxAdj);
13655                pw.print(" curRaw="); pw.print(r.curRawAdj);
13656                pw.print(" setRaw="); pw.print(r.setRawAdj);
13657                pw.print(" cur="); pw.print(r.curAdj);
13658                pw.print(" set="); pw.println(r.setAdj);
13659                pw.print(prefix);
13660                pw.print("    ");
13661                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13662                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13663                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
13664                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
13665                pw.println();
13666                pw.print(prefix);
13667                pw.print("    ");
13668                pw.print("cached="); pw.print(r.cached);
13669                pw.print(" empty="); pw.print(r.empty);
13670                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13671
13672                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13673                    if (r.lastWakeTime != 0) {
13674                        long wtime;
13675                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13676                        synchronized (stats) {
13677                            wtime = stats.getProcessWakeTime(r.info.uid,
13678                                    r.pid, curRealtime);
13679                        }
13680                        long timeUsed = wtime - r.lastWakeTime;
13681                        pw.print(prefix);
13682                        pw.print("    ");
13683                        pw.print("keep awake over ");
13684                        TimeUtils.formatDuration(realtimeSince, pw);
13685                        pw.print(" used ");
13686                        TimeUtils.formatDuration(timeUsed, pw);
13687                        pw.print(" (");
13688                        pw.print((timeUsed*100)/realtimeSince);
13689                        pw.println("%)");
13690                    }
13691                    if (r.lastCpuTime != 0) {
13692                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13693                        pw.print(prefix);
13694                        pw.print("    ");
13695                        pw.print("run cpu over ");
13696                        TimeUtils.formatDuration(uptimeSince, pw);
13697                        pw.print(" used ");
13698                        TimeUtils.formatDuration(timeUsed, pw);
13699                        pw.print(" (");
13700                        pw.print((timeUsed*100)/uptimeSince);
13701                        pw.println("%)");
13702                    }
13703                }
13704            }
13705        }
13706        return true;
13707    }
13708
13709    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13710            String[] args) {
13711        ArrayList<ProcessRecord> procs;
13712        synchronized (this) {
13713            if (args != null && args.length > start
13714                    && args[start].charAt(0) != '-') {
13715                procs = new ArrayList<ProcessRecord>();
13716                int pid = -1;
13717                try {
13718                    pid = Integer.parseInt(args[start]);
13719                } catch (NumberFormatException e) {
13720                }
13721                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13722                    ProcessRecord proc = mLruProcesses.get(i);
13723                    if (proc.pid == pid) {
13724                        procs.add(proc);
13725                    } else if (allPkgs && proc.pkgList != null
13726                            && proc.pkgList.containsKey(args[start])) {
13727                        procs.add(proc);
13728                    } else if (proc.processName.equals(args[start])) {
13729                        procs.add(proc);
13730                    }
13731                }
13732                if (procs.size() <= 0) {
13733                    return null;
13734                }
13735            } else {
13736                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13737            }
13738        }
13739        return procs;
13740    }
13741
13742    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13743            PrintWriter pw, String[] args) {
13744        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13745        if (procs == null) {
13746            pw.println("No process found for: " + args[0]);
13747            return;
13748        }
13749
13750        long uptime = SystemClock.uptimeMillis();
13751        long realtime = SystemClock.elapsedRealtime();
13752        pw.println("Applications Graphics Acceleration Info:");
13753        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13754
13755        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13756            ProcessRecord r = procs.get(i);
13757            if (r.thread != null) {
13758                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13759                pw.flush();
13760                try {
13761                    TransferPipe tp = new TransferPipe();
13762                    try {
13763                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13764                        tp.go(fd);
13765                    } finally {
13766                        tp.kill();
13767                    }
13768                } catch (IOException e) {
13769                    pw.println("Failure while dumping the app: " + r);
13770                    pw.flush();
13771                } catch (RemoteException e) {
13772                    pw.println("Got a RemoteException while dumping the app " + r);
13773                    pw.flush();
13774                }
13775            }
13776        }
13777    }
13778
13779    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13780        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13781        if (procs == null) {
13782            pw.println("No process found for: " + args[0]);
13783            return;
13784        }
13785
13786        pw.println("Applications Database Info:");
13787
13788        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13789            ProcessRecord r = procs.get(i);
13790            if (r.thread != null) {
13791                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13792                pw.flush();
13793                try {
13794                    TransferPipe tp = new TransferPipe();
13795                    try {
13796                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13797                        tp.go(fd);
13798                    } finally {
13799                        tp.kill();
13800                    }
13801                } catch (IOException e) {
13802                    pw.println("Failure while dumping the app: " + r);
13803                    pw.flush();
13804                } catch (RemoteException e) {
13805                    pw.println("Got a RemoteException while dumping the app " + r);
13806                    pw.flush();
13807                }
13808            }
13809        }
13810    }
13811
13812    final static class MemItem {
13813        final boolean isProc;
13814        final String label;
13815        final String shortLabel;
13816        final long pss;
13817        final int id;
13818        final boolean hasActivities;
13819        ArrayList<MemItem> subitems;
13820
13821        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13822                boolean _hasActivities) {
13823            isProc = true;
13824            label = _label;
13825            shortLabel = _shortLabel;
13826            pss = _pss;
13827            id = _id;
13828            hasActivities = _hasActivities;
13829        }
13830
13831        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13832            isProc = false;
13833            label = _label;
13834            shortLabel = _shortLabel;
13835            pss = _pss;
13836            id = _id;
13837            hasActivities = false;
13838        }
13839    }
13840
13841    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13842            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13843        if (sort && !isCompact) {
13844            Collections.sort(items, new Comparator<MemItem>() {
13845                @Override
13846                public int compare(MemItem lhs, MemItem rhs) {
13847                    if (lhs.pss < rhs.pss) {
13848                        return 1;
13849                    } else if (lhs.pss > rhs.pss) {
13850                        return -1;
13851                    }
13852                    return 0;
13853                }
13854            });
13855        }
13856
13857        for (int i=0; i<items.size(); i++) {
13858            MemItem mi = items.get(i);
13859            if (!isCompact) {
13860                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13861            } else if (mi.isProc) {
13862                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13863                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13864                pw.println(mi.hasActivities ? ",a" : ",e");
13865            } else {
13866                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13867                pw.println(mi.pss);
13868            }
13869            if (mi.subitems != null) {
13870                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13871                        true, isCompact);
13872            }
13873        }
13874    }
13875
13876    // These are in KB.
13877    static final long[] DUMP_MEM_BUCKETS = new long[] {
13878        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13879        120*1024, 160*1024, 200*1024,
13880        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13881        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13882    };
13883
13884    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13885            boolean stackLike) {
13886        int start = label.lastIndexOf('.');
13887        if (start >= 0) start++;
13888        else start = 0;
13889        int end = label.length();
13890        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13891            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13892                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13893                out.append(bucket);
13894                out.append(stackLike ? "MB." : "MB ");
13895                out.append(label, start, end);
13896                return;
13897            }
13898        }
13899        out.append(memKB/1024);
13900        out.append(stackLike ? "MB." : "MB ");
13901        out.append(label, start, end);
13902    }
13903
13904    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13905            ProcessList.NATIVE_ADJ,
13906            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13907            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13908            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13909            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13910            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13911            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13912    };
13913    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13914            "Native",
13915            "System", "Persistent", "Persistent Service", "Foreground",
13916            "Visible", "Perceptible",
13917            "Heavy Weight", "Backup",
13918            "A Services", "Home",
13919            "Previous", "B Services", "Cached"
13920    };
13921    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13922            "native",
13923            "sys", "pers", "persvc", "fore",
13924            "vis", "percept",
13925            "heavy", "backup",
13926            "servicea", "home",
13927            "prev", "serviceb", "cached"
13928    };
13929
13930    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13931            long realtime, boolean isCheckinRequest, boolean isCompact) {
13932        if (isCheckinRequest || isCompact) {
13933            // short checkin version
13934            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13935        } else {
13936            pw.println("Applications Memory Usage (kB):");
13937            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13938        }
13939    }
13940
13941    private static final int KSM_SHARED = 0;
13942    private static final int KSM_SHARING = 1;
13943    private static final int KSM_UNSHARED = 2;
13944    private static final int KSM_VOLATILE = 3;
13945
13946    private final long[] getKsmInfo() {
13947        long[] longOut = new long[4];
13948        final int[] SINGLE_LONG_FORMAT = new int[] {
13949            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13950        };
13951        long[] longTmp = new long[1];
13952        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13953                SINGLE_LONG_FORMAT, null, longTmp, null);
13954        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13955        longTmp[0] = 0;
13956        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13957                SINGLE_LONG_FORMAT, null, longTmp, null);
13958        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13959        longTmp[0] = 0;
13960        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13961                SINGLE_LONG_FORMAT, null, longTmp, null);
13962        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13963        longTmp[0] = 0;
13964        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13965                SINGLE_LONG_FORMAT, null, longTmp, null);
13966        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13967        return longOut;
13968    }
13969
13970    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13971            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13972        boolean dumpDetails = false;
13973        boolean dumpFullDetails = false;
13974        boolean dumpDalvik = false;
13975        boolean oomOnly = false;
13976        boolean isCompact = false;
13977        boolean localOnly = false;
13978        boolean packages = false;
13979
13980        int opti = 0;
13981        while (opti < args.length) {
13982            String opt = args[opti];
13983            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13984                break;
13985            }
13986            opti++;
13987            if ("-a".equals(opt)) {
13988                dumpDetails = true;
13989                dumpFullDetails = true;
13990                dumpDalvik = true;
13991            } else if ("-d".equals(opt)) {
13992                dumpDalvik = true;
13993            } else if ("-c".equals(opt)) {
13994                isCompact = true;
13995            } else if ("--oom".equals(opt)) {
13996                oomOnly = true;
13997            } else if ("--local".equals(opt)) {
13998                localOnly = true;
13999            } else if ("--package".equals(opt)) {
14000                packages = true;
14001            } else if ("-h".equals(opt)) {
14002                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
14003                pw.println("  -a: include all available information for each process.");
14004                pw.println("  -d: include dalvik details.");
14005                pw.println("  -c: dump in a compact machine-parseable representation.");
14006                pw.println("  --oom: only show processes organized by oom adj.");
14007                pw.println("  --local: only collect details locally, don't call process.");
14008                pw.println("  --package: interpret process arg as package, dumping all");
14009                pw.println("             processes that have loaded that package.");
14010                pw.println("If [process] is specified it can be the name or ");
14011                pw.println("pid of a specific process to dump.");
14012                return;
14013            } else {
14014                pw.println("Unknown argument: " + opt + "; use -h for help");
14015            }
14016        }
14017
14018        final boolean isCheckinRequest = scanArgs(args, "--checkin");
14019        long uptime = SystemClock.uptimeMillis();
14020        long realtime = SystemClock.elapsedRealtime();
14021        final long[] tmpLong = new long[1];
14022
14023        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
14024        if (procs == null) {
14025            // No Java processes.  Maybe they want to print a native process.
14026            if (args != null && args.length > opti
14027                    && args[opti].charAt(0) != '-') {
14028                ArrayList<ProcessCpuTracker.Stats> nativeProcs
14029                        = new ArrayList<ProcessCpuTracker.Stats>();
14030                updateCpuStatsNow();
14031                int findPid = -1;
14032                try {
14033                    findPid = Integer.parseInt(args[opti]);
14034                } catch (NumberFormatException e) {
14035                }
14036                synchronized (mProcessCpuTracker) {
14037                    final int N = mProcessCpuTracker.countStats();
14038                    for (int i=0; i<N; i++) {
14039                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14040                        if (st.pid == findPid || (st.baseName != null
14041                                && st.baseName.equals(args[opti]))) {
14042                            nativeProcs.add(st);
14043                        }
14044                    }
14045                }
14046                if (nativeProcs.size() > 0) {
14047                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14048                            isCompact);
14049                    Debug.MemoryInfo mi = null;
14050                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14051                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14052                        final int pid = r.pid;
14053                        if (!isCheckinRequest && dumpDetails) {
14054                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14055                        }
14056                        if (mi == null) {
14057                            mi = new Debug.MemoryInfo();
14058                        }
14059                        if (dumpDetails || (!brief && !oomOnly)) {
14060                            Debug.getMemoryInfo(pid, mi);
14061                        } else {
14062                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14063                            mi.dalvikPrivateDirty = (int)tmpLong[0];
14064                        }
14065                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14066                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14067                        if (isCheckinRequest) {
14068                            pw.println();
14069                        }
14070                    }
14071                    return;
14072                }
14073            }
14074            pw.println("No process found for: " + args[opti]);
14075            return;
14076        }
14077
14078        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14079            dumpDetails = true;
14080        }
14081
14082        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14083
14084        String[] innerArgs = new String[args.length-opti];
14085        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14086
14087        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14088        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14089        long nativePss = 0;
14090        long dalvikPss = 0;
14091        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
14092                EmptyArray.LONG;
14093        long otherPss = 0;
14094        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14095
14096        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14097        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14098                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14099
14100        long totalPss = 0;
14101        long cachedPss = 0;
14102
14103        Debug.MemoryInfo mi = null;
14104        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14105            final ProcessRecord r = procs.get(i);
14106            final IApplicationThread thread;
14107            final int pid;
14108            final int oomAdj;
14109            final boolean hasActivities;
14110            synchronized (this) {
14111                thread = r.thread;
14112                pid = r.pid;
14113                oomAdj = r.getSetAdjWithServices();
14114                hasActivities = r.activities.size() > 0;
14115            }
14116            if (thread != null) {
14117                if (!isCheckinRequest && dumpDetails) {
14118                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14119                }
14120                if (mi == null) {
14121                    mi = new Debug.MemoryInfo();
14122                }
14123                if (dumpDetails || (!brief && !oomOnly)) {
14124                    Debug.getMemoryInfo(pid, mi);
14125                } else {
14126                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14127                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14128                }
14129                if (dumpDetails) {
14130                    if (localOnly) {
14131                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14132                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14133                        if (isCheckinRequest) {
14134                            pw.println();
14135                        }
14136                    } else {
14137                        try {
14138                            pw.flush();
14139                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14140                                    dumpDalvik, innerArgs);
14141                        } catch (RemoteException e) {
14142                            if (!isCheckinRequest) {
14143                                pw.println("Got RemoteException!");
14144                                pw.flush();
14145                            }
14146                        }
14147                    }
14148                }
14149
14150                final long myTotalPss = mi.getTotalPss();
14151                final long myTotalUss = mi.getTotalUss();
14152
14153                synchronized (this) {
14154                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14155                        // Record this for posterity if the process has been stable.
14156                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14157                    }
14158                }
14159
14160                if (!isCheckinRequest && mi != null) {
14161                    totalPss += myTotalPss;
14162                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14163                            (hasActivities ? " / activities)" : ")"),
14164                            r.processName, myTotalPss, pid, hasActivities);
14165                    procMems.add(pssItem);
14166                    procMemsMap.put(pid, pssItem);
14167
14168                    nativePss += mi.nativePss;
14169                    dalvikPss += mi.dalvikPss;
14170                    for (int j=0; j<dalvikSubitemPss.length; j++) {
14171                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
14172                    }
14173                    otherPss += mi.otherPss;
14174                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14175                        long mem = mi.getOtherPss(j);
14176                        miscPss[j] += mem;
14177                        otherPss -= mem;
14178                    }
14179
14180                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14181                        cachedPss += myTotalPss;
14182                    }
14183
14184                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14185                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14186                                || oomIndex == (oomPss.length-1)) {
14187                            oomPss[oomIndex] += myTotalPss;
14188                            if (oomProcs[oomIndex] == null) {
14189                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14190                            }
14191                            oomProcs[oomIndex].add(pssItem);
14192                            break;
14193                        }
14194                    }
14195                }
14196            }
14197        }
14198
14199        long nativeProcTotalPss = 0;
14200
14201        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14202            // If we are showing aggregations, also look for native processes to
14203            // include so that our aggregations are more accurate.
14204            updateCpuStatsNow();
14205            mi = null;
14206            synchronized (mProcessCpuTracker) {
14207                final int N = mProcessCpuTracker.countStats();
14208                for (int i=0; i<N; i++) {
14209                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14210                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14211                        if (mi == null) {
14212                            mi = new Debug.MemoryInfo();
14213                        }
14214                        if (!brief && !oomOnly) {
14215                            Debug.getMemoryInfo(st.pid, mi);
14216                        } else {
14217                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14218                            mi.nativePrivateDirty = (int)tmpLong[0];
14219                        }
14220
14221                        final long myTotalPss = mi.getTotalPss();
14222                        totalPss += myTotalPss;
14223                        nativeProcTotalPss += myTotalPss;
14224
14225                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14226                                st.name, myTotalPss, st.pid, false);
14227                        procMems.add(pssItem);
14228
14229                        nativePss += mi.nativePss;
14230                        dalvikPss += mi.dalvikPss;
14231                        for (int j=0; j<dalvikSubitemPss.length; j++) {
14232                            dalvikSubitemPss[j] += mi.getOtherPss(
14233                                    Debug.MemoryInfo.NUM_OTHER_STATS + j);
14234                        }
14235                        otherPss += mi.otherPss;
14236                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14237                            long mem = mi.getOtherPss(j);
14238                            miscPss[j] += mem;
14239                            otherPss -= mem;
14240                        }
14241                        oomPss[0] += myTotalPss;
14242                        if (oomProcs[0] == null) {
14243                            oomProcs[0] = new ArrayList<MemItem>();
14244                        }
14245                        oomProcs[0].add(pssItem);
14246                    }
14247                }
14248            }
14249
14250            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14251
14252            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14253            final MemItem dalvikItem = new MemItem("Dalvik", "Dalvik", dalvikPss, -2);
14254            if (dalvikSubitemPss.length > 0) {
14255                dalvikItem.subitems = new ArrayList<MemItem>();
14256                for (int j=0; j<dalvikSubitemPss.length; j++) {
14257                    final String name = Debug.MemoryInfo.getOtherLabel(
14258                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
14259                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j], j));
14260                }
14261            }
14262            catMems.add(dalvikItem);
14263            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14264            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14265                String label = Debug.MemoryInfo.getOtherLabel(j);
14266                catMems.add(new MemItem(label, label, miscPss[j], j));
14267            }
14268
14269            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14270            for (int j=0; j<oomPss.length; j++) {
14271                if (oomPss[j] != 0) {
14272                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14273                            : DUMP_MEM_OOM_LABEL[j];
14274                    MemItem item = new MemItem(label, label, oomPss[j],
14275                            DUMP_MEM_OOM_ADJ[j]);
14276                    item.subitems = oomProcs[j];
14277                    oomMems.add(item);
14278                }
14279            }
14280
14281            if (!brief && !oomOnly && !isCompact) {
14282                pw.println();
14283                pw.println("Total PSS by process:");
14284                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14285                pw.println();
14286            }
14287            if (!isCompact) {
14288                pw.println("Total PSS by OOM adjustment:");
14289            }
14290            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14291            if (!brief && !oomOnly) {
14292                PrintWriter out = categoryPw != null ? categoryPw : pw;
14293                if (!isCompact) {
14294                    out.println();
14295                    out.println("Total PSS by category:");
14296                }
14297                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14298            }
14299            if (!isCompact) {
14300                pw.println();
14301            }
14302            MemInfoReader memInfo = new MemInfoReader();
14303            memInfo.readMemInfo();
14304            if (nativeProcTotalPss > 0) {
14305                synchronized (this) {
14306                    final long cachedKb = memInfo.getCachedSizeKb();
14307                    final long freeKb = memInfo.getFreeSizeKb();
14308                    final long zramKb = memInfo.getZramTotalSizeKb();
14309                    final long kernelKb = memInfo.getKernelUsedSizeKb();
14310                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
14311                            kernelKb*1024, nativeProcTotalPss*1024);
14312                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
14313                            nativeProcTotalPss);
14314                }
14315            }
14316            if (!brief) {
14317                if (!isCompact) {
14318                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14319                    pw.print(" kB (status ");
14320                    switch (mLastMemoryLevel) {
14321                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14322                            pw.println("normal)");
14323                            break;
14324                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14325                            pw.println("moderate)");
14326                            break;
14327                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14328                            pw.println("low)");
14329                            break;
14330                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14331                            pw.println("critical)");
14332                            break;
14333                        default:
14334                            pw.print(mLastMemoryLevel);
14335                            pw.println(")");
14336                            break;
14337                    }
14338                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14339                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14340                            pw.print(cachedPss); pw.print(" cached pss + ");
14341                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14342                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14343                } else {
14344                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14345                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14346                            + memInfo.getFreeSizeKb()); pw.print(",");
14347                    pw.println(totalPss - cachedPss);
14348                }
14349            }
14350            if (!isCompact) {
14351                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14352                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14353                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14354                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14355                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14356                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14357                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14358            }
14359            if (!brief) {
14360                if (memInfo.getZramTotalSizeKb() != 0) {
14361                    if (!isCompact) {
14362                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14363                                pw.print(" kB physical used for ");
14364                                pw.print(memInfo.getSwapTotalSizeKb()
14365                                        - memInfo.getSwapFreeSizeKb());
14366                                pw.print(" kB in swap (");
14367                                pw.print(memInfo.getSwapTotalSizeKb());
14368                                pw.println(" kB total swap)");
14369                    } else {
14370                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14371                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14372                                pw.println(memInfo.getSwapFreeSizeKb());
14373                    }
14374                }
14375                final long[] ksm = getKsmInfo();
14376                if (!isCompact) {
14377                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14378                            || ksm[KSM_VOLATILE] != 0) {
14379                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14380                                pw.print(" kB saved from shared ");
14381                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14382                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14383                                pw.print(" kB unshared; ");
14384                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14385                    }
14386                    pw.print("   Tuning: ");
14387                    pw.print(ActivityManager.staticGetMemoryClass());
14388                    pw.print(" (large ");
14389                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14390                    pw.print("), oom ");
14391                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14392                    pw.print(" kB");
14393                    pw.print(", restore limit ");
14394                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14395                    pw.print(" kB");
14396                    if (ActivityManager.isLowRamDeviceStatic()) {
14397                        pw.print(" (low-ram)");
14398                    }
14399                    if (ActivityManager.isHighEndGfx()) {
14400                        pw.print(" (high-end-gfx)");
14401                    }
14402                    pw.println();
14403                } else {
14404                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14405                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14406                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14407                    pw.print("tuning,");
14408                    pw.print(ActivityManager.staticGetMemoryClass());
14409                    pw.print(',');
14410                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14411                    pw.print(',');
14412                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14413                    if (ActivityManager.isLowRamDeviceStatic()) {
14414                        pw.print(",low-ram");
14415                    }
14416                    if (ActivityManager.isHighEndGfx()) {
14417                        pw.print(",high-end-gfx");
14418                    }
14419                    pw.println();
14420                }
14421            }
14422        }
14423    }
14424
14425    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14426            long memtrack, String name) {
14427        sb.append("  ");
14428        sb.append(ProcessList.makeOomAdjString(oomAdj));
14429        sb.append(' ');
14430        sb.append(ProcessList.makeProcStateString(procState));
14431        sb.append(' ');
14432        ProcessList.appendRamKb(sb, pss);
14433        sb.append(" kB: ");
14434        sb.append(name);
14435        if (memtrack > 0) {
14436            sb.append(" (");
14437            sb.append(memtrack);
14438            sb.append(" kB memtrack)");
14439        }
14440    }
14441
14442    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14443        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
14444        sb.append(" (pid ");
14445        sb.append(mi.pid);
14446        sb.append(") ");
14447        sb.append(mi.adjType);
14448        sb.append('\n');
14449        if (mi.adjReason != null) {
14450            sb.append("                      ");
14451            sb.append(mi.adjReason);
14452            sb.append('\n');
14453        }
14454    }
14455
14456    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14457        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14458        for (int i=0, N=memInfos.size(); i<N; i++) {
14459            ProcessMemInfo mi = memInfos.get(i);
14460            infoMap.put(mi.pid, mi);
14461        }
14462        updateCpuStatsNow();
14463        long[] memtrackTmp = new long[1];
14464        synchronized (mProcessCpuTracker) {
14465            final int N = mProcessCpuTracker.countStats();
14466            for (int i=0; i<N; i++) {
14467                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14468                if (st.vsize > 0) {
14469                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
14470                    if (pss > 0) {
14471                        if (infoMap.indexOfKey(st.pid) < 0) {
14472                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14473                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14474                            mi.pss = pss;
14475                            mi.memtrack = memtrackTmp[0];
14476                            memInfos.add(mi);
14477                        }
14478                    }
14479                }
14480            }
14481        }
14482
14483        long totalPss = 0;
14484        long totalMemtrack = 0;
14485        for (int i=0, N=memInfos.size(); i<N; i++) {
14486            ProcessMemInfo mi = memInfos.get(i);
14487            if (mi.pss == 0) {
14488                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
14489                mi.memtrack = memtrackTmp[0];
14490            }
14491            totalPss += mi.pss;
14492            totalMemtrack += mi.memtrack;
14493        }
14494        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14495            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14496                if (lhs.oomAdj != rhs.oomAdj) {
14497                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14498                }
14499                if (lhs.pss != rhs.pss) {
14500                    return lhs.pss < rhs.pss ? 1 : -1;
14501                }
14502                return 0;
14503            }
14504        });
14505
14506        StringBuilder tag = new StringBuilder(128);
14507        StringBuilder stack = new StringBuilder(128);
14508        tag.append("Low on memory -- ");
14509        appendMemBucket(tag, totalPss, "total", false);
14510        appendMemBucket(stack, totalPss, "total", true);
14511
14512        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14513        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14514        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14515
14516        boolean firstLine = true;
14517        int lastOomAdj = Integer.MIN_VALUE;
14518        long extraNativeRam = 0;
14519        long extraNativeMemtrack = 0;
14520        long cachedPss = 0;
14521        for (int i=0, N=memInfos.size(); i<N; i++) {
14522            ProcessMemInfo mi = memInfos.get(i);
14523
14524            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14525                cachedPss += mi.pss;
14526            }
14527
14528            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14529                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14530                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14531                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14532                if (lastOomAdj != mi.oomAdj) {
14533                    lastOomAdj = mi.oomAdj;
14534                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14535                        tag.append(" / ");
14536                    }
14537                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14538                        if (firstLine) {
14539                            stack.append(":");
14540                            firstLine = false;
14541                        }
14542                        stack.append("\n\t at ");
14543                    } else {
14544                        stack.append("$");
14545                    }
14546                } else {
14547                    tag.append(" ");
14548                    stack.append("$");
14549                }
14550                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14551                    appendMemBucket(tag, mi.pss, mi.name, false);
14552                }
14553                appendMemBucket(stack, mi.pss, mi.name, true);
14554                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14555                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14556                    stack.append("(");
14557                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14558                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14559                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14560                            stack.append(":");
14561                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14562                        }
14563                    }
14564                    stack.append(")");
14565                }
14566            }
14567
14568            appendMemInfo(fullNativeBuilder, mi);
14569            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14570                // The short form only has native processes that are >= 512K.
14571                if (mi.pss >= 512) {
14572                    appendMemInfo(shortNativeBuilder, mi);
14573                } else {
14574                    extraNativeRam += mi.pss;
14575                    extraNativeMemtrack += mi.memtrack;
14576                }
14577            } else {
14578                // Short form has all other details, but if we have collected RAM
14579                // from smaller native processes let's dump a summary of that.
14580                if (extraNativeRam > 0) {
14581                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14582                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
14583                    shortNativeBuilder.append('\n');
14584                    extraNativeRam = 0;
14585                }
14586                appendMemInfo(fullJavaBuilder, mi);
14587            }
14588        }
14589
14590        fullJavaBuilder.append("           ");
14591        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14592        fullJavaBuilder.append(" kB: TOTAL");
14593        if (totalMemtrack > 0) {
14594            fullJavaBuilder.append(" (");
14595            fullJavaBuilder.append(totalMemtrack);
14596            fullJavaBuilder.append(" kB memtrack)");
14597        } else {
14598        }
14599        fullJavaBuilder.append("\n");
14600
14601        MemInfoReader memInfo = new MemInfoReader();
14602        memInfo.readMemInfo();
14603        final long[] infos = memInfo.getRawInfo();
14604
14605        StringBuilder memInfoBuilder = new StringBuilder(1024);
14606        Debug.getMemInfo(infos);
14607        memInfoBuilder.append("  MemInfo: ");
14608        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14609        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14610        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14611        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14612        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14613        memInfoBuilder.append("           ");
14614        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14615        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14616        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14617        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14618        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14619            memInfoBuilder.append("  ZRAM: ");
14620            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14621            memInfoBuilder.append(" kB RAM, ");
14622            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14623            memInfoBuilder.append(" kB swap total, ");
14624            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14625            memInfoBuilder.append(" kB swap free\n");
14626        }
14627        final long[] ksm = getKsmInfo();
14628        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14629                || ksm[KSM_VOLATILE] != 0) {
14630            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14631            memInfoBuilder.append(" kB saved from shared ");
14632            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14633            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14634            memInfoBuilder.append(" kB unshared; ");
14635            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14636        }
14637        memInfoBuilder.append("  Free RAM: ");
14638        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14639                + memInfo.getFreeSizeKb());
14640        memInfoBuilder.append(" kB\n");
14641        memInfoBuilder.append("  Used RAM: ");
14642        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14643        memInfoBuilder.append(" kB\n");
14644        memInfoBuilder.append("  Lost RAM: ");
14645        memInfoBuilder.append(memInfo.getTotalSizeKb()
14646                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14647                - memInfo.getKernelUsedSizeKb());
14648        memInfoBuilder.append(" kB\n");
14649        Slog.i(TAG, "Low on memory:");
14650        Slog.i(TAG, shortNativeBuilder.toString());
14651        Slog.i(TAG, fullJavaBuilder.toString());
14652        Slog.i(TAG, memInfoBuilder.toString());
14653
14654        StringBuilder dropBuilder = new StringBuilder(1024);
14655        /*
14656        StringWriter oomSw = new StringWriter();
14657        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14658        StringWriter catSw = new StringWriter();
14659        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14660        String[] emptyArgs = new String[] { };
14661        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14662        oomPw.flush();
14663        String oomString = oomSw.toString();
14664        */
14665        dropBuilder.append("Low on memory:");
14666        dropBuilder.append(stack);
14667        dropBuilder.append('\n');
14668        dropBuilder.append(fullNativeBuilder);
14669        dropBuilder.append(fullJavaBuilder);
14670        dropBuilder.append('\n');
14671        dropBuilder.append(memInfoBuilder);
14672        dropBuilder.append('\n');
14673        /*
14674        dropBuilder.append(oomString);
14675        dropBuilder.append('\n');
14676        */
14677        StringWriter catSw = new StringWriter();
14678        synchronized (ActivityManagerService.this) {
14679            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14680            String[] emptyArgs = new String[] { };
14681            catPw.println();
14682            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14683            catPw.println();
14684            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14685                    false, false, null);
14686            catPw.println();
14687            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14688            catPw.flush();
14689        }
14690        dropBuilder.append(catSw.toString());
14691        addErrorToDropBox("lowmem", null, "system_server", null,
14692                null, tag.toString(), dropBuilder.toString(), null, null);
14693        //Slog.i(TAG, "Sent to dropbox:");
14694        //Slog.i(TAG, dropBuilder.toString());
14695        synchronized (ActivityManagerService.this) {
14696            long now = SystemClock.uptimeMillis();
14697            if (mLastMemUsageReportTime < now) {
14698                mLastMemUsageReportTime = now;
14699            }
14700        }
14701    }
14702
14703    /**
14704     * Searches array of arguments for the specified string
14705     * @param args array of argument strings
14706     * @param value value to search for
14707     * @return true if the value is contained in the array
14708     */
14709    private static boolean scanArgs(String[] args, String value) {
14710        if (args != null) {
14711            for (String arg : args) {
14712                if (value.equals(arg)) {
14713                    return true;
14714                }
14715            }
14716        }
14717        return false;
14718    }
14719
14720    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14721            ContentProviderRecord cpr, boolean always) {
14722        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14723
14724        if (!inLaunching || always) {
14725            synchronized (cpr) {
14726                cpr.launchingApp = null;
14727                cpr.notifyAll();
14728            }
14729            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14730            String names[] = cpr.info.authority.split(";");
14731            for (int j = 0; j < names.length; j++) {
14732                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14733            }
14734        }
14735
14736        for (int i=0; i<cpr.connections.size(); i++) {
14737            ContentProviderConnection conn = cpr.connections.get(i);
14738            if (conn.waiting) {
14739                // If this connection is waiting for the provider, then we don't
14740                // need to mess with its process unless we are always removing
14741                // or for some reason the provider is not currently launching.
14742                if (inLaunching && !always) {
14743                    continue;
14744                }
14745            }
14746            ProcessRecord capp = conn.client;
14747            conn.dead = true;
14748            if (conn.stableCount > 0) {
14749                if (!capp.persistent && capp.thread != null
14750                        && capp.pid != 0
14751                        && capp.pid != MY_PID) {
14752                    capp.kill("depends on provider "
14753                            + cpr.name.flattenToShortString()
14754                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14755                }
14756            } else if (capp.thread != null && conn.provider.provider != null) {
14757                try {
14758                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14759                } catch (RemoteException e) {
14760                }
14761                // In the protocol here, we don't expect the client to correctly
14762                // clean up this connection, we'll just remove it.
14763                cpr.connections.remove(i);
14764                if (conn.client.conProviders.remove(conn)) {
14765                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
14766                }
14767            }
14768        }
14769
14770        if (inLaunching && always) {
14771            mLaunchingProviders.remove(cpr);
14772        }
14773        return inLaunching;
14774    }
14775
14776    /**
14777     * Main code for cleaning up a process when it has gone away.  This is
14778     * called both as a result of the process dying, or directly when stopping
14779     * a process when running in single process mode.
14780     *
14781     * @return Returns true if the given process has been restarted, so the
14782     * app that was passed in must remain on the process lists.
14783     */
14784    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14785            boolean restarting, boolean allowRestart, int index) {
14786        if (index >= 0) {
14787            removeLruProcessLocked(app);
14788            ProcessList.remove(app.pid);
14789        }
14790
14791        mProcessesToGc.remove(app);
14792        mPendingPssProcesses.remove(app);
14793
14794        // Dismiss any open dialogs.
14795        if (app.crashDialog != null && !app.forceCrashReport) {
14796            app.crashDialog.dismiss();
14797            app.crashDialog = null;
14798        }
14799        if (app.anrDialog != null) {
14800            app.anrDialog.dismiss();
14801            app.anrDialog = null;
14802        }
14803        if (app.waitDialog != null) {
14804            app.waitDialog.dismiss();
14805            app.waitDialog = null;
14806        }
14807
14808        app.crashing = false;
14809        app.notResponding = false;
14810
14811        app.resetPackageList(mProcessStats);
14812        app.unlinkDeathRecipient();
14813        app.makeInactive(mProcessStats);
14814        app.waitingToKill = null;
14815        app.forcingToForeground = null;
14816        updateProcessForegroundLocked(app, false, false);
14817        app.foregroundActivities = false;
14818        app.hasShownUi = false;
14819        app.treatLikeActivity = false;
14820        app.hasAboveClient = false;
14821        app.hasClientActivities = false;
14822
14823        mServices.killServicesLocked(app, allowRestart);
14824
14825        boolean restart = false;
14826
14827        // Remove published content providers.
14828        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14829            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14830            final boolean always = app.bad || !allowRestart;
14831            if (removeDyingProviderLocked(app, cpr, always) || always) {
14832                // We left the provider in the launching list, need to
14833                // restart it.
14834                restart = true;
14835            }
14836
14837            cpr.provider = null;
14838            cpr.proc = null;
14839        }
14840        app.pubProviders.clear();
14841
14842        // Take care of any launching providers waiting for this process.
14843        if (checkAppInLaunchingProvidersLocked(app, false)) {
14844            restart = true;
14845        }
14846
14847        // Unregister from connected content providers.
14848        if (!app.conProviders.isEmpty()) {
14849            for (int i=0; i<app.conProviders.size(); i++) {
14850                ContentProviderConnection conn = app.conProviders.get(i);
14851                conn.provider.connections.remove(conn);
14852                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
14853                        conn.provider.name);
14854            }
14855            app.conProviders.clear();
14856        }
14857
14858        // At this point there may be remaining entries in mLaunchingProviders
14859        // where we were the only one waiting, so they are no longer of use.
14860        // Look for these and clean up if found.
14861        // XXX Commented out for now.  Trying to figure out a way to reproduce
14862        // the actual situation to identify what is actually going on.
14863        if (false) {
14864            for (int i=0; i<mLaunchingProviders.size(); i++) {
14865                ContentProviderRecord cpr = (ContentProviderRecord)
14866                        mLaunchingProviders.get(i);
14867                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14868                    synchronized (cpr) {
14869                        cpr.launchingApp = null;
14870                        cpr.notifyAll();
14871                    }
14872                }
14873            }
14874        }
14875
14876        skipCurrentReceiverLocked(app);
14877
14878        // Unregister any receivers.
14879        for (int i=app.receivers.size()-1; i>=0; i--) {
14880            removeReceiverLocked(app.receivers.valueAt(i));
14881        }
14882        app.receivers.clear();
14883
14884        // If the app is undergoing backup, tell the backup manager about it
14885        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14886            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
14887                    + mBackupTarget.appInfo + " died during backup");
14888            try {
14889                IBackupManager bm = IBackupManager.Stub.asInterface(
14890                        ServiceManager.getService(Context.BACKUP_SERVICE));
14891                bm.agentDisconnected(app.info.packageName);
14892            } catch (RemoteException e) {
14893                // can't happen; backup manager is local
14894            }
14895        }
14896
14897        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14898            ProcessChangeItem item = mPendingProcessChanges.get(i);
14899            if (item.pid == app.pid) {
14900                mPendingProcessChanges.remove(i);
14901                mAvailProcessChanges.add(item);
14902            }
14903        }
14904        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14905
14906        // If the caller is restarting this app, then leave it in its
14907        // current lists and let the caller take care of it.
14908        if (restarting) {
14909            return false;
14910        }
14911
14912        if (!app.persistent || app.isolated) {
14913            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
14914                    "Removing non-persistent process during cleanup: " + app);
14915            mProcessNames.remove(app.processName, app.uid);
14916            mIsolatedProcesses.remove(app.uid);
14917            if (mHeavyWeightProcess == app) {
14918                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14919                        mHeavyWeightProcess.userId, 0));
14920                mHeavyWeightProcess = null;
14921            }
14922        } else if (!app.removed) {
14923            // This app is persistent, so we need to keep its record around.
14924            // If it is not already on the pending app list, add it there
14925            // and start a new process for it.
14926            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14927                mPersistentStartingProcesses.add(app);
14928                restart = true;
14929            }
14930        }
14931        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
14932                TAG_CLEANUP, "Clean-up removing on hold: " + app);
14933        mProcessesOnHold.remove(app);
14934
14935        if (app == mHomeProcess) {
14936            mHomeProcess = null;
14937        }
14938        if (app == mPreviousProcess) {
14939            mPreviousProcess = null;
14940        }
14941
14942        if (restart && !app.isolated) {
14943            // We have components that still need to be running in the
14944            // process, so re-launch it.
14945            if (index < 0) {
14946                ProcessList.remove(app.pid);
14947            }
14948            mProcessNames.put(app.processName, app.uid, app);
14949            startProcessLocked(app, "restart", app.processName);
14950            return true;
14951        } else if (app.pid > 0 && app.pid != MY_PID) {
14952            // Goodbye!
14953            boolean removed;
14954            synchronized (mPidsSelfLocked) {
14955                mPidsSelfLocked.remove(app.pid);
14956                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14957            }
14958            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14959            if (app.isolated) {
14960                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14961            }
14962            app.setPid(0);
14963        }
14964        return false;
14965    }
14966
14967    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14968        // Look through the content providers we are waiting to have launched,
14969        // and if any run in this process then either schedule a restart of
14970        // the process or kill the client waiting for it if this process has
14971        // gone bad.
14972        int NL = mLaunchingProviders.size();
14973        boolean restart = false;
14974        for (int i=0; i<NL; i++) {
14975            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14976            if (cpr.launchingApp == app) {
14977                if (!alwaysBad && !app.bad) {
14978                    restart = true;
14979                } else {
14980                    removeDyingProviderLocked(app, cpr, true);
14981                    // cpr should have been removed from mLaunchingProviders
14982                    NL = mLaunchingProviders.size();
14983                    i--;
14984                }
14985            }
14986        }
14987        return restart;
14988    }
14989
14990    // =========================================================
14991    // SERVICES
14992    // =========================================================
14993
14994    @Override
14995    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14996            int flags) {
14997        enforceNotIsolatedCaller("getServices");
14998        synchronized (this) {
14999            return mServices.getRunningServiceInfoLocked(maxNum, flags);
15000        }
15001    }
15002
15003    @Override
15004    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
15005        enforceNotIsolatedCaller("getRunningServiceControlPanel");
15006        synchronized (this) {
15007            return mServices.getRunningServiceControlPanelLocked(name);
15008        }
15009    }
15010
15011    @Override
15012    public ComponentName startService(IApplicationThread caller, Intent service,
15013            String resolvedType, int userId) throws TransactionTooLargeException {
15014        enforceNotIsolatedCaller("startService");
15015        // Refuse possible leaked file descriptors
15016        if (service != null && service.hasFileDescriptors() == true) {
15017            throw new IllegalArgumentException("File descriptors passed in Intent");
15018        }
15019
15020        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15021                "startService: " + service + " type=" + resolvedType);
15022        synchronized(this) {
15023            final int callingPid = Binder.getCallingPid();
15024            final int callingUid = Binder.getCallingUid();
15025            final long origId = Binder.clearCallingIdentity();
15026            ComponentName res = mServices.startServiceLocked(caller, service,
15027                    resolvedType, callingPid, callingUid, userId);
15028            Binder.restoreCallingIdentity(origId);
15029            return res;
15030        }
15031    }
15032
15033    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType, int userId)
15034            throws TransactionTooLargeException {
15035        synchronized(this) {
15036            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15037                    "startServiceInPackage: " + service + " type=" + resolvedType);
15038            final long origId = Binder.clearCallingIdentity();
15039            ComponentName res = mServices.startServiceLocked(null, service,
15040                    resolvedType, -1, uid, userId);
15041            Binder.restoreCallingIdentity(origId);
15042            return res;
15043        }
15044    }
15045
15046    @Override
15047    public int stopService(IApplicationThread caller, Intent service,
15048            String resolvedType, int userId) {
15049        enforceNotIsolatedCaller("stopService");
15050        // Refuse possible leaked file descriptors
15051        if (service != null && service.hasFileDescriptors() == true) {
15052            throw new IllegalArgumentException("File descriptors passed in Intent");
15053        }
15054
15055        synchronized(this) {
15056            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
15057        }
15058    }
15059
15060    @Override
15061    public IBinder peekService(Intent service, String resolvedType) {
15062        enforceNotIsolatedCaller("peekService");
15063        // Refuse possible leaked file descriptors
15064        if (service != null && service.hasFileDescriptors() == true) {
15065            throw new IllegalArgumentException("File descriptors passed in Intent");
15066        }
15067        synchronized(this) {
15068            return mServices.peekServiceLocked(service, resolvedType);
15069        }
15070    }
15071
15072    @Override
15073    public boolean stopServiceToken(ComponentName className, IBinder token,
15074            int startId) {
15075        synchronized(this) {
15076            return mServices.stopServiceTokenLocked(className, token, startId);
15077        }
15078    }
15079
15080    @Override
15081    public void setServiceForeground(ComponentName className, IBinder token,
15082            int id, Notification notification, boolean removeNotification) {
15083        synchronized(this) {
15084            mServices.setServiceForegroundLocked(className, token, id, notification,
15085                    removeNotification);
15086        }
15087    }
15088
15089    @Override
15090    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15091            boolean requireFull, String name, String callerPackage) {
15092        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15093                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15094    }
15095
15096    int unsafeConvertIncomingUser(int userId) {
15097        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15098                ? mCurrentUserId : userId;
15099    }
15100
15101    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15102            int allowMode, String name, String callerPackage) {
15103        final int callingUserId = UserHandle.getUserId(callingUid);
15104        if (callingUserId == userId) {
15105            return userId;
15106        }
15107
15108        // Note that we may be accessing mCurrentUserId outside of a lock...
15109        // shouldn't be a big deal, if this is being called outside
15110        // of a locked context there is intrinsically a race with
15111        // the value the caller will receive and someone else changing it.
15112        // We assume that USER_CURRENT_OR_SELF will use the current user; later
15113        // we will switch to the calling user if access to the current user fails.
15114        int targetUserId = unsafeConvertIncomingUser(userId);
15115
15116        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15117            final boolean allow;
15118            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15119                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15120                // If the caller has this permission, they always pass go.  And collect $200.
15121                allow = true;
15122            } else if (allowMode == ALLOW_FULL_ONLY) {
15123                // We require full access, sucks to be you.
15124                allow = false;
15125            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15126                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15127                // If the caller does not have either permission, they are always doomed.
15128                allow = false;
15129            } else if (allowMode == ALLOW_NON_FULL) {
15130                // We are blanket allowing non-full access, you lucky caller!
15131                allow = true;
15132            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15133                // We may or may not allow this depending on whether the two users are
15134                // in the same profile.
15135                synchronized (mUserProfileGroupIdsSelfLocked) {
15136                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15137                            UserInfo.NO_PROFILE_GROUP_ID);
15138                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15139                            UserInfo.NO_PROFILE_GROUP_ID);
15140                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15141                            && callingProfile == targetProfile;
15142                }
15143            } else {
15144                throw new IllegalArgumentException("Unknown mode: " + allowMode);
15145            }
15146            if (!allow) {
15147                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15148                    // In this case, they would like to just execute as their
15149                    // owner user instead of failing.
15150                    targetUserId = callingUserId;
15151                } else {
15152                    StringBuilder builder = new StringBuilder(128);
15153                    builder.append("Permission Denial: ");
15154                    builder.append(name);
15155                    if (callerPackage != null) {
15156                        builder.append(" from ");
15157                        builder.append(callerPackage);
15158                    }
15159                    builder.append(" asks to run as user ");
15160                    builder.append(userId);
15161                    builder.append(" but is calling from user ");
15162                    builder.append(UserHandle.getUserId(callingUid));
15163                    builder.append("; this requires ");
15164                    builder.append(INTERACT_ACROSS_USERS_FULL);
15165                    if (allowMode != ALLOW_FULL_ONLY) {
15166                        builder.append(" or ");
15167                        builder.append(INTERACT_ACROSS_USERS);
15168                    }
15169                    String msg = builder.toString();
15170                    Slog.w(TAG, msg);
15171                    throw new SecurityException(msg);
15172                }
15173            }
15174        }
15175        if (!allowAll && targetUserId < 0) {
15176            throw new IllegalArgumentException(
15177                    "Call does not support special user #" + targetUserId);
15178        }
15179        // Check shell permission
15180        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15181            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15182                    targetUserId)) {
15183                throw new SecurityException("Shell does not have permission to access user "
15184                        + targetUserId + "\n " + Debug.getCallers(3));
15185            }
15186        }
15187        return targetUserId;
15188    }
15189
15190    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15191            String className, int flags) {
15192        boolean result = false;
15193        // For apps that don't have pre-defined UIDs, check for permission
15194        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15195            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15196                if (ActivityManager.checkUidPermission(
15197                        INTERACT_ACROSS_USERS,
15198                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15199                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15200                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15201                            + " requests FLAG_SINGLE_USER, but app does not hold "
15202                            + INTERACT_ACROSS_USERS;
15203                    Slog.w(TAG, msg);
15204                    throw new SecurityException(msg);
15205                }
15206                // Permission passed
15207                result = true;
15208            }
15209        } else if ("system".equals(componentProcessName)) {
15210            result = true;
15211        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15212            // Phone app and persistent apps are allowed to export singleuser providers.
15213            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15214                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15215        }
15216        if (DEBUG_MU) Slog.v(TAG_MU,
15217                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
15218                + Integer.toHexString(flags) + ") = " + result);
15219        return result;
15220    }
15221
15222    /**
15223     * Checks to see if the caller is in the same app as the singleton
15224     * component, or the component is in a special app. It allows special apps
15225     * to export singleton components but prevents exporting singleton
15226     * components for regular apps.
15227     */
15228    boolean isValidSingletonCall(int callingUid, int componentUid) {
15229        int componentAppId = UserHandle.getAppId(componentUid);
15230        return UserHandle.isSameApp(callingUid, componentUid)
15231                || componentAppId == Process.SYSTEM_UID
15232                || componentAppId == Process.PHONE_UID
15233                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15234                        == PackageManager.PERMISSION_GRANTED;
15235    }
15236
15237    public int bindService(IApplicationThread caller, IBinder token, Intent service,
15238            String resolvedType, IServiceConnection connection, int flags, int userId)
15239            throws TransactionTooLargeException {
15240        enforceNotIsolatedCaller("bindService");
15241
15242        // Refuse possible leaked file descriptors
15243        if (service != null && service.hasFileDescriptors() == true) {
15244            throw new IllegalArgumentException("File descriptors passed in Intent");
15245        }
15246
15247        synchronized(this) {
15248            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15249                    connection, flags, userId);
15250        }
15251    }
15252
15253    public boolean unbindService(IServiceConnection connection) {
15254        synchronized (this) {
15255            return mServices.unbindServiceLocked(connection);
15256        }
15257    }
15258
15259    public void publishService(IBinder token, Intent intent, IBinder service) {
15260        // Refuse possible leaked file descriptors
15261        if (intent != null && intent.hasFileDescriptors() == true) {
15262            throw new IllegalArgumentException("File descriptors passed in Intent");
15263        }
15264
15265        synchronized(this) {
15266            if (!(token instanceof ServiceRecord)) {
15267                throw new IllegalArgumentException("Invalid service token");
15268            }
15269            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15270        }
15271    }
15272
15273    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15274        // Refuse possible leaked file descriptors
15275        if (intent != null && intent.hasFileDescriptors() == true) {
15276            throw new IllegalArgumentException("File descriptors passed in Intent");
15277        }
15278
15279        synchronized(this) {
15280            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15281        }
15282    }
15283
15284    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15285        synchronized(this) {
15286            if (!(token instanceof ServiceRecord)) {
15287                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
15288                throw new IllegalArgumentException("Invalid service token");
15289            }
15290            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15291        }
15292    }
15293
15294    // =========================================================
15295    // BACKUP AND RESTORE
15296    // =========================================================
15297
15298    // Cause the target app to be launched if necessary and its backup agent
15299    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15300    // activity manager to announce its creation.
15301    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15302        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
15303                "bindBackupAgent: app=" + app + " mode=" + backupMode);
15304        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15305
15306        synchronized(this) {
15307            // !!! TODO: currently no check here that we're already bound
15308            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15309            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15310            synchronized (stats) {
15311                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15312            }
15313
15314            // Backup agent is now in use, its package can't be stopped.
15315            try {
15316                AppGlobals.getPackageManager().setPackageStoppedState(
15317                        app.packageName, false, UserHandle.getUserId(app.uid));
15318            } catch (RemoteException e) {
15319            } catch (IllegalArgumentException e) {
15320                Slog.w(TAG, "Failed trying to unstop package "
15321                        + app.packageName + ": " + e);
15322            }
15323
15324            BackupRecord r = new BackupRecord(ss, app, backupMode);
15325            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15326                    ? new ComponentName(app.packageName, app.backupAgentName)
15327                    : new ComponentName("android", "FullBackupAgent");
15328            // startProcessLocked() returns existing proc's record if it's already running
15329            ProcessRecord proc = startProcessLocked(app.processName, app,
15330                    false, 0, "backup", hostingName, false, false, false);
15331            if (proc == null) {
15332                Slog.e(TAG, "Unable to start backup agent process " + r);
15333                return false;
15334            }
15335
15336            r.app = proc;
15337            mBackupTarget = r;
15338            mBackupAppName = app.packageName;
15339
15340            // Try not to kill the process during backup
15341            updateOomAdjLocked(proc);
15342
15343            // If the process is already attached, schedule the creation of the backup agent now.
15344            // If it is not yet live, this will be done when it attaches to the framework.
15345            if (proc.thread != null) {
15346                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
15347                try {
15348                    proc.thread.scheduleCreateBackupAgent(app,
15349                            compatibilityInfoForPackageLocked(app), backupMode);
15350                } catch (RemoteException e) {
15351                    // Will time out on the backup manager side
15352                }
15353            } else {
15354                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
15355            }
15356            // Invariants: at this point, the target app process exists and the application
15357            // is either already running or in the process of coming up.  mBackupTarget and
15358            // mBackupAppName describe the app, so that when it binds back to the AM we
15359            // know that it's scheduled for a backup-agent operation.
15360        }
15361
15362        return true;
15363    }
15364
15365    @Override
15366    public void clearPendingBackup() {
15367        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
15368        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15369
15370        synchronized (this) {
15371            mBackupTarget = null;
15372            mBackupAppName = null;
15373        }
15374    }
15375
15376    // A backup agent has just come up
15377    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15378        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
15379                + " = " + agent);
15380
15381        synchronized(this) {
15382            if (!agentPackageName.equals(mBackupAppName)) {
15383                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15384                return;
15385            }
15386        }
15387
15388        long oldIdent = Binder.clearCallingIdentity();
15389        try {
15390            IBackupManager bm = IBackupManager.Stub.asInterface(
15391                    ServiceManager.getService(Context.BACKUP_SERVICE));
15392            bm.agentConnected(agentPackageName, agent);
15393        } catch (RemoteException e) {
15394            // can't happen; the backup manager service is local
15395        } catch (Exception e) {
15396            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15397            e.printStackTrace();
15398        } finally {
15399            Binder.restoreCallingIdentity(oldIdent);
15400        }
15401    }
15402
15403    // done with this agent
15404    public void unbindBackupAgent(ApplicationInfo appInfo) {
15405        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
15406        if (appInfo == null) {
15407            Slog.w(TAG, "unbind backup agent for null app");
15408            return;
15409        }
15410
15411        synchronized(this) {
15412            try {
15413                if (mBackupAppName == null) {
15414                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15415                    return;
15416                }
15417
15418                if (!mBackupAppName.equals(appInfo.packageName)) {
15419                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15420                    return;
15421                }
15422
15423                // Not backing this app up any more; reset its OOM adjustment
15424                final ProcessRecord proc = mBackupTarget.app;
15425                updateOomAdjLocked(proc);
15426
15427                // If the app crashed during backup, 'thread' will be null here
15428                if (proc.thread != null) {
15429                    try {
15430                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15431                                compatibilityInfoForPackageLocked(appInfo));
15432                    } catch (Exception e) {
15433                        Slog.e(TAG, "Exception when unbinding backup agent:");
15434                        e.printStackTrace();
15435                    }
15436                }
15437            } finally {
15438                mBackupTarget = null;
15439                mBackupAppName = null;
15440            }
15441        }
15442    }
15443    // =========================================================
15444    // BROADCASTS
15445    // =========================================================
15446
15447    boolean isPendingBroadcastProcessLocked(int pid) {
15448        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15449                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15450    }
15451
15452    void skipPendingBroadcastLocked(int pid) {
15453            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15454            for (BroadcastQueue queue : mBroadcastQueues) {
15455                queue.skipPendingBroadcastLocked(pid);
15456            }
15457    }
15458
15459    // The app just attached; send any pending broadcasts that it should receive
15460    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15461        boolean didSomething = false;
15462        for (BroadcastQueue queue : mBroadcastQueues) {
15463            didSomething |= queue.sendPendingBroadcastsLocked(app);
15464        }
15465        return didSomething;
15466    }
15467
15468    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15469            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15470        enforceNotIsolatedCaller("registerReceiver");
15471        ArrayList<Intent> stickyIntents = null;
15472        ProcessRecord callerApp = null;
15473        int callingUid;
15474        int callingPid;
15475        synchronized(this) {
15476            if (caller != null) {
15477                callerApp = getRecordForAppLocked(caller);
15478                if (callerApp == null) {
15479                    throw new SecurityException(
15480                            "Unable to find app for caller " + caller
15481                            + " (pid=" + Binder.getCallingPid()
15482                            + ") when registering receiver " + receiver);
15483                }
15484                if (callerApp.info.uid != Process.SYSTEM_UID &&
15485                        !callerApp.pkgList.containsKey(callerPackage) &&
15486                        !"android".equals(callerPackage)) {
15487                    throw new SecurityException("Given caller package " + callerPackage
15488                            + " is not running in process " + callerApp);
15489                }
15490                callingUid = callerApp.info.uid;
15491                callingPid = callerApp.pid;
15492            } else {
15493                callerPackage = null;
15494                callingUid = Binder.getCallingUid();
15495                callingPid = Binder.getCallingPid();
15496            }
15497
15498            userId = handleIncomingUser(callingPid, callingUid, userId,
15499                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15500
15501            Iterator<String> actions = filter.actionsIterator();
15502            if (actions == null) {
15503                ArrayList<String> noAction = new ArrayList<String>(1);
15504                noAction.add(null);
15505                actions = noAction.iterator();
15506            }
15507
15508            // Collect stickies of users
15509            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
15510            while (actions.hasNext()) {
15511                String action = actions.next();
15512                for (int id : userIds) {
15513                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
15514                    if (stickies != null) {
15515                        ArrayList<Intent> intents = stickies.get(action);
15516                        if (intents != null) {
15517                            if (stickyIntents == null) {
15518                                stickyIntents = new ArrayList<Intent>();
15519                            }
15520                            stickyIntents.addAll(intents);
15521                        }
15522                    }
15523                }
15524            }
15525        }
15526
15527        ArrayList<Intent> allSticky = null;
15528        if (stickyIntents != null) {
15529            final ContentResolver resolver = mContext.getContentResolver();
15530            // Look for any matching sticky broadcasts...
15531            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
15532                Intent intent = stickyIntents.get(i);
15533                // If intent has scheme "content", it will need to acccess
15534                // provider that needs to lock mProviderMap in ActivityThread
15535                // and also it may need to wait application response, so we
15536                // cannot lock ActivityManagerService here.
15537                if (filter.match(resolver, intent, true, TAG) >= 0) {
15538                    if (allSticky == null) {
15539                        allSticky = new ArrayList<Intent>();
15540                    }
15541                    allSticky.add(intent);
15542                }
15543            }
15544        }
15545
15546        // The first sticky in the list is returned directly back to the client.
15547        Intent sticky = allSticky != null ? allSticky.get(0) : null;
15548        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
15549        if (receiver == null) {
15550            return sticky;
15551        }
15552
15553        synchronized (this) {
15554            if (callerApp != null && (callerApp.thread == null
15555                    || callerApp.thread.asBinder() != caller.asBinder())) {
15556                // Original caller already died
15557                return null;
15558            }
15559            ReceiverList rl
15560                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15561            if (rl == null) {
15562                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15563                        userId, receiver);
15564                if (rl.app != null) {
15565                    rl.app.receivers.add(rl);
15566                } else {
15567                    try {
15568                        receiver.asBinder().linkToDeath(rl, 0);
15569                    } catch (RemoteException e) {
15570                        return sticky;
15571                    }
15572                    rl.linkedToDeath = true;
15573                }
15574                mRegisteredReceivers.put(receiver.asBinder(), rl);
15575            } else if (rl.uid != callingUid) {
15576                throw new IllegalArgumentException(
15577                        "Receiver requested to register for uid " + callingUid
15578                        + " was previously registered for uid " + rl.uid);
15579            } else if (rl.pid != callingPid) {
15580                throw new IllegalArgumentException(
15581                        "Receiver requested to register for pid " + callingPid
15582                        + " was previously registered for pid " + rl.pid);
15583            } else if (rl.userId != userId) {
15584                throw new IllegalArgumentException(
15585                        "Receiver requested to register for user " + userId
15586                        + " was previously registered for user " + rl.userId);
15587            }
15588            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15589                    permission, callingUid, userId);
15590            rl.add(bf);
15591            if (!bf.debugCheck()) {
15592                Slog.w(TAG, "==> For Dynamic broadast");
15593            }
15594            mReceiverResolver.addFilter(bf);
15595
15596            // Enqueue broadcasts for all existing stickies that match
15597            // this filter.
15598            if (allSticky != null) {
15599                ArrayList receivers = new ArrayList();
15600                receivers.add(bf);
15601
15602                int N = allSticky.size();
15603                for (int i=0; i<N; i++) {
15604                    Intent intent = (Intent)allSticky.get(i);
15605                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15606                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15607                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15608                            null, null, false, true, true, -1);
15609                    queue.enqueueParallelBroadcastLocked(r);
15610                    queue.scheduleBroadcastsLocked();
15611                }
15612            }
15613
15614            return sticky;
15615        }
15616    }
15617
15618    public void unregisterReceiver(IIntentReceiver receiver) {
15619        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
15620
15621        final long origId = Binder.clearCallingIdentity();
15622        try {
15623            boolean doTrim = false;
15624
15625            synchronized(this) {
15626                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15627                if (rl != null) {
15628                    final BroadcastRecord r = rl.curBroadcast;
15629                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
15630                        final boolean doNext = r.queue.finishReceiverLocked(
15631                                r, r.resultCode, r.resultData, r.resultExtras,
15632                                r.resultAbort, false);
15633                        if (doNext) {
15634                            doTrim = true;
15635                            r.queue.processNextBroadcast(false);
15636                        }
15637                    }
15638
15639                    if (rl.app != null) {
15640                        rl.app.receivers.remove(rl);
15641                    }
15642                    removeReceiverLocked(rl);
15643                    if (rl.linkedToDeath) {
15644                        rl.linkedToDeath = false;
15645                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15646                    }
15647                }
15648            }
15649
15650            // If we actually concluded any broadcasts, we might now be able
15651            // to trim the recipients' apps from our working set
15652            if (doTrim) {
15653                trimApplications();
15654                return;
15655            }
15656
15657        } finally {
15658            Binder.restoreCallingIdentity(origId);
15659        }
15660    }
15661
15662    void removeReceiverLocked(ReceiverList rl) {
15663        mRegisteredReceivers.remove(rl.receiver.asBinder());
15664        int N = rl.size();
15665        for (int i=0; i<N; i++) {
15666            mReceiverResolver.removeFilter(rl.get(i));
15667        }
15668    }
15669
15670    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15671        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15672            ProcessRecord r = mLruProcesses.get(i);
15673            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15674                try {
15675                    r.thread.dispatchPackageBroadcast(cmd, packages);
15676                } catch (RemoteException ex) {
15677                }
15678            }
15679        }
15680    }
15681
15682    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15683            int callingUid, int[] users) {
15684        List<ResolveInfo> receivers = null;
15685        try {
15686            HashSet<ComponentName> singleUserReceivers = null;
15687            boolean scannedFirstReceivers = false;
15688            for (int user : users) {
15689                // Skip users that have Shell restrictions
15690                if (callingUid == Process.SHELL_UID
15691                        && getUserManagerLocked().hasUserRestriction(
15692                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15693                    continue;
15694                }
15695                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15696                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15697                if (user != UserHandle.USER_OWNER && newReceivers != null) {
15698                    // If this is not the primary user, we need to check for
15699                    // any receivers that should be filtered out.
15700                    for (int i=0; i<newReceivers.size(); i++) {
15701                        ResolveInfo ri = newReceivers.get(i);
15702                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15703                            newReceivers.remove(i);
15704                            i--;
15705                        }
15706                    }
15707                }
15708                if (newReceivers != null && newReceivers.size() == 0) {
15709                    newReceivers = null;
15710                }
15711                if (receivers == null) {
15712                    receivers = newReceivers;
15713                } else if (newReceivers != null) {
15714                    // We need to concatenate the additional receivers
15715                    // found with what we have do far.  This would be easy,
15716                    // but we also need to de-dup any receivers that are
15717                    // singleUser.
15718                    if (!scannedFirstReceivers) {
15719                        // Collect any single user receivers we had already retrieved.
15720                        scannedFirstReceivers = true;
15721                        for (int i=0; i<receivers.size(); i++) {
15722                            ResolveInfo ri = receivers.get(i);
15723                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15724                                ComponentName cn = new ComponentName(
15725                                        ri.activityInfo.packageName, ri.activityInfo.name);
15726                                if (singleUserReceivers == null) {
15727                                    singleUserReceivers = new HashSet<ComponentName>();
15728                                }
15729                                singleUserReceivers.add(cn);
15730                            }
15731                        }
15732                    }
15733                    // Add the new results to the existing results, tracking
15734                    // and de-dupping single user receivers.
15735                    for (int i=0; i<newReceivers.size(); i++) {
15736                        ResolveInfo ri = newReceivers.get(i);
15737                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15738                            ComponentName cn = new ComponentName(
15739                                    ri.activityInfo.packageName, ri.activityInfo.name);
15740                            if (singleUserReceivers == null) {
15741                                singleUserReceivers = new HashSet<ComponentName>();
15742                            }
15743                            if (!singleUserReceivers.contains(cn)) {
15744                                singleUserReceivers.add(cn);
15745                                receivers.add(ri);
15746                            }
15747                        } else {
15748                            receivers.add(ri);
15749                        }
15750                    }
15751                }
15752            }
15753        } catch (RemoteException ex) {
15754            // pm is in same process, this will never happen.
15755        }
15756        return receivers;
15757    }
15758
15759    private final int broadcastIntentLocked(ProcessRecord callerApp,
15760            String callerPackage, Intent intent, String resolvedType,
15761            IIntentReceiver resultTo, int resultCode, String resultData,
15762            Bundle map, String requiredPermission, int appOp,
15763            boolean ordered, boolean sticky, int callingPid, int callingUid,
15764            int userId) {
15765        intent = new Intent(intent);
15766
15767        // By default broadcasts do not go to stopped apps.
15768        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15769
15770        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
15771                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15772                + " ordered=" + ordered + " userid=" + userId);
15773        if ((resultTo != null) && !ordered) {
15774            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15775        }
15776
15777        userId = handleIncomingUser(callingPid, callingUid, userId,
15778                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15779
15780        // Make sure that the user who is receiving this broadcast is running.
15781        // If not, we will just skip it. Make an exception for shutdown broadcasts
15782        // and upgrade steps.
15783
15784        if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
15785            if ((callingUid != Process.SYSTEM_UID
15786                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
15787                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
15788                Slog.w(TAG, "Skipping broadcast of " + intent
15789                        + ": user " + userId + " is stopped");
15790                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15791            }
15792        }
15793
15794        /*
15795         * Prevent non-system code (defined here to be non-persistent
15796         * processes) from sending protected broadcasts.
15797         */
15798        int callingAppId = UserHandle.getAppId(callingUid);
15799        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15800            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15801            || callingAppId == Process.NFC_UID || callingUid == 0) {
15802            // Always okay.
15803        } else if (callerApp == null || !callerApp.persistent) {
15804            try {
15805                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15806                        intent.getAction())) {
15807                    String msg = "Permission Denial: not allowed to send broadcast "
15808                            + intent.getAction() + " from pid="
15809                            + callingPid + ", uid=" + callingUid;
15810                    Slog.w(TAG, msg);
15811                    throw new SecurityException(msg);
15812                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15813                    // Special case for compatibility: we don't want apps to send this,
15814                    // but historically it has not been protected and apps may be using it
15815                    // to poke their own app widget.  So, instead of making it protected,
15816                    // just limit it to the caller.
15817                    if (callerApp == null) {
15818                        String msg = "Permission Denial: not allowed to send broadcast "
15819                                + intent.getAction() + " from unknown caller.";
15820                        Slog.w(TAG, msg);
15821                        throw new SecurityException(msg);
15822                    } else if (intent.getComponent() != null) {
15823                        // They are good enough to send to an explicit component...  verify
15824                        // it is being sent to the calling app.
15825                        if (!intent.getComponent().getPackageName().equals(
15826                                callerApp.info.packageName)) {
15827                            String msg = "Permission Denial: not allowed to send broadcast "
15828                                    + intent.getAction() + " to "
15829                                    + intent.getComponent().getPackageName() + " from "
15830                                    + callerApp.info.packageName;
15831                            Slog.w(TAG, msg);
15832                            throw new SecurityException(msg);
15833                        }
15834                    } else {
15835                        // Limit broadcast to their own package.
15836                        intent.setPackage(callerApp.info.packageName);
15837                    }
15838                }
15839            } catch (RemoteException e) {
15840                Slog.w(TAG, "Remote exception", e);
15841                return ActivityManager.BROADCAST_SUCCESS;
15842            }
15843        }
15844
15845        final String action = intent.getAction();
15846        if (action != null) {
15847            switch (action) {
15848                case Intent.ACTION_UID_REMOVED:
15849                case Intent.ACTION_PACKAGE_REMOVED:
15850                case Intent.ACTION_PACKAGE_CHANGED:
15851                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15852                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15853                    // Handle special intents: if this broadcast is from the package
15854                    // manager about a package being removed, we need to remove all of
15855                    // its activities from the history stack.
15856                    if (checkComponentPermission(
15857                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15858                            callingPid, callingUid, -1, true)
15859                            != PackageManager.PERMISSION_GRANTED) {
15860                        String msg = "Permission Denial: " + intent.getAction()
15861                                + " broadcast from " + callerPackage + " (pid=" + callingPid
15862                                + ", uid=" + callingUid + ")"
15863                                + " requires "
15864                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15865                        Slog.w(TAG, msg);
15866                        throw new SecurityException(msg);
15867                    }
15868                    switch (action) {
15869                        case Intent.ACTION_UID_REMOVED:
15870                            final Bundle intentExtras = intent.getExtras();
15871                            final int uid = intentExtras != null
15872                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15873                            if (uid >= 0) {
15874                                BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15875                                synchronized (bs) {
15876                                    bs.removeUidStatsLocked(uid);
15877                                }
15878                                mAppOpsService.uidRemoved(uid);
15879                            }
15880                            break;
15881                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15882                            // If resources are unavailable just force stop all those packages
15883                            // and flush the attribute cache as well.
15884                            String list[] =
15885                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15886                            if (list != null && list.length > 0) {
15887                                for (int i = 0; i < list.length; i++) {
15888                                    forceStopPackageLocked(list[i], -1, false, true, true,
15889                                            false, false, userId, "storage unmount");
15890                                }
15891                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
15892                                sendPackageBroadcastLocked(
15893                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
15894                                        userId);
15895                            }
15896                            break;
15897                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15898                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
15899                            break;
15900                        case Intent.ACTION_PACKAGE_REMOVED:
15901                        case Intent.ACTION_PACKAGE_CHANGED:
15902                            Uri data = intent.getData();
15903                            String ssp;
15904                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15905                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
15906                                boolean fullUninstall = removed &&
15907                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15908                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15909                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
15910                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
15911                                            false, true, true, false, fullUninstall, userId,
15912                                            removed ? "pkg removed" : "pkg changed");
15913                                }
15914                                if (removed) {
15915                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15916                                            new String[] {ssp}, userId);
15917                                    if (fullUninstall) {
15918                                        mAppOpsService.packageRemoved(
15919                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15920
15921                                        // Remove all permissions granted from/to this package
15922                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
15923
15924                                        removeTasksByPackageNameLocked(ssp, userId);
15925                                        if (userId == UserHandle.USER_OWNER) {
15926                                            mTaskPersister.removeFromPackageCache(ssp);
15927                                        }
15928                                        mBatteryStatsService.notePackageUninstalled(ssp);
15929                                    }
15930                                } else {
15931                                    removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15932                                    if (userId == UserHandle.USER_OWNER) {
15933                                        mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
15934                                    }
15935                                }
15936                            }
15937                            break;
15938                    }
15939                    break;
15940                case Intent.ACTION_PACKAGE_ADDED:
15941                    // Special case for adding a package: by default turn on compatibility mode.
15942                    Uri data = intent.getData();
15943                    String ssp;
15944                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
15945                        final boolean replacing =
15946                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15947                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
15948
15949                        if (replacing) {
15950                            removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15951                        }
15952                        if (userId == UserHandle.USER_OWNER) {
15953                            mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
15954                        }
15955                        try {
15956                            ApplicationInfo ai = AppGlobals.getPackageManager().
15957                                    getApplicationInfo(ssp, 0, 0);
15958                            mBatteryStatsService.notePackageInstalled(ssp,
15959                                    ai != null ? ai.versionCode : 0);
15960                        } catch (RemoteException e) {
15961                        }
15962                    }
15963                    break;
15964                case Intent.ACTION_TIMEZONE_CHANGED:
15965                    // If this is the time zone changed action, queue up a message that will reset
15966                    // the timezone of all currently running processes. This message will get
15967                    // queued up before the broadcast happens.
15968                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15969                    break;
15970                case Intent.ACTION_TIME_CHANGED:
15971                    // If the user set the time, let all running processes know.
15972                    final int is24Hour =
15973                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
15974                                    : 0;
15975                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15976                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15977                    synchronized (stats) {
15978                        stats.noteCurrentTimeChangedLocked();
15979                    }
15980                    break;
15981                case Intent.ACTION_CLEAR_DNS_CACHE:
15982                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15983                    break;
15984                case Proxy.PROXY_CHANGE_ACTION:
15985                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15986                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15987                    break;
15988            }
15989        }
15990
15991        // Add to the sticky list if requested.
15992        if (sticky) {
15993            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15994                    callingPid, callingUid)
15995                    != PackageManager.PERMISSION_GRANTED) {
15996                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15997                        + callingPid + ", uid=" + callingUid
15998                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15999                Slog.w(TAG, msg);
16000                throw new SecurityException(msg);
16001            }
16002            if (requiredPermission != null) {
16003                Slog.w(TAG, "Can't broadcast sticky intent " + intent
16004                        + " and enforce permission " + requiredPermission);
16005                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
16006            }
16007            if (intent.getComponent() != null) {
16008                throw new SecurityException(
16009                        "Sticky broadcasts can't target a specific component");
16010            }
16011            // We use userId directly here, since the "all" target is maintained
16012            // as a separate set of sticky broadcasts.
16013            if (userId != UserHandle.USER_ALL) {
16014                // But first, if this is not a broadcast to all users, then
16015                // make sure it doesn't conflict with an existing broadcast to
16016                // all users.
16017                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
16018                        UserHandle.USER_ALL);
16019                if (stickies != null) {
16020                    ArrayList<Intent> list = stickies.get(intent.getAction());
16021                    if (list != null) {
16022                        int N = list.size();
16023                        int i;
16024                        for (i=0; i<N; i++) {
16025                            if (intent.filterEquals(list.get(i))) {
16026                                throw new IllegalArgumentException(
16027                                        "Sticky broadcast " + intent + " for user "
16028                                        + userId + " conflicts with existing global broadcast");
16029                            }
16030                        }
16031                    }
16032                }
16033            }
16034            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16035            if (stickies == null) {
16036                stickies = new ArrayMap<String, ArrayList<Intent>>();
16037                mStickyBroadcasts.put(userId, stickies);
16038            }
16039            ArrayList<Intent> list = stickies.get(intent.getAction());
16040            if (list == null) {
16041                list = new ArrayList<Intent>();
16042                stickies.put(intent.getAction(), list);
16043            }
16044            int N = list.size();
16045            int i;
16046            for (i=0; i<N; i++) {
16047                if (intent.filterEquals(list.get(i))) {
16048                    // This sticky already exists, replace it.
16049                    list.set(i, new Intent(intent));
16050                    break;
16051                }
16052            }
16053            if (i >= N) {
16054                list.add(new Intent(intent));
16055            }
16056        }
16057
16058        int[] users;
16059        if (userId == UserHandle.USER_ALL) {
16060            // Caller wants broadcast to go to all started users.
16061            users = mStartedUserArray;
16062        } else {
16063            // Caller wants broadcast to go to one specific user.
16064            users = new int[] {userId};
16065        }
16066
16067        // Figure out who all will receive this broadcast.
16068        List receivers = null;
16069        List<BroadcastFilter> registeredReceivers = null;
16070        // Need to resolve the intent to interested receivers...
16071        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
16072                 == 0) {
16073            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
16074        }
16075        if (intent.getComponent() == null) {
16076            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
16077                // Query one target user at a time, excluding shell-restricted users
16078                UserManagerService ums = getUserManagerLocked();
16079                for (int i = 0; i < users.length; i++) {
16080                    if (ums.hasUserRestriction(
16081                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
16082                        continue;
16083                    }
16084                    List<BroadcastFilter> registeredReceiversForUser =
16085                            mReceiverResolver.queryIntent(intent,
16086                                    resolvedType, false, users[i]);
16087                    if (registeredReceivers == null) {
16088                        registeredReceivers = registeredReceiversForUser;
16089                    } else if (registeredReceiversForUser != null) {
16090                        registeredReceivers.addAll(registeredReceiversForUser);
16091                    }
16092                }
16093            } else {
16094                registeredReceivers = mReceiverResolver.queryIntent(intent,
16095                        resolvedType, false, userId);
16096            }
16097        }
16098
16099        final boolean replacePending =
16100                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16101
16102        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
16103                + " replacePending=" + replacePending);
16104
16105        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16106        if (!ordered && NR > 0) {
16107            // If we are not serializing this broadcast, then send the
16108            // registered receivers separately so they don't wait for the
16109            // components to be launched.
16110            final BroadcastQueue queue = broadcastQueueForIntent(intent);
16111            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16112                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
16113                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
16114                    ordered, sticky, false, userId);
16115            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
16116            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16117            if (!replaced) {
16118                queue.enqueueParallelBroadcastLocked(r);
16119                queue.scheduleBroadcastsLocked();
16120            }
16121            registeredReceivers = null;
16122            NR = 0;
16123        }
16124
16125        // Merge into one list.
16126        int ir = 0;
16127        if (receivers != null) {
16128            // A special case for PACKAGE_ADDED: do not allow the package
16129            // being added to see this broadcast.  This prevents them from
16130            // using this as a back door to get run as soon as they are
16131            // installed.  Maybe in the future we want to have a special install
16132            // broadcast or such for apps, but we'd like to deliberately make
16133            // this decision.
16134            String skipPackages[] = null;
16135            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16136                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16137                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16138                Uri data = intent.getData();
16139                if (data != null) {
16140                    String pkgName = data.getSchemeSpecificPart();
16141                    if (pkgName != null) {
16142                        skipPackages = new String[] { pkgName };
16143                    }
16144                }
16145            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16146                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16147            }
16148            if (skipPackages != null && (skipPackages.length > 0)) {
16149                for (String skipPackage : skipPackages) {
16150                    if (skipPackage != null) {
16151                        int NT = receivers.size();
16152                        for (int it=0; it<NT; it++) {
16153                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
16154                            if (curt.activityInfo.packageName.equals(skipPackage)) {
16155                                receivers.remove(it);
16156                                it--;
16157                                NT--;
16158                            }
16159                        }
16160                    }
16161                }
16162            }
16163
16164            int NT = receivers != null ? receivers.size() : 0;
16165            int it = 0;
16166            ResolveInfo curt = null;
16167            BroadcastFilter curr = null;
16168            while (it < NT && ir < NR) {
16169                if (curt == null) {
16170                    curt = (ResolveInfo)receivers.get(it);
16171                }
16172                if (curr == null) {
16173                    curr = registeredReceivers.get(ir);
16174                }
16175                if (curr.getPriority() >= curt.priority) {
16176                    // Insert this broadcast record into the final list.
16177                    receivers.add(it, curr);
16178                    ir++;
16179                    curr = null;
16180                    it++;
16181                    NT++;
16182                } else {
16183                    // Skip to the next ResolveInfo in the final list.
16184                    it++;
16185                    curt = null;
16186                }
16187            }
16188        }
16189        while (ir < NR) {
16190            if (receivers == null) {
16191                receivers = new ArrayList();
16192            }
16193            receivers.add(registeredReceivers.get(ir));
16194            ir++;
16195        }
16196
16197        if ((receivers != null && receivers.size() > 0)
16198                || resultTo != null) {
16199            BroadcastQueue queue = broadcastQueueForIntent(intent);
16200            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16201                    callerPackage, callingPid, callingUid, resolvedType,
16202                    requiredPermission, appOp, receivers, resultTo, resultCode,
16203                    resultData, map, ordered, sticky, false, userId);
16204
16205            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
16206                    + ": prev had " + queue.mOrderedBroadcasts.size());
16207            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
16208                    "Enqueueing broadcast " + r.intent.getAction());
16209
16210            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16211            if (!replaced) {
16212                queue.enqueueOrderedBroadcastLocked(r);
16213                queue.scheduleBroadcastsLocked();
16214            }
16215        }
16216
16217        return ActivityManager.BROADCAST_SUCCESS;
16218    }
16219
16220    final Intent verifyBroadcastLocked(Intent intent) {
16221        // Refuse possible leaked file descriptors
16222        if (intent != null && intent.hasFileDescriptors() == true) {
16223            throw new IllegalArgumentException("File descriptors passed in Intent");
16224        }
16225
16226        int flags = intent.getFlags();
16227
16228        if (!mProcessesReady) {
16229            // if the caller really truly claims to know what they're doing, go
16230            // ahead and allow the broadcast without launching any receivers
16231            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16232                intent = new Intent(intent);
16233                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16234            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16235                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16236                        + " before boot completion");
16237                throw new IllegalStateException("Cannot broadcast before boot completed");
16238            }
16239        }
16240
16241        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16242            throw new IllegalArgumentException(
16243                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16244        }
16245
16246        return intent;
16247    }
16248
16249    public final int broadcastIntent(IApplicationThread caller,
16250            Intent intent, String resolvedType, IIntentReceiver resultTo,
16251            int resultCode, String resultData, Bundle map,
16252            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16253        enforceNotIsolatedCaller("broadcastIntent");
16254        synchronized(this) {
16255            intent = verifyBroadcastLocked(intent);
16256
16257            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16258            final int callingPid = Binder.getCallingPid();
16259            final int callingUid = Binder.getCallingUid();
16260            final long origId = Binder.clearCallingIdentity();
16261            int res = broadcastIntentLocked(callerApp,
16262                    callerApp != null ? callerApp.info.packageName : null,
16263                    intent, resolvedType, resultTo,
16264                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16265                    callingPid, callingUid, userId);
16266            Binder.restoreCallingIdentity(origId);
16267            return res;
16268        }
16269    }
16270
16271    int broadcastIntentInPackage(String packageName, int uid,
16272            Intent intent, String resolvedType, IIntentReceiver resultTo,
16273            int resultCode, String resultData, Bundle map,
16274            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16275        synchronized(this) {
16276            intent = verifyBroadcastLocked(intent);
16277
16278            final long origId = Binder.clearCallingIdentity();
16279            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16280                    resultTo, resultCode, resultData, map, requiredPermission,
16281                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16282            Binder.restoreCallingIdentity(origId);
16283            return res;
16284        }
16285    }
16286
16287    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16288        // Refuse possible leaked file descriptors
16289        if (intent != null && intent.hasFileDescriptors() == true) {
16290            throw new IllegalArgumentException("File descriptors passed in Intent");
16291        }
16292
16293        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16294                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16295
16296        synchronized(this) {
16297            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16298                    != PackageManager.PERMISSION_GRANTED) {
16299                String msg = "Permission Denial: unbroadcastIntent() from pid="
16300                        + Binder.getCallingPid()
16301                        + ", uid=" + Binder.getCallingUid()
16302                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16303                Slog.w(TAG, msg);
16304                throw new SecurityException(msg);
16305            }
16306            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16307            if (stickies != null) {
16308                ArrayList<Intent> list = stickies.get(intent.getAction());
16309                if (list != null) {
16310                    int N = list.size();
16311                    int i;
16312                    for (i=0; i<N; i++) {
16313                        if (intent.filterEquals(list.get(i))) {
16314                            list.remove(i);
16315                            break;
16316                        }
16317                    }
16318                    if (list.size() <= 0) {
16319                        stickies.remove(intent.getAction());
16320                    }
16321                }
16322                if (stickies.size() <= 0) {
16323                    mStickyBroadcasts.remove(userId);
16324                }
16325            }
16326        }
16327    }
16328
16329    void backgroundServicesFinishedLocked(int userId) {
16330        for (BroadcastQueue queue : mBroadcastQueues) {
16331            queue.backgroundServicesFinishedLocked(userId);
16332        }
16333    }
16334
16335    public void finishReceiver(IBinder who, int resultCode, String resultData,
16336            Bundle resultExtras, boolean resultAbort, int flags) {
16337        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
16338
16339        // Refuse possible leaked file descriptors
16340        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16341            throw new IllegalArgumentException("File descriptors passed in Bundle");
16342        }
16343
16344        final long origId = Binder.clearCallingIdentity();
16345        try {
16346            boolean doNext = false;
16347            BroadcastRecord r;
16348
16349            synchronized(this) {
16350                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
16351                        ? mFgBroadcastQueue : mBgBroadcastQueue;
16352                r = queue.getMatchingOrderedReceiver(who);
16353                if (r != null) {
16354                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16355                        resultData, resultExtras, resultAbort, true);
16356                }
16357            }
16358
16359            if (doNext) {
16360                r.queue.processNextBroadcast(false);
16361            }
16362            trimApplications();
16363        } finally {
16364            Binder.restoreCallingIdentity(origId);
16365        }
16366    }
16367
16368    // =========================================================
16369    // INSTRUMENTATION
16370    // =========================================================
16371
16372    public boolean startInstrumentation(ComponentName className,
16373            String profileFile, int flags, Bundle arguments,
16374            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16375            int userId, String abiOverride) {
16376        enforceNotIsolatedCaller("startInstrumentation");
16377        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16378                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16379        // Refuse possible leaked file descriptors
16380        if (arguments != null && arguments.hasFileDescriptors()) {
16381            throw new IllegalArgumentException("File descriptors passed in Bundle");
16382        }
16383
16384        synchronized(this) {
16385            InstrumentationInfo ii = null;
16386            ApplicationInfo ai = null;
16387            try {
16388                ii = mContext.getPackageManager().getInstrumentationInfo(
16389                    className, STOCK_PM_FLAGS);
16390                ai = AppGlobals.getPackageManager().getApplicationInfo(
16391                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16392            } catch (PackageManager.NameNotFoundException e) {
16393            } catch (RemoteException e) {
16394            }
16395            if (ii == null) {
16396                reportStartInstrumentationFailure(watcher, className,
16397                        "Unable to find instrumentation info for: " + className);
16398                return false;
16399            }
16400            if (ai == null) {
16401                reportStartInstrumentationFailure(watcher, className,
16402                        "Unable to find instrumentation target package: " + ii.targetPackage);
16403                return false;
16404            }
16405
16406            int match = mContext.getPackageManager().checkSignatures(
16407                    ii.targetPackage, ii.packageName);
16408            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16409                String msg = "Permission Denial: starting instrumentation "
16410                        + className + " from pid="
16411                        + Binder.getCallingPid()
16412                        + ", uid=" + Binder.getCallingPid()
16413                        + " not allowed because package " + ii.packageName
16414                        + " does not have a signature matching the target "
16415                        + ii.targetPackage;
16416                reportStartInstrumentationFailure(watcher, className, msg);
16417                throw new SecurityException(msg);
16418            }
16419
16420            final long origId = Binder.clearCallingIdentity();
16421            // Instrumentation can kill and relaunch even persistent processes
16422            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16423                    "start instr");
16424            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16425            app.instrumentationClass = className;
16426            app.instrumentationInfo = ai;
16427            app.instrumentationProfileFile = profileFile;
16428            app.instrumentationArguments = arguments;
16429            app.instrumentationWatcher = watcher;
16430            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16431            app.instrumentationResultClass = className;
16432            Binder.restoreCallingIdentity(origId);
16433        }
16434
16435        return true;
16436    }
16437
16438    /**
16439     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16440     * error to the logs, but if somebody is watching, send the report there too.  This enables
16441     * the "am" command to report errors with more information.
16442     *
16443     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16444     * @param cn The component name of the instrumentation.
16445     * @param report The error report.
16446     */
16447    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16448            ComponentName cn, String report) {
16449        Slog.w(TAG, report);
16450        try {
16451            if (watcher != null) {
16452                Bundle results = new Bundle();
16453                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16454                results.putString("Error", report);
16455                watcher.instrumentationStatus(cn, -1, results);
16456            }
16457        } catch (RemoteException e) {
16458            Slog.w(TAG, e);
16459        }
16460    }
16461
16462    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16463        if (app.instrumentationWatcher != null) {
16464            try {
16465                // NOTE:  IInstrumentationWatcher *must* be oneway here
16466                app.instrumentationWatcher.instrumentationFinished(
16467                    app.instrumentationClass,
16468                    resultCode,
16469                    results);
16470            } catch (RemoteException e) {
16471            }
16472        }
16473        if (app.instrumentationUiAutomationConnection != null) {
16474            try {
16475                app.instrumentationUiAutomationConnection.shutdown();
16476            } catch (RemoteException re) {
16477                /* ignore */
16478            }
16479            // Only a UiAutomation can set this flag and now that
16480            // it is finished we make sure it is reset to its default.
16481            mUserIsMonkey = false;
16482        }
16483        app.instrumentationWatcher = null;
16484        app.instrumentationUiAutomationConnection = null;
16485        app.instrumentationClass = null;
16486        app.instrumentationInfo = null;
16487        app.instrumentationProfileFile = null;
16488        app.instrumentationArguments = null;
16489
16490        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16491                "finished inst");
16492    }
16493
16494    public void finishInstrumentation(IApplicationThread target,
16495            int resultCode, Bundle results) {
16496        int userId = UserHandle.getCallingUserId();
16497        // Refuse possible leaked file descriptors
16498        if (results != null && results.hasFileDescriptors()) {
16499            throw new IllegalArgumentException("File descriptors passed in Intent");
16500        }
16501
16502        synchronized(this) {
16503            ProcessRecord app = getRecordForAppLocked(target);
16504            if (app == null) {
16505                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16506                return;
16507            }
16508            final long origId = Binder.clearCallingIdentity();
16509            finishInstrumentationLocked(app, resultCode, results);
16510            Binder.restoreCallingIdentity(origId);
16511        }
16512    }
16513
16514    // =========================================================
16515    // CONFIGURATION
16516    // =========================================================
16517
16518    public ConfigurationInfo getDeviceConfigurationInfo() {
16519        ConfigurationInfo config = new ConfigurationInfo();
16520        synchronized (this) {
16521            config.reqTouchScreen = mConfiguration.touchscreen;
16522            config.reqKeyboardType = mConfiguration.keyboard;
16523            config.reqNavigation = mConfiguration.navigation;
16524            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16525                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16526                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16527            }
16528            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16529                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16530                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16531            }
16532            config.reqGlEsVersion = GL_ES_VERSION;
16533        }
16534        return config;
16535    }
16536
16537    ActivityStack getFocusedStack() {
16538        return mStackSupervisor.getFocusedStack();
16539    }
16540
16541    @Override
16542    public int getFocusedStackId() throws RemoteException {
16543        ActivityStack focusedStack = getFocusedStack();
16544        if (focusedStack != null) {
16545            return focusedStack.getStackId();
16546        }
16547        return -1;
16548    }
16549
16550    public Configuration getConfiguration() {
16551        Configuration ci;
16552        synchronized(this) {
16553            ci = new Configuration(mConfiguration);
16554            ci.userSetLocale = false;
16555        }
16556        return ci;
16557    }
16558
16559    public void updatePersistentConfiguration(Configuration values) {
16560        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16561                "updateConfiguration()");
16562        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16563                "updateConfiguration()");
16564        if (values == null) {
16565            throw new NullPointerException("Configuration must not be null");
16566        }
16567
16568        synchronized(this) {
16569            final long origId = Binder.clearCallingIdentity();
16570            updateConfigurationLocked(values, null, true, false);
16571            Binder.restoreCallingIdentity(origId);
16572        }
16573    }
16574
16575    public void updateConfiguration(Configuration values) {
16576        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16577                "updateConfiguration()");
16578
16579        synchronized(this) {
16580            if (values == null && mWindowManager != null) {
16581                // sentinel: fetch the current configuration from the window manager
16582                values = mWindowManager.computeNewConfiguration();
16583            }
16584
16585            if (mWindowManager != null) {
16586                mProcessList.applyDisplaySize(mWindowManager);
16587            }
16588
16589            final long origId = Binder.clearCallingIdentity();
16590            if (values != null) {
16591                Settings.System.clearConfiguration(values);
16592            }
16593            updateConfigurationLocked(values, null, false, false);
16594            Binder.restoreCallingIdentity(origId);
16595        }
16596    }
16597
16598    /**
16599     * Do either or both things: (1) change the current configuration, and (2)
16600     * make sure the given activity is running with the (now) current
16601     * configuration.  Returns true if the activity has been left running, or
16602     * false if <var>starting</var> is being destroyed to match the new
16603     * configuration.
16604     * @param persistent TODO
16605     */
16606    boolean updateConfigurationLocked(Configuration values,
16607            ActivityRecord starting, boolean persistent, boolean initLocale) {
16608        int changes = 0;
16609
16610        if (values != null) {
16611            Configuration newConfig = new Configuration(mConfiguration);
16612            changes = newConfig.updateFrom(values);
16613            if (changes != 0) {
16614                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
16615                        "Updating configuration to: " + values);
16616
16617                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16618
16619                if (!initLocale && values.locale != null && values.userSetLocale) {
16620                    final String languageTag = values.locale.toLanguageTag();
16621                    SystemProperties.set("persist.sys.locale", languageTag);
16622                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
16623                            values.locale));
16624                }
16625
16626                mConfigurationSeq++;
16627                if (mConfigurationSeq <= 0) {
16628                    mConfigurationSeq = 1;
16629                }
16630                newConfig.seq = mConfigurationSeq;
16631                mConfiguration = newConfig;
16632                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16633                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16634                //mUsageStatsService.noteStartConfig(newConfig);
16635
16636                final Configuration configCopy = new Configuration(mConfiguration);
16637
16638                // TODO: If our config changes, should we auto dismiss any currently
16639                // showing dialogs?
16640                mShowDialogs = shouldShowDialogs(newConfig);
16641
16642                AttributeCache ac = AttributeCache.instance();
16643                if (ac != null) {
16644                    ac.updateConfiguration(configCopy);
16645                }
16646
16647                // Make sure all resources in our process are updated
16648                // right now, so that anyone who is going to retrieve
16649                // resource values after we return will be sure to get
16650                // the new ones.  This is especially important during
16651                // boot, where the first config change needs to guarantee
16652                // all resources have that config before following boot
16653                // code is executed.
16654                mSystemThread.applyConfigurationToResources(configCopy);
16655
16656                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16657                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16658                    msg.obj = new Configuration(configCopy);
16659                    mHandler.sendMessage(msg);
16660                }
16661
16662                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16663                    ProcessRecord app = mLruProcesses.get(i);
16664                    try {
16665                        if (app.thread != null) {
16666                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
16667                                    + app.processName + " new config " + mConfiguration);
16668                            app.thread.scheduleConfigurationChanged(configCopy);
16669                        }
16670                    } catch (Exception e) {
16671                    }
16672                }
16673                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16674                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16675                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16676                        | Intent.FLAG_RECEIVER_FOREGROUND);
16677                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16678                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16679                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16680                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16681                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16682                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16683                    broadcastIntentLocked(null, null, intent,
16684                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16685                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16686                }
16687            }
16688        }
16689
16690        boolean kept = true;
16691        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16692        // mainStack is null during startup.
16693        if (mainStack != null) {
16694            if (changes != 0 && starting == null) {
16695                // If the configuration changed, and the caller is not already
16696                // in the process of starting an activity, then find the top
16697                // activity to check if its configuration needs to change.
16698                starting = mainStack.topRunningActivityLocked(null);
16699            }
16700
16701            if (starting != null) {
16702                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16703                // And we need to make sure at this point that all other activities
16704                // are made visible with the correct configuration.
16705                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16706            }
16707        }
16708
16709        if (values != null && mWindowManager != null) {
16710            mWindowManager.setNewConfiguration(mConfiguration);
16711        }
16712
16713        return kept;
16714    }
16715
16716    /**
16717     * Decide based on the configuration whether we should shouw the ANR,
16718     * crash, etc dialogs.  The idea is that if there is no affordnace to
16719     * press the on-screen buttons, we shouldn't show the dialog.
16720     *
16721     * A thought: SystemUI might also want to get told about this, the Power
16722     * dialog / global actions also might want different behaviors.
16723     */
16724    private static final boolean shouldShowDialogs(Configuration config) {
16725        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16726                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
16727                && config.navigation == Configuration.NAVIGATION_NONAV);
16728    }
16729
16730    @Override
16731    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16732        synchronized (this) {
16733            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
16734            if (srec != null) {
16735                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16736            }
16737        }
16738        return false;
16739    }
16740
16741    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16742            Intent resultData) {
16743
16744        synchronized (this) {
16745            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
16746            if (r != null) {
16747                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
16748            }
16749            return false;
16750        }
16751    }
16752
16753    public int getLaunchedFromUid(IBinder activityToken) {
16754        ActivityRecord srec;
16755        synchronized (this) {
16756            srec = ActivityRecord.forTokenLocked(activityToken);
16757        }
16758        if (srec == null) {
16759            return -1;
16760        }
16761        return srec.launchedFromUid;
16762    }
16763
16764    public String getLaunchedFromPackage(IBinder activityToken) {
16765        ActivityRecord srec;
16766        synchronized (this) {
16767            srec = ActivityRecord.forTokenLocked(activityToken);
16768        }
16769        if (srec == null) {
16770            return null;
16771        }
16772        return srec.launchedFromPackage;
16773    }
16774
16775    // =========================================================
16776    // LIFETIME MANAGEMENT
16777    // =========================================================
16778
16779    // Returns which broadcast queue the app is the current [or imminent] receiver
16780    // on, or 'null' if the app is not an active broadcast recipient.
16781    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16782        BroadcastRecord r = app.curReceiver;
16783        if (r != null) {
16784            return r.queue;
16785        }
16786
16787        // It's not the current receiver, but it might be starting up to become one
16788        synchronized (this) {
16789            for (BroadcastQueue queue : mBroadcastQueues) {
16790                r = queue.mPendingBroadcast;
16791                if (r != null && r.curApp == app) {
16792                    // found it; report which queue it's in
16793                    return queue;
16794                }
16795            }
16796        }
16797
16798        return null;
16799    }
16800
16801    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
16802            ComponentName targetComponent, String targetProcess) {
16803        if (!mTrackingAssociations) {
16804            return null;
16805        }
16806        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
16807                = mAssociations.get(targetUid);
16808        if (components == null) {
16809            components = new ArrayMap<>();
16810            mAssociations.put(targetUid, components);
16811        }
16812        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
16813        if (sourceUids == null) {
16814            sourceUids = new SparseArray<>();
16815            components.put(targetComponent, sourceUids);
16816        }
16817        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
16818        if (sourceProcesses == null) {
16819            sourceProcesses = new ArrayMap<>();
16820            sourceUids.put(sourceUid, sourceProcesses);
16821        }
16822        Association ass = sourceProcesses.get(sourceProcess);
16823        if (ass == null) {
16824            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
16825                    targetProcess);
16826            sourceProcesses.put(sourceProcess, ass);
16827        }
16828        ass.mCount++;
16829        ass.mNesting++;
16830        if (ass.mNesting == 1) {
16831            ass.mStartTime = SystemClock.uptimeMillis();
16832        }
16833        return ass;
16834    }
16835
16836    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
16837            ComponentName targetComponent) {
16838        if (!mTrackingAssociations) {
16839            return;
16840        }
16841        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
16842                = mAssociations.get(targetUid);
16843        if (components == null) {
16844            return;
16845        }
16846        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
16847        if (sourceUids == null) {
16848            return;
16849        }
16850        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
16851        if (sourceProcesses == null) {
16852            return;
16853        }
16854        Association ass = sourceProcesses.get(sourceProcess);
16855        if (ass == null || ass.mNesting <= 0) {
16856            return;
16857        }
16858        ass.mNesting--;
16859        if (ass.mNesting == 0) {
16860            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
16861        }
16862    }
16863
16864    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16865            boolean doingAll, long now) {
16866        if (mAdjSeq == app.adjSeq) {
16867            // This adjustment has already been computed.
16868            return app.curRawAdj;
16869        }
16870
16871        if (app.thread == null) {
16872            app.adjSeq = mAdjSeq;
16873            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16874            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16875            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16876        }
16877
16878        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16879        app.adjSource = null;
16880        app.adjTarget = null;
16881        app.empty = false;
16882        app.cached = false;
16883
16884        final int activitiesSize = app.activities.size();
16885
16886        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16887            // The max adjustment doesn't allow this app to be anything
16888            // below foreground, so it is not worth doing work for it.
16889            app.adjType = "fixed";
16890            app.adjSeq = mAdjSeq;
16891            app.curRawAdj = app.maxAdj;
16892            app.foregroundActivities = false;
16893            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16894            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16895            // System processes can do UI, and when they do we want to have
16896            // them trim their memory after the user leaves the UI.  To
16897            // facilitate this, here we need to determine whether or not it
16898            // is currently showing UI.
16899            app.systemNoUi = true;
16900            if (app == TOP_APP) {
16901                app.systemNoUi = false;
16902            } else if (activitiesSize > 0) {
16903                for (int j = 0; j < activitiesSize; j++) {
16904                    final ActivityRecord r = app.activities.get(j);
16905                    if (r.visible) {
16906                        app.systemNoUi = false;
16907                    }
16908                }
16909            }
16910            if (!app.systemNoUi) {
16911                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16912            }
16913            return (app.curAdj=app.maxAdj);
16914        }
16915
16916        app.systemNoUi = false;
16917
16918        final int PROCESS_STATE_TOP = mTopProcessState;
16919
16920        // Determine the importance of the process, starting with most
16921        // important to least, and assign an appropriate OOM adjustment.
16922        int adj;
16923        int schedGroup;
16924        int procState;
16925        boolean foregroundActivities = false;
16926        BroadcastQueue queue;
16927        if (app == TOP_APP) {
16928            // The last app on the list is the foreground app.
16929            adj = ProcessList.FOREGROUND_APP_ADJ;
16930            schedGroup = Process.THREAD_GROUP_DEFAULT;
16931            app.adjType = "top-activity";
16932            foregroundActivities = true;
16933            procState = PROCESS_STATE_TOP;
16934        } else if (app.instrumentationClass != null) {
16935            // Don't want to kill running instrumentation.
16936            adj = ProcessList.FOREGROUND_APP_ADJ;
16937            schedGroup = Process.THREAD_GROUP_DEFAULT;
16938            app.adjType = "instrumentation";
16939            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16940        } else if ((queue = isReceivingBroadcast(app)) != null) {
16941            // An app that is currently receiving a broadcast also
16942            // counts as being in the foreground for OOM killer purposes.
16943            // It's placed in a sched group based on the nature of the
16944            // broadcast as reflected by which queue it's active in.
16945            adj = ProcessList.FOREGROUND_APP_ADJ;
16946            schedGroup = (queue == mFgBroadcastQueue)
16947                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16948            app.adjType = "broadcast";
16949            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16950        } else if (app.executingServices.size() > 0) {
16951            // An app that is currently executing a service callback also
16952            // counts as being in the foreground.
16953            adj = ProcessList.FOREGROUND_APP_ADJ;
16954            schedGroup = app.execServicesFg ?
16955                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16956            app.adjType = "exec-service";
16957            procState = ActivityManager.PROCESS_STATE_SERVICE;
16958            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16959        } else {
16960            // As far as we know the process is empty.  We may change our mind later.
16961            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16962            // At this point we don't actually know the adjustment.  Use the cached adj
16963            // value that the caller wants us to.
16964            adj = cachedAdj;
16965            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16966            app.cached = true;
16967            app.empty = true;
16968            app.adjType = "cch-empty";
16969        }
16970
16971        // Examine all activities if not already foreground.
16972        if (!foregroundActivities && activitiesSize > 0) {
16973            for (int j = 0; j < activitiesSize; j++) {
16974                final ActivityRecord r = app.activities.get(j);
16975                if (r.app != app) {
16976                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16977                            + app + "?!?");
16978                    continue;
16979                }
16980                if (r.visible) {
16981                    // App has a visible activity; only upgrade adjustment.
16982                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16983                        adj = ProcessList.VISIBLE_APP_ADJ;
16984                        app.adjType = "visible";
16985                    }
16986                    if (procState > PROCESS_STATE_TOP) {
16987                        procState = PROCESS_STATE_TOP;
16988                    }
16989                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16990                    app.cached = false;
16991                    app.empty = false;
16992                    foregroundActivities = true;
16993                    break;
16994                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16995                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16996                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16997                        app.adjType = "pausing";
16998                    }
16999                    if (procState > PROCESS_STATE_TOP) {
17000                        procState = PROCESS_STATE_TOP;
17001                    }
17002                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17003                    app.cached = false;
17004                    app.empty = false;
17005                    foregroundActivities = true;
17006                } else if (r.state == ActivityState.STOPPING) {
17007                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17008                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17009                        app.adjType = "stopping";
17010                    }
17011                    // For the process state, we will at this point consider the
17012                    // process to be cached.  It will be cached either as an activity
17013                    // or empty depending on whether the activity is finishing.  We do
17014                    // this so that we can treat the process as cached for purposes of
17015                    // memory trimming (determing current memory level, trim command to
17016                    // send to process) since there can be an arbitrary number of stopping
17017                    // processes and they should soon all go into the cached state.
17018                    if (!r.finishing) {
17019                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17020                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17021                        }
17022                    }
17023                    app.cached = false;
17024                    app.empty = false;
17025                    foregroundActivities = true;
17026                } else {
17027                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17028                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17029                        app.adjType = "cch-act";
17030                    }
17031                }
17032            }
17033        }
17034
17035        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17036            if (app.foregroundServices) {
17037                // The user is aware of this app, so make it visible.
17038                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17039                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17040                app.cached = false;
17041                app.adjType = "fg-service";
17042                schedGroup = Process.THREAD_GROUP_DEFAULT;
17043            } else if (app.forcingToForeground != null) {
17044                // The user is aware of this app, so make it visible.
17045                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17046                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17047                app.cached = false;
17048                app.adjType = "force-fg";
17049                app.adjSource = app.forcingToForeground;
17050                schedGroup = Process.THREAD_GROUP_DEFAULT;
17051            }
17052        }
17053
17054        if (app == mHeavyWeightProcess) {
17055            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
17056                // We don't want to kill the current heavy-weight process.
17057                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
17058                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17059                app.cached = false;
17060                app.adjType = "heavy";
17061            }
17062            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17063                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
17064            }
17065        }
17066
17067        if (app == mHomeProcess) {
17068            if (adj > ProcessList.HOME_APP_ADJ) {
17069                // This process is hosting what we currently consider to be the
17070                // home app, so we don't want to let it go into the background.
17071                adj = ProcessList.HOME_APP_ADJ;
17072                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17073                app.cached = false;
17074                app.adjType = "home";
17075            }
17076            if (procState > ActivityManager.PROCESS_STATE_HOME) {
17077                procState = ActivityManager.PROCESS_STATE_HOME;
17078            }
17079        }
17080
17081        if (app == mPreviousProcess && app.activities.size() > 0) {
17082            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
17083                // This was the previous process that showed UI to the user.
17084                // We want to try to keep it around more aggressively, to give
17085                // a good experience around switching between two apps.
17086                adj = ProcessList.PREVIOUS_APP_ADJ;
17087                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17088                app.cached = false;
17089                app.adjType = "previous";
17090            }
17091            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17092                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17093            }
17094        }
17095
17096        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
17097                + " reason=" + app.adjType);
17098
17099        // By default, we use the computed adjustment.  It may be changed if
17100        // there are applications dependent on our services or providers, but
17101        // this gives us a baseline and makes sure we don't get into an
17102        // infinite recursion.
17103        app.adjSeq = mAdjSeq;
17104        app.curRawAdj = adj;
17105        app.hasStartedServices = false;
17106
17107        if (mBackupTarget != null && app == mBackupTarget.app) {
17108            // If possible we want to avoid killing apps while they're being backed up
17109            if (adj > ProcessList.BACKUP_APP_ADJ) {
17110                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
17111                adj = ProcessList.BACKUP_APP_ADJ;
17112                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17113                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17114                }
17115                app.adjType = "backup";
17116                app.cached = false;
17117            }
17118            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
17119                procState = ActivityManager.PROCESS_STATE_BACKUP;
17120            }
17121        }
17122
17123        boolean mayBeTop = false;
17124
17125        for (int is = app.services.size()-1;
17126                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17127                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17128                        || procState > ActivityManager.PROCESS_STATE_TOP);
17129                is--) {
17130            ServiceRecord s = app.services.valueAt(is);
17131            if (s.startRequested) {
17132                app.hasStartedServices = true;
17133                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
17134                    procState = ActivityManager.PROCESS_STATE_SERVICE;
17135                }
17136                if (app.hasShownUi && app != mHomeProcess) {
17137                    // If this process has shown some UI, let it immediately
17138                    // go to the LRU list because it may be pretty heavy with
17139                    // UI stuff.  We'll tag it with a label just to help
17140                    // debug and understand what is going on.
17141                    if (adj > ProcessList.SERVICE_ADJ) {
17142                        app.adjType = "cch-started-ui-services";
17143                    }
17144                } else {
17145                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17146                        // This service has seen some activity within
17147                        // recent memory, so we will keep its process ahead
17148                        // of the background processes.
17149                        if (adj > ProcessList.SERVICE_ADJ) {
17150                            adj = ProcessList.SERVICE_ADJ;
17151                            app.adjType = "started-services";
17152                            app.cached = false;
17153                        }
17154                    }
17155                    // If we have let the service slide into the background
17156                    // state, still have some text describing what it is doing
17157                    // even though the service no longer has an impact.
17158                    if (adj > ProcessList.SERVICE_ADJ) {
17159                        app.adjType = "cch-started-services";
17160                    }
17161                }
17162            }
17163            for (int conni = s.connections.size()-1;
17164                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17165                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17166                            || procState > ActivityManager.PROCESS_STATE_TOP);
17167                    conni--) {
17168                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17169                for (int i = 0;
17170                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17171                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17172                                || procState > ActivityManager.PROCESS_STATE_TOP);
17173                        i++) {
17174                    // XXX should compute this based on the max of
17175                    // all connected clients.
17176                    ConnectionRecord cr = clist.get(i);
17177                    if (cr.binding.client == app) {
17178                        // Binding to ourself is not interesting.
17179                        continue;
17180                    }
17181                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17182                        ProcessRecord client = cr.binding.client;
17183                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
17184                                TOP_APP, doingAll, now);
17185                        int clientProcState = client.curProcState;
17186                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17187                            // If the other app is cached for any reason, for purposes here
17188                            // we are going to consider it empty.  The specific cached state
17189                            // doesn't propagate except under certain conditions.
17190                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17191                        }
17192                        String adjType = null;
17193                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17194                            // Not doing bind OOM management, so treat
17195                            // this guy more like a started service.
17196                            if (app.hasShownUi && app != mHomeProcess) {
17197                                // If this process has shown some UI, let it immediately
17198                                // go to the LRU list because it may be pretty heavy with
17199                                // UI stuff.  We'll tag it with a label just to help
17200                                // debug and understand what is going on.
17201                                if (adj > clientAdj) {
17202                                    adjType = "cch-bound-ui-services";
17203                                }
17204                                app.cached = false;
17205                                clientAdj = adj;
17206                                clientProcState = procState;
17207                            } else {
17208                                if (now >= (s.lastActivity
17209                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17210                                    // This service has not seen activity within
17211                                    // recent memory, so allow it to drop to the
17212                                    // LRU list if there is no other reason to keep
17213                                    // it around.  We'll also tag it with a label just
17214                                    // to help debug and undertand what is going on.
17215                                    if (adj > clientAdj) {
17216                                        adjType = "cch-bound-services";
17217                                    }
17218                                    clientAdj = adj;
17219                                }
17220                            }
17221                        }
17222                        if (adj > clientAdj) {
17223                            // If this process has recently shown UI, and
17224                            // the process that is binding to it is less
17225                            // important than being visible, then we don't
17226                            // care about the binding as much as we care
17227                            // about letting this process get into the LRU
17228                            // list to be killed and restarted if needed for
17229                            // memory.
17230                            if (app.hasShownUi && app != mHomeProcess
17231                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17232                                adjType = "cch-bound-ui-services";
17233                            } else {
17234                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17235                                        |Context.BIND_IMPORTANT)) != 0) {
17236                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17237                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17238                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17239                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17240                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17241                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17242                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17243                                    adj = clientAdj;
17244                                } else {
17245                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17246                                        adj = ProcessList.VISIBLE_APP_ADJ;
17247                                    }
17248                                }
17249                                if (!client.cached) {
17250                                    app.cached = false;
17251                                }
17252                                adjType = "service";
17253                            }
17254                        }
17255                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17256                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17257                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17258                            }
17259                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17260                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17261                                    // Special handling of clients who are in the top state.
17262                                    // We *may* want to consider this process to be in the
17263                                    // top state as well, but only if there is not another
17264                                    // reason for it to be running.  Being on the top is a
17265                                    // special state, meaning you are specifically running
17266                                    // for the current top app.  If the process is already
17267                                    // running in the background for some other reason, it
17268                                    // is more important to continue considering it to be
17269                                    // in the background state.
17270                                    mayBeTop = true;
17271                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17272                                } else {
17273                                    // Special handling for above-top states (persistent
17274                                    // processes).  These should not bring the current process
17275                                    // into the top state, since they are not on top.  Instead
17276                                    // give them the best state after that.
17277                                    clientProcState =
17278                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17279                                }
17280                            }
17281                        } else {
17282                            if (clientProcState <
17283                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17284                                clientProcState =
17285                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17286                            }
17287                        }
17288                        if (procState > clientProcState) {
17289                            procState = clientProcState;
17290                        }
17291                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17292                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17293                            app.pendingUiClean = true;
17294                        }
17295                        if (adjType != null) {
17296                            app.adjType = adjType;
17297                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17298                                    .REASON_SERVICE_IN_USE;
17299                            app.adjSource = cr.binding.client;
17300                            app.adjSourceProcState = clientProcState;
17301                            app.adjTarget = s.name;
17302                        }
17303                    }
17304                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17305                        app.treatLikeActivity = true;
17306                    }
17307                    final ActivityRecord a = cr.activity;
17308                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17309                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17310                                (a.visible || a.state == ActivityState.RESUMED
17311                                 || a.state == ActivityState.PAUSING)) {
17312                            adj = ProcessList.FOREGROUND_APP_ADJ;
17313                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17314                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17315                            }
17316                            app.cached = false;
17317                            app.adjType = "service";
17318                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17319                                    .REASON_SERVICE_IN_USE;
17320                            app.adjSource = a;
17321                            app.adjSourceProcState = procState;
17322                            app.adjTarget = s.name;
17323                        }
17324                    }
17325                }
17326            }
17327        }
17328
17329        for (int provi = app.pubProviders.size()-1;
17330                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17331                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17332                        || procState > ActivityManager.PROCESS_STATE_TOP);
17333                provi--) {
17334            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17335            for (int i = cpr.connections.size()-1;
17336                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17337                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17338                            || procState > ActivityManager.PROCESS_STATE_TOP);
17339                    i--) {
17340                ContentProviderConnection conn = cpr.connections.get(i);
17341                ProcessRecord client = conn.client;
17342                if (client == app) {
17343                    // Being our own client is not interesting.
17344                    continue;
17345                }
17346                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17347                int clientProcState = client.curProcState;
17348                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17349                    // If the other app is cached for any reason, for purposes here
17350                    // we are going to consider it empty.
17351                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17352                }
17353                if (adj > clientAdj) {
17354                    if (app.hasShownUi && app != mHomeProcess
17355                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17356                        app.adjType = "cch-ui-provider";
17357                    } else {
17358                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17359                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17360                        app.adjType = "provider";
17361                    }
17362                    app.cached &= client.cached;
17363                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17364                            .REASON_PROVIDER_IN_USE;
17365                    app.adjSource = client;
17366                    app.adjSourceProcState = clientProcState;
17367                    app.adjTarget = cpr.name;
17368                }
17369                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17370                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17371                        // Special handling of clients who are in the top state.
17372                        // We *may* want to consider this process to be in the
17373                        // top state as well, but only if there is not another
17374                        // reason for it to be running.  Being on the top is a
17375                        // special state, meaning you are specifically running
17376                        // for the current top app.  If the process is already
17377                        // running in the background for some other reason, it
17378                        // is more important to continue considering it to be
17379                        // in the background state.
17380                        mayBeTop = true;
17381                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17382                    } else {
17383                        // Special handling for above-top states (persistent
17384                        // processes).  These should not bring the current process
17385                        // into the top state, since they are not on top.  Instead
17386                        // give them the best state after that.
17387                        clientProcState =
17388                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17389                    }
17390                }
17391                if (procState > clientProcState) {
17392                    procState = clientProcState;
17393                }
17394                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17395                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17396                }
17397            }
17398            // If the provider has external (non-framework) process
17399            // dependencies, ensure that its adjustment is at least
17400            // FOREGROUND_APP_ADJ.
17401            if (cpr.hasExternalProcessHandles()) {
17402                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17403                    adj = ProcessList.FOREGROUND_APP_ADJ;
17404                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17405                    app.cached = false;
17406                    app.adjType = "provider";
17407                    app.adjTarget = cpr.name;
17408                }
17409                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17410                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17411                }
17412            }
17413        }
17414
17415        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17416            // A client of one of our services or providers is in the top state.  We
17417            // *may* want to be in the top state, but not if we are already running in
17418            // the background for some other reason.  For the decision here, we are going
17419            // to pick out a few specific states that we want to remain in when a client
17420            // is top (states that tend to be longer-term) and otherwise allow it to go
17421            // to the top state.
17422            switch (procState) {
17423                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17424                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17425                case ActivityManager.PROCESS_STATE_SERVICE:
17426                    // These all are longer-term states, so pull them up to the top
17427                    // of the background states, but not all the way to the top state.
17428                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17429                    break;
17430                default:
17431                    // Otherwise, top is a better choice, so take it.
17432                    procState = ActivityManager.PROCESS_STATE_TOP;
17433                    break;
17434            }
17435        }
17436
17437        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17438            if (app.hasClientActivities) {
17439                // This is a cached process, but with client activities.  Mark it so.
17440                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17441                app.adjType = "cch-client-act";
17442            } else if (app.treatLikeActivity) {
17443                // This is a cached process, but somebody wants us to treat it like it has
17444                // an activity, okay!
17445                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17446                app.adjType = "cch-as-act";
17447            }
17448        }
17449
17450        if (adj == ProcessList.SERVICE_ADJ) {
17451            if (doingAll) {
17452                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17453                mNewNumServiceProcs++;
17454                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17455                if (!app.serviceb) {
17456                    // This service isn't far enough down on the LRU list to
17457                    // normally be a B service, but if we are low on RAM and it
17458                    // is large we want to force it down since we would prefer to
17459                    // keep launcher over it.
17460                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17461                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17462                        app.serviceHighRam = true;
17463                        app.serviceb = true;
17464                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17465                    } else {
17466                        mNewNumAServiceProcs++;
17467                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17468                    }
17469                } else {
17470                    app.serviceHighRam = false;
17471                }
17472            }
17473            if (app.serviceb) {
17474                adj = ProcessList.SERVICE_B_ADJ;
17475            }
17476        }
17477
17478        app.curRawAdj = adj;
17479
17480        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17481        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17482        if (adj > app.maxAdj) {
17483            adj = app.maxAdj;
17484            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17485                schedGroup = Process.THREAD_GROUP_DEFAULT;
17486            }
17487        }
17488
17489        // Do final modification to adj.  Everything we do between here and applying
17490        // the final setAdj must be done in this function, because we will also use
17491        // it when computing the final cached adj later.  Note that we don't need to
17492        // worry about this for max adj above, since max adj will always be used to
17493        // keep it out of the cached vaues.
17494        app.curAdj = app.modifyRawOomAdj(adj);
17495        app.curSchedGroup = schedGroup;
17496        app.curProcState = procState;
17497        app.foregroundActivities = foregroundActivities;
17498
17499        return app.curRawAdj;
17500    }
17501
17502    /**
17503     * Record new PSS sample for a process.
17504     */
17505    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long now) {
17506        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024);
17507        proc.lastPssTime = now;
17508        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
17509        if (DEBUG_PSS) Slog.d(TAG_PSS,
17510                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
17511                + " state=" + ProcessList.makeProcStateString(procState));
17512        if (proc.initialIdlePss == 0) {
17513            proc.initialIdlePss = pss;
17514        }
17515        proc.lastPss = pss;
17516        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
17517            proc.lastCachedPss = pss;
17518        }
17519
17520        final SparseArray<Pair<Long, String>> watchUids
17521                = mMemWatchProcesses.getMap().get(proc.processName);
17522        Long check = null;
17523        if (watchUids != null) {
17524            Pair<Long, String> val = watchUids.get(proc.uid);
17525            if (val == null) {
17526                val = watchUids.get(0);
17527            }
17528            if (val != null) {
17529                check = val.first;
17530            }
17531        }
17532        if (check != null) {
17533            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
17534                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17535                if (!isDebuggable) {
17536                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
17537                        isDebuggable = true;
17538                    }
17539                }
17540                if (isDebuggable) {
17541                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
17542                    final ProcessRecord myProc = proc;
17543                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
17544                    mMemWatchDumpProcName = proc.processName;
17545                    mMemWatchDumpFile = heapdumpFile.toString();
17546                    mMemWatchDumpPid = proc.pid;
17547                    mMemWatchDumpUid = proc.uid;
17548                    BackgroundThread.getHandler().post(new Runnable() {
17549                        @Override
17550                        public void run() {
17551                            revokeUriPermission(ActivityThread.currentActivityThread()
17552                                            .getApplicationThread(),
17553                                    DumpHeapActivity.JAVA_URI,
17554                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
17555                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
17556                                    UserHandle.myUserId());
17557                            ParcelFileDescriptor fd = null;
17558                            try {
17559                                heapdumpFile.delete();
17560                                fd = ParcelFileDescriptor.open(heapdumpFile,
17561                                        ParcelFileDescriptor.MODE_CREATE |
17562                                                ParcelFileDescriptor.MODE_TRUNCATE |
17563                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
17564                                                ParcelFileDescriptor.MODE_APPEND);
17565                                IApplicationThread thread = myProc.thread;
17566                                if (thread != null) {
17567                                    try {
17568                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
17569                                                "Requesting dump heap from "
17570                                                + myProc + " to " + heapdumpFile);
17571                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
17572                                    } catch (RemoteException e) {
17573                                    }
17574                                }
17575                            } catch (FileNotFoundException e) {
17576                                e.printStackTrace();
17577                            } finally {
17578                                if (fd != null) {
17579                                    try {
17580                                        fd.close();
17581                                    } catch (IOException e) {
17582                                    }
17583                                }
17584                            }
17585                        }
17586                    });
17587                } else {
17588                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
17589                            + ", but debugging not enabled");
17590                }
17591            }
17592        }
17593    }
17594
17595    /**
17596     * Schedule PSS collection of a process.
17597     */
17598    void requestPssLocked(ProcessRecord proc, int procState) {
17599        if (mPendingPssProcesses.contains(proc)) {
17600            return;
17601        }
17602        if (mPendingPssProcesses.size() == 0) {
17603            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17604        }
17605        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
17606        proc.pssProcState = procState;
17607        mPendingPssProcesses.add(proc);
17608    }
17609
17610    /**
17611     * Schedule PSS collection of all processes.
17612     */
17613    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17614        if (!always) {
17615            if (now < (mLastFullPssTime +
17616                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17617                return;
17618            }
17619        }
17620        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
17621        mLastFullPssTime = now;
17622        mFullPssPending = true;
17623        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17624        mPendingPssProcesses.clear();
17625        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17626            ProcessRecord app = mLruProcesses.get(i);
17627            if (app.thread == null
17628                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
17629                continue;
17630            }
17631            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17632                app.pssProcState = app.setProcState;
17633                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17634                        mTestPssMode, isSleeping(), now);
17635                mPendingPssProcesses.add(app);
17636            }
17637        }
17638        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17639    }
17640
17641    public void setTestPssMode(boolean enabled) {
17642        synchronized (this) {
17643            mTestPssMode = enabled;
17644            if (enabled) {
17645                // Whenever we enable the mode, we want to take a snapshot all of current
17646                // process mem use.
17647                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
17648            }
17649        }
17650    }
17651
17652    /**
17653     * Ask a given process to GC right now.
17654     */
17655    final void performAppGcLocked(ProcessRecord app) {
17656        try {
17657            app.lastRequestedGc = SystemClock.uptimeMillis();
17658            if (app.thread != null) {
17659                if (app.reportLowMemory) {
17660                    app.reportLowMemory = false;
17661                    app.thread.scheduleLowMemory();
17662                } else {
17663                    app.thread.processInBackground();
17664                }
17665            }
17666        } catch (Exception e) {
17667            // whatever.
17668        }
17669    }
17670
17671    /**
17672     * Returns true if things are idle enough to perform GCs.
17673     */
17674    private final boolean canGcNowLocked() {
17675        boolean processingBroadcasts = false;
17676        for (BroadcastQueue q : mBroadcastQueues) {
17677            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17678                processingBroadcasts = true;
17679            }
17680        }
17681        return !processingBroadcasts
17682                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17683    }
17684
17685    /**
17686     * Perform GCs on all processes that are waiting for it, but only
17687     * if things are idle.
17688     */
17689    final void performAppGcsLocked() {
17690        final int N = mProcessesToGc.size();
17691        if (N <= 0) {
17692            return;
17693        }
17694        if (canGcNowLocked()) {
17695            while (mProcessesToGc.size() > 0) {
17696                ProcessRecord proc = mProcessesToGc.remove(0);
17697                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17698                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17699                            <= SystemClock.uptimeMillis()) {
17700                        // To avoid spamming the system, we will GC processes one
17701                        // at a time, waiting a few seconds between each.
17702                        performAppGcLocked(proc);
17703                        scheduleAppGcsLocked();
17704                        return;
17705                    } else {
17706                        // It hasn't been long enough since we last GCed this
17707                        // process...  put it in the list to wait for its time.
17708                        addProcessToGcListLocked(proc);
17709                        break;
17710                    }
17711                }
17712            }
17713
17714            scheduleAppGcsLocked();
17715        }
17716    }
17717
17718    /**
17719     * If all looks good, perform GCs on all processes waiting for them.
17720     */
17721    final void performAppGcsIfAppropriateLocked() {
17722        if (canGcNowLocked()) {
17723            performAppGcsLocked();
17724            return;
17725        }
17726        // Still not idle, wait some more.
17727        scheduleAppGcsLocked();
17728    }
17729
17730    /**
17731     * Schedule the execution of all pending app GCs.
17732     */
17733    final void scheduleAppGcsLocked() {
17734        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17735
17736        if (mProcessesToGc.size() > 0) {
17737            // Schedule a GC for the time to the next process.
17738            ProcessRecord proc = mProcessesToGc.get(0);
17739            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17740
17741            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17742            long now = SystemClock.uptimeMillis();
17743            if (when < (now+GC_TIMEOUT)) {
17744                when = now + GC_TIMEOUT;
17745            }
17746            mHandler.sendMessageAtTime(msg, when);
17747        }
17748    }
17749
17750    /**
17751     * Add a process to the array of processes waiting to be GCed.  Keeps the
17752     * list in sorted order by the last GC time.  The process can't already be
17753     * on the list.
17754     */
17755    final void addProcessToGcListLocked(ProcessRecord proc) {
17756        boolean added = false;
17757        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17758            if (mProcessesToGc.get(i).lastRequestedGc <
17759                    proc.lastRequestedGc) {
17760                added = true;
17761                mProcessesToGc.add(i+1, proc);
17762                break;
17763            }
17764        }
17765        if (!added) {
17766            mProcessesToGc.add(0, proc);
17767        }
17768    }
17769
17770    /**
17771     * Set up to ask a process to GC itself.  This will either do it
17772     * immediately, or put it on the list of processes to gc the next
17773     * time things are idle.
17774     */
17775    final void scheduleAppGcLocked(ProcessRecord app) {
17776        long now = SystemClock.uptimeMillis();
17777        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17778            return;
17779        }
17780        if (!mProcessesToGc.contains(app)) {
17781            addProcessToGcListLocked(app);
17782            scheduleAppGcsLocked();
17783        }
17784    }
17785
17786    final void checkExcessivePowerUsageLocked(boolean doKills) {
17787        updateCpuStatsNow();
17788
17789        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17790        boolean doWakeKills = doKills;
17791        boolean doCpuKills = doKills;
17792        if (mLastPowerCheckRealtime == 0) {
17793            doWakeKills = false;
17794        }
17795        if (mLastPowerCheckUptime == 0) {
17796            doCpuKills = false;
17797        }
17798        if (stats.isScreenOn()) {
17799            doWakeKills = false;
17800        }
17801        final long curRealtime = SystemClock.elapsedRealtime();
17802        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17803        final long curUptime = SystemClock.uptimeMillis();
17804        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17805        mLastPowerCheckRealtime = curRealtime;
17806        mLastPowerCheckUptime = curUptime;
17807        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17808            doWakeKills = false;
17809        }
17810        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17811            doCpuKills = false;
17812        }
17813        int i = mLruProcesses.size();
17814        while (i > 0) {
17815            i--;
17816            ProcessRecord app = mLruProcesses.get(i);
17817            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17818                long wtime;
17819                synchronized (stats) {
17820                    wtime = stats.getProcessWakeTime(app.info.uid,
17821                            app.pid, curRealtime);
17822                }
17823                long wtimeUsed = wtime - app.lastWakeTime;
17824                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17825                if (DEBUG_POWER) {
17826                    StringBuilder sb = new StringBuilder(128);
17827                    sb.append("Wake for ");
17828                    app.toShortString(sb);
17829                    sb.append(": over ");
17830                    TimeUtils.formatDuration(realtimeSince, sb);
17831                    sb.append(" used ");
17832                    TimeUtils.formatDuration(wtimeUsed, sb);
17833                    sb.append(" (");
17834                    sb.append((wtimeUsed*100)/realtimeSince);
17835                    sb.append("%)");
17836                    Slog.i(TAG_POWER, sb.toString());
17837                    sb.setLength(0);
17838                    sb.append("CPU for ");
17839                    app.toShortString(sb);
17840                    sb.append(": over ");
17841                    TimeUtils.formatDuration(uptimeSince, sb);
17842                    sb.append(" used ");
17843                    TimeUtils.formatDuration(cputimeUsed, sb);
17844                    sb.append(" (");
17845                    sb.append((cputimeUsed*100)/uptimeSince);
17846                    sb.append("%)");
17847                    Slog.i(TAG_POWER, sb.toString());
17848                }
17849                // If a process has held a wake lock for more
17850                // than 50% of the time during this period,
17851                // that sounds bad.  Kill!
17852                if (doWakeKills && realtimeSince > 0
17853                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17854                    synchronized (stats) {
17855                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17856                                realtimeSince, wtimeUsed);
17857                    }
17858                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17859                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17860                } else if (doCpuKills && uptimeSince > 0
17861                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17862                    synchronized (stats) {
17863                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17864                                uptimeSince, cputimeUsed);
17865                    }
17866                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17867                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17868                } else {
17869                    app.lastWakeTime = wtime;
17870                    app.lastCpuTime = app.curCpuTime;
17871                }
17872            }
17873        }
17874    }
17875
17876    private final boolean applyOomAdjLocked(ProcessRecord app,
17877            ProcessRecord TOP_APP, boolean doingAll, long now) {
17878        boolean success = true;
17879
17880        if (app.curRawAdj != app.setRawAdj) {
17881            app.setRawAdj = app.curRawAdj;
17882        }
17883
17884        int changes = 0;
17885
17886        if (app.curAdj != app.setAdj) {
17887            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17888            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
17889                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
17890                    + app.adjType);
17891            app.setAdj = app.curAdj;
17892        }
17893
17894        if (app.setSchedGroup != app.curSchedGroup) {
17895            app.setSchedGroup = app.curSchedGroup;
17896            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
17897                    "Setting process group of " + app.processName
17898                    + " to " + app.curSchedGroup);
17899            if (app.waitingToKill != null &&
17900                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17901                app.kill(app.waitingToKill, true);
17902                success = false;
17903            } else {
17904                if (true) {
17905                    long oldId = Binder.clearCallingIdentity();
17906                    try {
17907                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17908                    } catch (Exception e) {
17909                        Slog.w(TAG, "Failed setting process group of " + app.pid
17910                                + " to " + app.curSchedGroup);
17911                        e.printStackTrace();
17912                    } finally {
17913                        Binder.restoreCallingIdentity(oldId);
17914                    }
17915                } else {
17916                    if (app.thread != null) {
17917                        try {
17918                            app.thread.setSchedulingGroup(app.curSchedGroup);
17919                        } catch (RemoteException e) {
17920                        }
17921                    }
17922                }
17923                Process.setSwappiness(app.pid,
17924                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17925            }
17926        }
17927        if (app.repForegroundActivities != app.foregroundActivities) {
17928            app.repForegroundActivities = app.foregroundActivities;
17929            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17930        }
17931        if (app.repProcState != app.curProcState) {
17932            app.repProcState = app.curProcState;
17933            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17934            if (app.thread != null) {
17935                try {
17936                    if (false) {
17937                        //RuntimeException h = new RuntimeException("here");
17938                        Slog.i(TAG, "Sending new process state " + app.repProcState
17939                                + " to " + app /*, h*/);
17940                    }
17941                    app.thread.setProcessState(app.repProcState);
17942                } catch (RemoteException e) {
17943                }
17944            }
17945        }
17946        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
17947                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
17948            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
17949                // Experimental code to more aggressively collect pss while
17950                // running test...  the problem is that this tends to collect
17951                // the data right when a process is transitioning between process
17952                // states, which well tend to give noisy data.
17953                long start = SystemClock.uptimeMillis();
17954                long pss = Debug.getPss(app.pid, mTmpLong, null);
17955                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], now);
17956                mPendingPssProcesses.remove(app);
17957                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
17958                        + " to " + app.curProcState + ": "
17959                        + (SystemClock.uptimeMillis()-start) + "ms");
17960            }
17961            app.lastStateTime = now;
17962            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17963                    mTestPssMode, isSleeping(), now);
17964            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
17965                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17966                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17967                    + (app.nextPssTime-now) + ": " + app);
17968        } else {
17969            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17970                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
17971                    mTestPssMode)))) {
17972                requestPssLocked(app, app.setProcState);
17973                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17974                        mTestPssMode, isSleeping(), now);
17975            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
17976                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17977        }
17978        if (app.setProcState != app.curProcState) {
17979            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
17980                    "Proc state change of " + app.processName
17981                    + " to " + app.curProcState);
17982            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17983            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17984            if (setImportant && !curImportant) {
17985                // This app is no longer something we consider important enough to allow to
17986                // use arbitrary amounts of battery power.  Note
17987                // its current wake lock time to later know to kill it if
17988                // it is not behaving well.
17989                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17990                synchronized (stats) {
17991                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17992                            app.pid, SystemClock.elapsedRealtime());
17993                }
17994                app.lastCpuTime = app.curCpuTime;
17995
17996            }
17997            // Inform UsageStats of important process state change
17998            // Must be called before updating setProcState
17999            maybeUpdateUsageStats(app);
18000
18001            app.setProcState = app.curProcState;
18002            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18003                app.notCachedSinceIdle = false;
18004            }
18005            if (!doingAll) {
18006                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
18007            } else {
18008                app.procStateChanged = true;
18009            }
18010        }
18011
18012        if (changes != 0) {
18013            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18014                    "Changes in " + app + ": " + changes);
18015            int i = mPendingProcessChanges.size()-1;
18016            ProcessChangeItem item = null;
18017            while (i >= 0) {
18018                item = mPendingProcessChanges.get(i);
18019                if (item.pid == app.pid) {
18020                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18021                            "Re-using existing item: " + item);
18022                    break;
18023                }
18024                i--;
18025            }
18026            if (i < 0) {
18027                // No existing item in pending changes; need a new one.
18028                final int NA = mAvailProcessChanges.size();
18029                if (NA > 0) {
18030                    item = mAvailProcessChanges.remove(NA-1);
18031                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18032                            "Retreiving available item: " + item);
18033                } else {
18034                    item = new ProcessChangeItem();
18035                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18036                            "Allocating new item: " + item);
18037                }
18038                item.changes = 0;
18039                item.pid = app.pid;
18040                item.uid = app.info.uid;
18041                if (mPendingProcessChanges.size() == 0) {
18042                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18043                            "*** Enqueueing dispatch processes changed!");
18044                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
18045                }
18046                mPendingProcessChanges.add(item);
18047            }
18048            item.changes |= changes;
18049            item.processState = app.repProcState;
18050            item.foregroundActivities = app.repForegroundActivities;
18051            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18052                    "Item " + Integer.toHexString(System.identityHashCode(item))
18053                    + " " + app.toShortString() + ": changes=" + item.changes
18054                    + " procState=" + item.processState
18055                    + " foreground=" + item.foregroundActivities
18056                    + " type=" + app.adjType + " source=" + app.adjSource
18057                    + " target=" + app.adjTarget);
18058        }
18059
18060        return success;
18061    }
18062
18063    private void maybeUpdateUsageStats(ProcessRecord app) {
18064        if (DEBUG_USAGE_STATS) {
18065            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
18066                    + "] state changes: old = " + app.setProcState + ", new = "
18067                    + app.curProcState);
18068        }
18069        if (mUsageStatsService == null) {
18070            return;
18071        }
18072        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
18073                && (app.setProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
18074                        || app.setProcState < 0)) {
18075            String[] packages = app.getPackageList();
18076            if (packages != null) {
18077                for (int i = 0; i < packages.length; i++) {
18078                    mUsageStatsService.reportEvent(packages[i], app.userId,
18079                            UsageEvents.Event.INTERACTION);
18080                }
18081            }
18082        }
18083    }
18084
18085    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
18086        if (proc.thread != null) {
18087            if (proc.baseProcessTracker != null) {
18088                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
18089            }
18090            if (proc.repProcState >= 0) {
18091                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
18092                        proc.repProcState);
18093            }
18094        }
18095    }
18096
18097    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
18098            ProcessRecord TOP_APP, boolean doingAll, long now) {
18099        if (app.thread == null) {
18100            return false;
18101        }
18102
18103        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
18104
18105        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
18106    }
18107
18108    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
18109            boolean oomAdj) {
18110        if (isForeground != proc.foregroundServices) {
18111            proc.foregroundServices = isForeground;
18112            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
18113                    proc.info.uid);
18114            if (isForeground) {
18115                if (curProcs == null) {
18116                    curProcs = new ArrayList<ProcessRecord>();
18117                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
18118                }
18119                if (!curProcs.contains(proc)) {
18120                    curProcs.add(proc);
18121                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
18122                            proc.info.packageName, proc.info.uid);
18123                }
18124            } else {
18125                if (curProcs != null) {
18126                    if (curProcs.remove(proc)) {
18127                        mBatteryStatsService.noteEvent(
18128                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
18129                                proc.info.packageName, proc.info.uid);
18130                        if (curProcs.size() <= 0) {
18131                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
18132                        }
18133                    }
18134                }
18135            }
18136            if (oomAdj) {
18137                updateOomAdjLocked();
18138            }
18139        }
18140    }
18141
18142    private final ActivityRecord resumedAppLocked() {
18143        ActivityRecord act = mStackSupervisor.resumedAppLocked();
18144        String pkg;
18145        int uid;
18146        if (act != null) {
18147            pkg = act.packageName;
18148            uid = act.info.applicationInfo.uid;
18149        } else {
18150            pkg = null;
18151            uid = -1;
18152        }
18153        // Has the UID or resumed package name changed?
18154        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
18155                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
18156            if (mCurResumedPackage != null) {
18157                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
18158                        mCurResumedPackage, mCurResumedUid);
18159            }
18160            mCurResumedPackage = pkg;
18161            mCurResumedUid = uid;
18162            if (mCurResumedPackage != null) {
18163                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
18164                        mCurResumedPackage, mCurResumedUid);
18165            }
18166        }
18167        return act;
18168    }
18169
18170    final boolean updateOomAdjLocked(ProcessRecord app) {
18171        final ActivityRecord TOP_ACT = resumedAppLocked();
18172        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18173        final boolean wasCached = app.cached;
18174
18175        mAdjSeq++;
18176
18177        // This is the desired cached adjusment we want to tell it to use.
18178        // If our app is currently cached, we know it, and that is it.  Otherwise,
18179        // we don't know it yet, and it needs to now be cached we will then
18180        // need to do a complete oom adj.
18181        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
18182                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
18183        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
18184                SystemClock.uptimeMillis());
18185        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
18186            // Changed to/from cached state, so apps after it in the LRU
18187            // list may also be changed.
18188            updateOomAdjLocked();
18189        }
18190        return success;
18191    }
18192
18193    final void updateOomAdjLocked() {
18194        final ActivityRecord TOP_ACT = resumedAppLocked();
18195        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18196        final long now = SystemClock.uptimeMillis();
18197        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
18198        final int N = mLruProcesses.size();
18199
18200        if (false) {
18201            RuntimeException e = new RuntimeException();
18202            e.fillInStackTrace();
18203            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
18204        }
18205
18206        mAdjSeq++;
18207        mNewNumServiceProcs = 0;
18208        mNewNumAServiceProcs = 0;
18209
18210        final int emptyProcessLimit;
18211        final int cachedProcessLimit;
18212        if (mProcessLimit <= 0) {
18213            emptyProcessLimit = cachedProcessLimit = 0;
18214        } else if (mProcessLimit == 1) {
18215            emptyProcessLimit = 1;
18216            cachedProcessLimit = 0;
18217        } else {
18218            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
18219            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
18220        }
18221
18222        // Let's determine how many processes we have running vs.
18223        // how many slots we have for background processes; we may want
18224        // to put multiple processes in a slot of there are enough of
18225        // them.
18226        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
18227                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
18228        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
18229        if (numEmptyProcs > cachedProcessLimit) {
18230            // If there are more empty processes than our limit on cached
18231            // processes, then use the cached process limit for the factor.
18232            // This ensures that the really old empty processes get pushed
18233            // down to the bottom, so if we are running low on memory we will
18234            // have a better chance at keeping around more cached processes
18235            // instead of a gazillion empty processes.
18236            numEmptyProcs = cachedProcessLimit;
18237        }
18238        int emptyFactor = numEmptyProcs/numSlots;
18239        if (emptyFactor < 1) emptyFactor = 1;
18240        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
18241        if (cachedFactor < 1) cachedFactor = 1;
18242        int stepCached = 0;
18243        int stepEmpty = 0;
18244        int numCached = 0;
18245        int numEmpty = 0;
18246        int numTrimming = 0;
18247
18248        mNumNonCachedProcs = 0;
18249        mNumCachedHiddenProcs = 0;
18250
18251        // First update the OOM adjustment for each of the
18252        // application processes based on their current state.
18253        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
18254        int nextCachedAdj = curCachedAdj+1;
18255        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
18256        int nextEmptyAdj = curEmptyAdj+2;
18257        for (int i=N-1; i>=0; i--) {
18258            ProcessRecord app = mLruProcesses.get(i);
18259            if (!app.killedByAm && app.thread != null) {
18260                app.procStateChanged = false;
18261                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
18262
18263                // If we haven't yet assigned the final cached adj
18264                // to the process, do that now.
18265                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
18266                    switch (app.curProcState) {
18267                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18268                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18269                            // This process is a cached process holding activities...
18270                            // assign it the next cached value for that type, and then
18271                            // step that cached level.
18272                            app.curRawAdj = curCachedAdj;
18273                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
18274                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
18275                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
18276                                    + ")");
18277                            if (curCachedAdj != nextCachedAdj) {
18278                                stepCached++;
18279                                if (stepCached >= cachedFactor) {
18280                                    stepCached = 0;
18281                                    curCachedAdj = nextCachedAdj;
18282                                    nextCachedAdj += 2;
18283                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18284                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
18285                                    }
18286                                }
18287                            }
18288                            break;
18289                        default:
18290                            // For everything else, assign next empty cached process
18291                            // level and bump that up.  Note that this means that
18292                            // long-running services that have dropped down to the
18293                            // cached level will be treated as empty (since their process
18294                            // state is still as a service), which is what we want.
18295                            app.curRawAdj = curEmptyAdj;
18296                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
18297                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
18298                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
18299                                    + ")");
18300                            if (curEmptyAdj != nextEmptyAdj) {
18301                                stepEmpty++;
18302                                if (stepEmpty >= emptyFactor) {
18303                                    stepEmpty = 0;
18304                                    curEmptyAdj = nextEmptyAdj;
18305                                    nextEmptyAdj += 2;
18306                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18307                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
18308                                    }
18309                                }
18310                            }
18311                            break;
18312                    }
18313                }
18314
18315                applyOomAdjLocked(app, TOP_APP, true, now);
18316
18317                // Count the number of process types.
18318                switch (app.curProcState) {
18319                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18320                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18321                        mNumCachedHiddenProcs++;
18322                        numCached++;
18323                        if (numCached > cachedProcessLimit) {
18324                            app.kill("cached #" + numCached, true);
18325                        }
18326                        break;
18327                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
18328                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
18329                                && app.lastActivityTime < oldTime) {
18330                            app.kill("empty for "
18331                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
18332                                    / 1000) + "s", true);
18333                        } else {
18334                            numEmpty++;
18335                            if (numEmpty > emptyProcessLimit) {
18336                                app.kill("empty #" + numEmpty, true);
18337                            }
18338                        }
18339                        break;
18340                    default:
18341                        mNumNonCachedProcs++;
18342                        break;
18343                }
18344
18345                if (app.isolated && app.services.size() <= 0) {
18346                    // If this is an isolated process, and there are no
18347                    // services running in it, then the process is no longer
18348                    // needed.  We agressively kill these because we can by
18349                    // definition not re-use the same process again, and it is
18350                    // good to avoid having whatever code was running in them
18351                    // left sitting around after no longer needed.
18352                    app.kill("isolated not needed", true);
18353                }
18354
18355                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18356                        && !app.killedByAm) {
18357                    numTrimming++;
18358                }
18359            }
18360        }
18361
18362        mNumServiceProcs = mNewNumServiceProcs;
18363
18364        // Now determine the memory trimming level of background processes.
18365        // Unfortunately we need to start at the back of the list to do this
18366        // properly.  We only do this if the number of background apps we
18367        // are managing to keep around is less than half the maximum we desire;
18368        // if we are keeping a good number around, we'll let them use whatever
18369        // memory they want.
18370        final int numCachedAndEmpty = numCached + numEmpty;
18371        int memFactor;
18372        if (numCached <= ProcessList.TRIM_CACHED_APPS
18373                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
18374            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
18375                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
18376            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
18377                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
18378            } else {
18379                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
18380            }
18381        } else {
18382            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
18383        }
18384        // We always allow the memory level to go up (better).  We only allow it to go
18385        // down if we are in a state where that is allowed, *and* the total number of processes
18386        // has gone down since last time.
18387        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
18388                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
18389                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
18390        if (memFactor > mLastMemoryLevel) {
18391            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
18392                memFactor = mLastMemoryLevel;
18393                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
18394            }
18395        }
18396        mLastMemoryLevel = memFactor;
18397        mLastNumProcesses = mLruProcesses.size();
18398        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
18399        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
18400        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
18401            if (mLowRamStartTime == 0) {
18402                mLowRamStartTime = now;
18403            }
18404            int step = 0;
18405            int fgTrimLevel;
18406            switch (memFactor) {
18407                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18408                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
18409                    break;
18410                case ProcessStats.ADJ_MEM_FACTOR_LOW:
18411                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
18412                    break;
18413                default:
18414                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
18415                    break;
18416            }
18417            int factor = numTrimming/3;
18418            int minFactor = 2;
18419            if (mHomeProcess != null) minFactor++;
18420            if (mPreviousProcess != null) minFactor++;
18421            if (factor < minFactor) factor = minFactor;
18422            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
18423            for (int i=N-1; i>=0; i--) {
18424                ProcessRecord app = mLruProcesses.get(i);
18425                if (allChanged || app.procStateChanged) {
18426                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18427                    app.procStateChanged = false;
18428                }
18429                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18430                        && !app.killedByAm) {
18431                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
18432                        try {
18433                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18434                                    "Trimming memory of " + app.processName + " to " + curLevel);
18435                            app.thread.scheduleTrimMemory(curLevel);
18436                        } catch (RemoteException e) {
18437                        }
18438                        if (false) {
18439                            // For now we won't do this; our memory trimming seems
18440                            // to be good enough at this point that destroying
18441                            // activities causes more harm than good.
18442                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
18443                                    && app != mHomeProcess && app != mPreviousProcess) {
18444                                // Need to do this on its own message because the stack may not
18445                                // be in a consistent state at this point.
18446                                // For these apps we will also finish their activities
18447                                // to help them free memory.
18448                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
18449                            }
18450                        }
18451                    }
18452                    app.trimMemoryLevel = curLevel;
18453                    step++;
18454                    if (step >= factor) {
18455                        step = 0;
18456                        switch (curLevel) {
18457                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18458                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18459                                break;
18460                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18461                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18462                                break;
18463                        }
18464                    }
18465                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18466                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18467                            && app.thread != null) {
18468                        try {
18469                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18470                                    "Trimming memory of heavy-weight " + app.processName
18471                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18472                            app.thread.scheduleTrimMemory(
18473                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18474                        } catch (RemoteException e) {
18475                        }
18476                    }
18477                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18478                } else {
18479                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18480                            || app.systemNoUi) && app.pendingUiClean) {
18481                        // If this application is now in the background and it
18482                        // had done UI, then give it the special trim level to
18483                        // have it free UI resources.
18484                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18485                        if (app.trimMemoryLevel < level && app.thread != null) {
18486                            try {
18487                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18488                                        "Trimming memory of bg-ui " + app.processName
18489                                        + " to " + level);
18490                                app.thread.scheduleTrimMemory(level);
18491                            } catch (RemoteException e) {
18492                            }
18493                        }
18494                        app.pendingUiClean = false;
18495                    }
18496                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18497                        try {
18498                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18499                                    "Trimming memory of fg " + app.processName
18500                                    + " to " + fgTrimLevel);
18501                            app.thread.scheduleTrimMemory(fgTrimLevel);
18502                        } catch (RemoteException e) {
18503                        }
18504                    }
18505                    app.trimMemoryLevel = fgTrimLevel;
18506                }
18507            }
18508        } else {
18509            if (mLowRamStartTime != 0) {
18510                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18511                mLowRamStartTime = 0;
18512            }
18513            for (int i=N-1; i>=0; i--) {
18514                ProcessRecord app = mLruProcesses.get(i);
18515                if (allChanged || app.procStateChanged) {
18516                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18517                    app.procStateChanged = false;
18518                }
18519                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18520                        || app.systemNoUi) && app.pendingUiClean) {
18521                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18522                            && app.thread != null) {
18523                        try {
18524                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18525                                    "Trimming memory of ui hidden " + app.processName
18526                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18527                            app.thread.scheduleTrimMemory(
18528                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18529                        } catch (RemoteException e) {
18530                        }
18531                    }
18532                    app.pendingUiClean = false;
18533                }
18534                app.trimMemoryLevel = 0;
18535            }
18536        }
18537
18538        if (mAlwaysFinishActivities) {
18539            // Need to do this on its own message because the stack may not
18540            // be in a consistent state at this point.
18541            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18542        }
18543
18544        if (allChanged) {
18545            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18546        }
18547
18548        if (mProcessStats.shouldWriteNowLocked(now)) {
18549            mHandler.post(new Runnable() {
18550                @Override public void run() {
18551                    synchronized (ActivityManagerService.this) {
18552                        mProcessStats.writeStateAsyncLocked();
18553                    }
18554                }
18555            });
18556        }
18557
18558        if (DEBUG_OOM_ADJ) {
18559            final long duration = SystemClock.uptimeMillis() - now;
18560            if (false) {
18561                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
18562                        new RuntimeException("here").fillInStackTrace());
18563            } else {
18564                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
18565            }
18566        }
18567    }
18568
18569    final void trimApplications() {
18570        synchronized (this) {
18571            int i;
18572
18573            // First remove any unused application processes whose package
18574            // has been removed.
18575            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18576                final ProcessRecord app = mRemovedProcesses.get(i);
18577                if (app.activities.size() == 0
18578                        && app.curReceiver == null && app.services.size() == 0) {
18579                    Slog.i(
18580                        TAG, "Exiting empty application process "
18581                        + app.processName + " ("
18582                        + (app.thread != null ? app.thread.asBinder() : null)
18583                        + ")\n");
18584                    if (app.pid > 0 && app.pid != MY_PID) {
18585                        app.kill("empty", false);
18586                    } else {
18587                        try {
18588                            app.thread.scheduleExit();
18589                        } catch (Exception e) {
18590                            // Ignore exceptions.
18591                        }
18592                    }
18593                    cleanUpApplicationRecordLocked(app, false, true, -1);
18594                    mRemovedProcesses.remove(i);
18595
18596                    if (app.persistent) {
18597                        addAppLocked(app.info, false, null /* ABI override */);
18598                    }
18599                }
18600            }
18601
18602            // Now update the oom adj for all processes.
18603            updateOomAdjLocked();
18604        }
18605    }
18606
18607    /** This method sends the specified signal to each of the persistent apps */
18608    public void signalPersistentProcesses(int sig) throws RemoteException {
18609        if (sig != Process.SIGNAL_USR1) {
18610            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18611        }
18612
18613        synchronized (this) {
18614            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18615                    != PackageManager.PERMISSION_GRANTED) {
18616                throw new SecurityException("Requires permission "
18617                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18618            }
18619
18620            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18621                ProcessRecord r = mLruProcesses.get(i);
18622                if (r.thread != null && r.persistent) {
18623                    Process.sendSignal(r.pid, sig);
18624                }
18625            }
18626        }
18627    }
18628
18629    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18630        if (proc == null || proc == mProfileProc) {
18631            proc = mProfileProc;
18632            profileType = mProfileType;
18633            clearProfilerLocked();
18634        }
18635        if (proc == null) {
18636            return;
18637        }
18638        try {
18639            proc.thread.profilerControl(false, null, profileType);
18640        } catch (RemoteException e) {
18641            throw new IllegalStateException("Process disappeared");
18642        }
18643    }
18644
18645    private void clearProfilerLocked() {
18646        if (mProfileFd != null) {
18647            try {
18648                mProfileFd.close();
18649            } catch (IOException e) {
18650            }
18651        }
18652        mProfileApp = null;
18653        mProfileProc = null;
18654        mProfileFile = null;
18655        mProfileType = 0;
18656        mAutoStopProfiler = false;
18657        mSamplingInterval = 0;
18658    }
18659
18660    public boolean profileControl(String process, int userId, boolean start,
18661            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18662
18663        try {
18664            synchronized (this) {
18665                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18666                // its own permission.
18667                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18668                        != PackageManager.PERMISSION_GRANTED) {
18669                    throw new SecurityException("Requires permission "
18670                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18671                }
18672
18673                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18674                    throw new IllegalArgumentException("null profile info or fd");
18675                }
18676
18677                ProcessRecord proc = null;
18678                if (process != null) {
18679                    proc = findProcessLocked(process, userId, "profileControl");
18680                }
18681
18682                if (start && (proc == null || proc.thread == null)) {
18683                    throw new IllegalArgumentException("Unknown process: " + process);
18684                }
18685
18686                if (start) {
18687                    stopProfilerLocked(null, 0);
18688                    setProfileApp(proc.info, proc.processName, profilerInfo);
18689                    mProfileProc = proc;
18690                    mProfileType = profileType;
18691                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18692                    try {
18693                        fd = fd.dup();
18694                    } catch (IOException e) {
18695                        fd = null;
18696                    }
18697                    profilerInfo.profileFd = fd;
18698                    proc.thread.profilerControl(start, profilerInfo, profileType);
18699                    fd = null;
18700                    mProfileFd = null;
18701                } else {
18702                    stopProfilerLocked(proc, profileType);
18703                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18704                        try {
18705                            profilerInfo.profileFd.close();
18706                        } catch (IOException e) {
18707                        }
18708                    }
18709                }
18710
18711                return true;
18712            }
18713        } catch (RemoteException e) {
18714            throw new IllegalStateException("Process disappeared");
18715        } finally {
18716            if (profilerInfo != null && profilerInfo.profileFd != null) {
18717                try {
18718                    profilerInfo.profileFd.close();
18719                } catch (IOException e) {
18720                }
18721            }
18722        }
18723    }
18724
18725    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18726        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18727                userId, true, ALLOW_FULL_ONLY, callName, null);
18728        ProcessRecord proc = null;
18729        try {
18730            int pid = Integer.parseInt(process);
18731            synchronized (mPidsSelfLocked) {
18732                proc = mPidsSelfLocked.get(pid);
18733            }
18734        } catch (NumberFormatException e) {
18735        }
18736
18737        if (proc == null) {
18738            ArrayMap<String, SparseArray<ProcessRecord>> all
18739                    = mProcessNames.getMap();
18740            SparseArray<ProcessRecord> procs = all.get(process);
18741            if (procs != null && procs.size() > 0) {
18742                proc = procs.valueAt(0);
18743                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18744                    for (int i=1; i<procs.size(); i++) {
18745                        ProcessRecord thisProc = procs.valueAt(i);
18746                        if (thisProc.userId == userId) {
18747                            proc = thisProc;
18748                            break;
18749                        }
18750                    }
18751                }
18752            }
18753        }
18754
18755        return proc;
18756    }
18757
18758    public boolean dumpHeap(String process, int userId, boolean managed,
18759            String path, ParcelFileDescriptor fd) throws RemoteException {
18760
18761        try {
18762            synchronized (this) {
18763                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18764                // its own permission (same as profileControl).
18765                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18766                        != PackageManager.PERMISSION_GRANTED) {
18767                    throw new SecurityException("Requires permission "
18768                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18769                }
18770
18771                if (fd == null) {
18772                    throw new IllegalArgumentException("null fd");
18773                }
18774
18775                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18776                if (proc == null || proc.thread == null) {
18777                    throw new IllegalArgumentException("Unknown process: " + process);
18778                }
18779
18780                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18781                if (!isDebuggable) {
18782                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18783                        throw new SecurityException("Process not debuggable: " + proc);
18784                    }
18785                }
18786
18787                proc.thread.dumpHeap(managed, path, fd);
18788                fd = null;
18789                return true;
18790            }
18791        } catch (RemoteException e) {
18792            throw new IllegalStateException("Process disappeared");
18793        } finally {
18794            if (fd != null) {
18795                try {
18796                    fd.close();
18797                } catch (IOException e) {
18798                }
18799            }
18800        }
18801    }
18802
18803    @Override
18804    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
18805            String reportPackage) {
18806        if (processName != null) {
18807            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
18808                    "setDumpHeapDebugLimit()");
18809        } else {
18810            if (!Build.IS_DEBUGGABLE) {
18811                throw new SecurityException("Not running a debuggable build");
18812            }
18813            synchronized (mPidsSelfLocked) {
18814                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
18815                if (proc == null) {
18816                    throw new SecurityException("No process found for calling pid "
18817                            + Binder.getCallingPid());
18818                }
18819                processName = proc.processName;
18820                uid = proc.uid;
18821                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
18822                    throw new SecurityException("Package " + reportPackage + " is not running in "
18823                            + proc);
18824                }
18825            }
18826        }
18827        synchronized (this) {
18828            if (maxMemSize > 0) {
18829                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
18830            } else {
18831                if (uid != 0) {
18832                    mMemWatchProcesses.remove(processName, uid);
18833                } else {
18834                    mMemWatchProcesses.getMap().remove(processName);
18835                }
18836            }
18837        }
18838    }
18839
18840    @Override
18841    public void dumpHeapFinished(String path) {
18842        synchronized (this) {
18843            if (Binder.getCallingPid() != mMemWatchDumpPid) {
18844                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
18845                        + " does not match last pid " + mMemWatchDumpPid);
18846                return;
18847            }
18848            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
18849                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
18850                        + " does not match last path " + mMemWatchDumpFile);
18851                return;
18852            }
18853            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
18854            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
18855        }
18856    }
18857
18858    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18859    public void monitor() {
18860        synchronized (this) { }
18861    }
18862
18863    void onCoreSettingsChange(Bundle settings) {
18864        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18865            ProcessRecord processRecord = mLruProcesses.get(i);
18866            try {
18867                if (processRecord.thread != null) {
18868                    processRecord.thread.setCoreSettings(settings);
18869                }
18870            } catch (RemoteException re) {
18871                /* ignore */
18872            }
18873        }
18874    }
18875
18876    // Multi-user methods
18877
18878    /**
18879     * Start user, if its not already running, but don't bring it to foreground.
18880     */
18881    @Override
18882    public boolean startUserInBackground(final int userId) {
18883        return startUser(userId, /* foreground */ false);
18884    }
18885
18886    /**
18887     * Start user, if its not already running, and bring it to foreground.
18888     */
18889    boolean startUserInForeground(final int userId, Dialog dlg) {
18890        boolean result = startUser(userId, /* foreground */ true);
18891        dlg.dismiss();
18892        return result;
18893    }
18894
18895    /**
18896     * Refreshes the list of users related to the current user when either a
18897     * user switch happens or when a new related user is started in the
18898     * background.
18899     */
18900    private void updateCurrentProfileIdsLocked() {
18901        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18902                mCurrentUserId, false /* enabledOnly */);
18903        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18904        for (int i = 0; i < currentProfileIds.length; i++) {
18905            currentProfileIds[i] = profiles.get(i).id;
18906        }
18907        mCurrentProfileIds = currentProfileIds;
18908
18909        synchronized (mUserProfileGroupIdsSelfLocked) {
18910            mUserProfileGroupIdsSelfLocked.clear();
18911            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18912            for (int i = 0; i < users.size(); i++) {
18913                UserInfo user = users.get(i);
18914                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18915                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18916                }
18917            }
18918        }
18919    }
18920
18921    private Set<Integer> getProfileIdsLocked(int userId) {
18922        Set<Integer> userIds = new HashSet<Integer>();
18923        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18924                userId, false /* enabledOnly */);
18925        for (UserInfo user : profiles) {
18926            userIds.add(Integer.valueOf(user.id));
18927        }
18928        return userIds;
18929    }
18930
18931    @Override
18932    public boolean switchUser(final int userId) {
18933        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18934        String userName;
18935        synchronized (this) {
18936            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18937            if (userInfo == null) {
18938                Slog.w(TAG, "No user info for user #" + userId);
18939                return false;
18940            }
18941            if (userInfo.isManagedProfile()) {
18942                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18943                return false;
18944            }
18945            userName = userInfo.name;
18946            mTargetUserId = userId;
18947        }
18948        mHandler.removeMessages(START_USER_SWITCH_MSG);
18949        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18950        return true;
18951    }
18952
18953    private void showUserSwitchDialog(int userId, String userName) {
18954        // The dialog will show and then initiate the user switch by calling startUserInForeground
18955        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18956                true /* above system */);
18957        d.show();
18958    }
18959
18960    private boolean startUser(final int userId, final boolean foreground) {
18961        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18962                != PackageManager.PERMISSION_GRANTED) {
18963            String msg = "Permission Denial: switchUser() from pid="
18964                    + Binder.getCallingPid()
18965                    + ", uid=" + Binder.getCallingUid()
18966                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18967            Slog.w(TAG, msg);
18968            throw new SecurityException(msg);
18969        }
18970
18971        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18972
18973        final long ident = Binder.clearCallingIdentity();
18974        try {
18975            synchronized (this) {
18976                final int oldUserId = mCurrentUserId;
18977                if (oldUserId == userId) {
18978                    return true;
18979                }
18980
18981                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
18982                        "startUser");
18983
18984                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18985                if (userInfo == null) {
18986                    Slog.w(TAG, "No user info for user #" + userId);
18987                    return false;
18988                }
18989                if (foreground && userInfo.isManagedProfile()) {
18990                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18991                    return false;
18992                }
18993
18994                if (foreground) {
18995                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18996                            R.anim.screen_user_enter);
18997                }
18998
18999                boolean needStart = false;
19000
19001                // If the user we are switching to is not currently started, then
19002                // we need to start it now.
19003                if (mStartedUsers.get(userId) == null) {
19004                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
19005                    updateStartedUserArrayLocked();
19006                    needStart = true;
19007                }
19008
19009                final Integer userIdInt = Integer.valueOf(userId);
19010                mUserLru.remove(userIdInt);
19011                mUserLru.add(userIdInt);
19012
19013                if (foreground) {
19014                    mCurrentUserId = userId;
19015                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
19016                    updateCurrentProfileIdsLocked();
19017                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
19018                    // Once the internal notion of the active user has switched, we lock the device
19019                    // with the option to show the user switcher on the keyguard.
19020                    mWindowManager.lockNow(null);
19021                } else {
19022                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
19023                    updateCurrentProfileIdsLocked();
19024                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
19025                    mUserLru.remove(currentUserIdInt);
19026                    mUserLru.add(currentUserIdInt);
19027                }
19028
19029                final UserStartedState uss = mStartedUsers.get(userId);
19030
19031                // Make sure user is in the started state.  If it is currently
19032                // stopping, we need to knock that off.
19033                if (uss.mState == UserStartedState.STATE_STOPPING) {
19034                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
19035                    // so we can just fairly silently bring the user back from
19036                    // the almost-dead.
19037                    uss.mState = UserStartedState.STATE_RUNNING;
19038                    updateStartedUserArrayLocked();
19039                    needStart = true;
19040                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
19041                    // This means ACTION_SHUTDOWN has been sent, so we will
19042                    // need to treat this as a new boot of the user.
19043                    uss.mState = UserStartedState.STATE_BOOTING;
19044                    updateStartedUserArrayLocked();
19045                    needStart = true;
19046                }
19047
19048                if (uss.mState == UserStartedState.STATE_BOOTING) {
19049                    // Booting up a new user, need to tell system services about it.
19050                    // Note that this is on the same handler as scheduling of broadcasts,
19051                    // which is important because it needs to go first.
19052                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
19053                }
19054
19055                if (foreground) {
19056                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
19057                            oldUserId));
19058                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
19059                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19060                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
19061                            oldUserId, userId, uss));
19062                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
19063                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
19064                }
19065
19066                if (needStart) {
19067                    // Send USER_STARTED broadcast
19068                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
19069                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19070                            | Intent.FLAG_RECEIVER_FOREGROUND);
19071                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19072                    broadcastIntentLocked(null, null, intent,
19073                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19074                            false, false, MY_PID, Process.SYSTEM_UID, userId);
19075                }
19076
19077                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
19078                    if (userId != UserHandle.USER_OWNER) {
19079                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
19080                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19081                        broadcastIntentLocked(null, null, intent, null,
19082                                new IIntentReceiver.Stub() {
19083                                    public void performReceive(Intent intent, int resultCode,
19084                                            String data, Bundle extras, boolean ordered,
19085                                            boolean sticky, int sendingUser) {
19086                                        onUserInitialized(uss, foreground, oldUserId, userId);
19087                                    }
19088                                }, 0, null, null, null, AppOpsManager.OP_NONE,
19089                                true, false, MY_PID, Process.SYSTEM_UID,
19090                                userId);
19091                        uss.initializing = true;
19092                    } else {
19093                        getUserManagerLocked().makeInitialized(userInfo.id);
19094                    }
19095                }
19096
19097                if (foreground) {
19098                    if (!uss.initializing) {
19099                        moveUserToForeground(uss, oldUserId, userId);
19100                    }
19101                } else {
19102                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
19103                }
19104
19105                if (needStart) {
19106                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
19107                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19108                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19109                    broadcastIntentLocked(null, null, intent,
19110                            null, new IIntentReceiver.Stub() {
19111                                @Override
19112                                public void performReceive(Intent intent, int resultCode, String data,
19113                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
19114                                        throws RemoteException {
19115                                }
19116                            }, 0, null, null,
19117                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19118                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19119                }
19120            }
19121        } finally {
19122            Binder.restoreCallingIdentity(ident);
19123        }
19124
19125        return true;
19126    }
19127
19128    void dispatchForegroundProfileChanged(int userId) {
19129        final int N = mUserSwitchObservers.beginBroadcast();
19130        for (int i = 0; i < N; i++) {
19131            try {
19132                mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
19133            } catch (RemoteException e) {
19134                // Ignore
19135            }
19136        }
19137        mUserSwitchObservers.finishBroadcast();
19138    }
19139
19140    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
19141        long ident = Binder.clearCallingIdentity();
19142        try {
19143            Intent intent;
19144            if (oldUserId >= 0) {
19145                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
19146                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
19147                int count = profiles.size();
19148                for (int i = 0; i < count; i++) {
19149                    int profileUserId = profiles.get(i).id;
19150                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
19151                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19152                            | Intent.FLAG_RECEIVER_FOREGROUND);
19153                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19154                    broadcastIntentLocked(null, null, intent,
19155                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19156                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19157                }
19158            }
19159            if (newUserId >= 0) {
19160                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
19161                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
19162                int count = profiles.size();
19163                for (int i = 0; i < count; i++) {
19164                    int profileUserId = profiles.get(i).id;
19165                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
19166                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19167                            | Intent.FLAG_RECEIVER_FOREGROUND);
19168                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19169                    broadcastIntentLocked(null, null, intent,
19170                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19171                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19172                }
19173                intent = new Intent(Intent.ACTION_USER_SWITCHED);
19174                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19175                        | Intent.FLAG_RECEIVER_FOREGROUND);
19176                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
19177                broadcastIntentLocked(null, null, intent,
19178                        null, null, 0, null, null,
19179                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
19180                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19181            }
19182        } finally {
19183            Binder.restoreCallingIdentity(ident);
19184        }
19185    }
19186
19187    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
19188            final int newUserId) {
19189        final int N = mUserSwitchObservers.beginBroadcast();
19190        if (N > 0) {
19191            final IRemoteCallback callback = new IRemoteCallback.Stub() {
19192                int mCount = 0;
19193                @Override
19194                public void sendResult(Bundle data) throws RemoteException {
19195                    synchronized (ActivityManagerService.this) {
19196                        if (mCurUserSwitchCallback == this) {
19197                            mCount++;
19198                            if (mCount == N) {
19199                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19200                            }
19201                        }
19202                    }
19203                }
19204            };
19205            synchronized (this) {
19206                uss.switching = true;
19207                mCurUserSwitchCallback = callback;
19208            }
19209            for (int i=0; i<N; i++) {
19210                try {
19211                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
19212                            newUserId, callback);
19213                } catch (RemoteException e) {
19214                }
19215            }
19216        } else {
19217            synchronized (this) {
19218                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19219            }
19220        }
19221        mUserSwitchObservers.finishBroadcast();
19222    }
19223
19224    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
19225        synchronized (this) {
19226            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
19227            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19228        }
19229    }
19230
19231    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
19232        mCurUserSwitchCallback = null;
19233        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19234        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
19235                oldUserId, newUserId, uss));
19236    }
19237
19238    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
19239        synchronized (this) {
19240            if (foreground) {
19241                moveUserToForeground(uss, oldUserId, newUserId);
19242            }
19243        }
19244
19245        completeSwitchAndInitalize(uss, newUserId, true, false);
19246    }
19247
19248    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
19249        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
19250        if (homeInFront) {
19251            startHomeActivityLocked(newUserId, "moveUserToFroreground");
19252        } else {
19253            mStackSupervisor.resumeTopActivitiesLocked();
19254        }
19255        EventLogTags.writeAmSwitchUser(newUserId);
19256        getUserManagerLocked().userForeground(newUserId);
19257        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
19258    }
19259
19260    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
19261        completeSwitchAndInitalize(uss, newUserId, false, true);
19262    }
19263
19264    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
19265            boolean clearInitializing, boolean clearSwitching) {
19266        boolean unfrozen = false;
19267        synchronized (this) {
19268            if (clearInitializing) {
19269                uss.initializing = false;
19270                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
19271            }
19272            if (clearSwitching) {
19273                uss.switching = false;
19274            }
19275            if (!uss.switching && !uss.initializing) {
19276                mWindowManager.stopFreezingScreen();
19277                unfrozen = true;
19278            }
19279        }
19280        if (unfrozen) {
19281            final int N = mUserSwitchObservers.beginBroadcast();
19282            for (int i=0; i<N; i++) {
19283                try {
19284                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
19285                } catch (RemoteException e) {
19286                }
19287            }
19288            mUserSwitchObservers.finishBroadcast();
19289        }
19290        stopGuestUserIfBackground();
19291    }
19292
19293    /**
19294     * Stops the guest user if it has gone to the background.
19295     */
19296    private void stopGuestUserIfBackground() {
19297        synchronized (this) {
19298            final int num = mUserLru.size();
19299            for (int i = 0; i < num; i++) {
19300                Integer oldUserId = mUserLru.get(i);
19301                UserStartedState oldUss = mStartedUsers.get(oldUserId);
19302                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
19303                        || oldUss.mState == UserStartedState.STATE_STOPPING
19304                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19305                    continue;
19306                }
19307                UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
19308                if (userInfo.isGuest()) {
19309                    // This is a user to be stopped.
19310                    stopUserLocked(oldUserId, null);
19311                    break;
19312                }
19313            }
19314        }
19315    }
19316
19317    void scheduleStartProfilesLocked() {
19318        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
19319            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
19320                    DateUtils.SECOND_IN_MILLIS);
19321        }
19322    }
19323
19324    void startProfilesLocked() {
19325        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
19326        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19327                mCurrentUserId, false /* enabledOnly */);
19328        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
19329        for (UserInfo user : profiles) {
19330            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
19331                    && user.id != mCurrentUserId) {
19332                toStart.add(user);
19333            }
19334        }
19335        final int n = toStart.size();
19336        int i = 0;
19337        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
19338            startUserInBackground(toStart.get(i).id);
19339        }
19340        if (i < n) {
19341            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
19342        }
19343    }
19344
19345    void finishUserBoot(UserStartedState uss) {
19346        synchronized (this) {
19347            if (uss.mState == UserStartedState.STATE_BOOTING
19348                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
19349                uss.mState = UserStartedState.STATE_RUNNING;
19350                final int userId = uss.mHandle.getIdentifier();
19351                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
19352                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19353                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
19354                broadcastIntentLocked(null, null, intent,
19355                        null, null, 0, null, null,
19356                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
19357                        true, false, MY_PID, Process.SYSTEM_UID, userId);
19358            }
19359        }
19360    }
19361
19362    void finishUserSwitch(UserStartedState uss) {
19363        synchronized (this) {
19364            finishUserBoot(uss);
19365
19366            startProfilesLocked();
19367
19368            int num = mUserLru.size();
19369            int i = 0;
19370            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
19371                Integer oldUserId = mUserLru.get(i);
19372                UserStartedState oldUss = mStartedUsers.get(oldUserId);
19373                if (oldUss == null) {
19374                    // Shouldn't happen, but be sane if it does.
19375                    mUserLru.remove(i);
19376                    num--;
19377                    continue;
19378                }
19379                if (oldUss.mState == UserStartedState.STATE_STOPPING
19380                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19381                    // This user is already stopping, doesn't count.
19382                    num--;
19383                    i++;
19384                    continue;
19385                }
19386                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
19387                    // Owner and current can't be stopped, but count as running.
19388                    i++;
19389                    continue;
19390                }
19391                // This is a user to be stopped.
19392                stopUserLocked(oldUserId, null);
19393                num--;
19394                i++;
19395            }
19396        }
19397    }
19398
19399    @Override
19400    public int stopUser(final int userId, final IStopUserCallback callback) {
19401        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19402                != PackageManager.PERMISSION_GRANTED) {
19403            String msg = "Permission Denial: switchUser() from pid="
19404                    + Binder.getCallingPid()
19405                    + ", uid=" + Binder.getCallingUid()
19406                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19407            Slog.w(TAG, msg);
19408            throw new SecurityException(msg);
19409        }
19410        if (userId < 0 || userId == UserHandle.USER_OWNER) {
19411            throw new IllegalArgumentException("Can't stop primary user " + userId);
19412        }
19413        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19414        synchronized (this) {
19415            return stopUserLocked(userId, callback);
19416        }
19417    }
19418
19419    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
19420        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
19421        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
19422            return ActivityManager.USER_OP_IS_CURRENT;
19423        }
19424
19425        final UserStartedState uss = mStartedUsers.get(userId);
19426        if (uss == null) {
19427            // User is not started, nothing to do...  but we do need to
19428            // callback if requested.
19429            if (callback != null) {
19430                mHandler.post(new Runnable() {
19431                    @Override
19432                    public void run() {
19433                        try {
19434                            callback.userStopped(userId);
19435                        } catch (RemoteException e) {
19436                        }
19437                    }
19438                });
19439            }
19440            return ActivityManager.USER_OP_SUCCESS;
19441        }
19442
19443        if (callback != null) {
19444            uss.mStopCallbacks.add(callback);
19445        }
19446
19447        if (uss.mState != UserStartedState.STATE_STOPPING
19448                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19449            uss.mState = UserStartedState.STATE_STOPPING;
19450            updateStartedUserArrayLocked();
19451
19452            long ident = Binder.clearCallingIdentity();
19453            try {
19454                // We are going to broadcast ACTION_USER_STOPPING and then
19455                // once that is done send a final ACTION_SHUTDOWN and then
19456                // stop the user.
19457                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
19458                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19459                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19460                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
19461                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
19462                // This is the result receiver for the final shutdown broadcast.
19463                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
19464                    @Override
19465                    public void performReceive(Intent intent, int resultCode, String data,
19466                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19467                        finishUserStop(uss);
19468                    }
19469                };
19470                // This is the result receiver for the initial stopping broadcast.
19471                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
19472                    @Override
19473                    public void performReceive(Intent intent, int resultCode, String data,
19474                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19475                        // On to the next.
19476                        synchronized (ActivityManagerService.this) {
19477                            if (uss.mState != UserStartedState.STATE_STOPPING) {
19478                                // Whoops, we are being started back up.  Abort, abort!
19479                                return;
19480                            }
19481                            uss.mState = UserStartedState.STATE_SHUTDOWN;
19482                        }
19483                        mBatteryStatsService.noteEvent(
19484                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
19485                                Integer.toString(userId), userId);
19486                        mSystemServiceManager.stopUser(userId);
19487                        broadcastIntentLocked(null, null, shutdownIntent,
19488                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
19489                                true, false, MY_PID, Process.SYSTEM_UID, userId);
19490                    }
19491                };
19492                // Kick things off.
19493                broadcastIntentLocked(null, null, stoppingIntent,
19494                        null, stoppingReceiver, 0, null, null,
19495                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19496                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19497            } finally {
19498                Binder.restoreCallingIdentity(ident);
19499            }
19500        }
19501
19502        return ActivityManager.USER_OP_SUCCESS;
19503    }
19504
19505    void finishUserStop(UserStartedState uss) {
19506        final int userId = uss.mHandle.getIdentifier();
19507        boolean stopped;
19508        ArrayList<IStopUserCallback> callbacks;
19509        synchronized (this) {
19510            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
19511            if (mStartedUsers.get(userId) != uss) {
19512                stopped = false;
19513            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
19514                stopped = false;
19515            } else {
19516                stopped = true;
19517                // User can no longer run.
19518                mStartedUsers.remove(userId);
19519                mUserLru.remove(Integer.valueOf(userId));
19520                updateStartedUserArrayLocked();
19521
19522                // Clean up all state and processes associated with the user.
19523                // Kill all the processes for the user.
19524                forceStopUserLocked(userId, "finish user");
19525            }
19526
19527            // Explicitly remove the old information in mRecentTasks.
19528            mRecentTasks.removeTasksForUserLocked(userId);
19529        }
19530
19531        for (int i=0; i<callbacks.size(); i++) {
19532            try {
19533                if (stopped) callbacks.get(i).userStopped(userId);
19534                else callbacks.get(i).userStopAborted(userId);
19535            } catch (RemoteException e) {
19536            }
19537        }
19538
19539        if (stopped) {
19540            mSystemServiceManager.cleanupUser(userId);
19541            synchronized (this) {
19542                mStackSupervisor.removeUserLocked(userId);
19543            }
19544        }
19545    }
19546
19547    @Override
19548    public UserInfo getCurrentUser() {
19549        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
19550                != PackageManager.PERMISSION_GRANTED) && (
19551                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19552                != PackageManager.PERMISSION_GRANTED)) {
19553            String msg = "Permission Denial: getCurrentUser() from pid="
19554                    + Binder.getCallingPid()
19555                    + ", uid=" + Binder.getCallingUid()
19556                    + " requires " + INTERACT_ACROSS_USERS;
19557            Slog.w(TAG, msg);
19558            throw new SecurityException(msg);
19559        }
19560        synchronized (this) {
19561            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19562            return getUserManagerLocked().getUserInfo(userId);
19563        }
19564    }
19565
19566    int getCurrentUserIdLocked() {
19567        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19568    }
19569
19570    @Override
19571    public boolean isUserRunning(int userId, boolean orStopped) {
19572        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19573                != PackageManager.PERMISSION_GRANTED) {
19574            String msg = "Permission Denial: isUserRunning() from pid="
19575                    + Binder.getCallingPid()
19576                    + ", uid=" + Binder.getCallingUid()
19577                    + " requires " + INTERACT_ACROSS_USERS;
19578            Slog.w(TAG, msg);
19579            throw new SecurityException(msg);
19580        }
19581        synchronized (this) {
19582            return isUserRunningLocked(userId, orStopped);
19583        }
19584    }
19585
19586    boolean isUserRunningLocked(int userId, boolean orStopped) {
19587        UserStartedState state = mStartedUsers.get(userId);
19588        if (state == null) {
19589            return false;
19590        }
19591        if (orStopped) {
19592            return true;
19593        }
19594        return state.mState != UserStartedState.STATE_STOPPING
19595                && state.mState != UserStartedState.STATE_SHUTDOWN;
19596    }
19597
19598    @Override
19599    public int[] getRunningUserIds() {
19600        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19601                != PackageManager.PERMISSION_GRANTED) {
19602            String msg = "Permission Denial: isUserRunning() from pid="
19603                    + Binder.getCallingPid()
19604                    + ", uid=" + Binder.getCallingUid()
19605                    + " requires " + INTERACT_ACROSS_USERS;
19606            Slog.w(TAG, msg);
19607            throw new SecurityException(msg);
19608        }
19609        synchronized (this) {
19610            return mStartedUserArray;
19611        }
19612    }
19613
19614    private void updateStartedUserArrayLocked() {
19615        int num = 0;
19616        for (int i=0; i<mStartedUsers.size();  i++) {
19617            UserStartedState uss = mStartedUsers.valueAt(i);
19618            // This list does not include stopping users.
19619            if (uss.mState != UserStartedState.STATE_STOPPING
19620                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19621                num++;
19622            }
19623        }
19624        mStartedUserArray = new int[num];
19625        num = 0;
19626        for (int i=0; i<mStartedUsers.size();  i++) {
19627            UserStartedState uss = mStartedUsers.valueAt(i);
19628            if (uss.mState != UserStartedState.STATE_STOPPING
19629                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19630                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19631                num++;
19632            }
19633        }
19634    }
19635
19636    @Override
19637    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19638        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19639                != PackageManager.PERMISSION_GRANTED) {
19640            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19641                    + Binder.getCallingPid()
19642                    + ", uid=" + Binder.getCallingUid()
19643                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19644            Slog.w(TAG, msg);
19645            throw new SecurityException(msg);
19646        }
19647
19648        mUserSwitchObservers.register(observer);
19649    }
19650
19651    @Override
19652    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19653        mUserSwitchObservers.unregister(observer);
19654    }
19655
19656    int[] getUsersLocked() {
19657        UserManagerService ums = getUserManagerLocked();
19658        return ums != null ? ums.getUserIds() : new int[] { 0 };
19659    }
19660
19661    UserManagerService getUserManagerLocked() {
19662        if (mUserManager == null) {
19663            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19664            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19665        }
19666        return mUserManager;
19667    }
19668
19669    private int applyUserId(int uid, int userId) {
19670        return UserHandle.getUid(userId, uid);
19671    }
19672
19673    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19674        if (info == null) return null;
19675        ApplicationInfo newInfo = new ApplicationInfo(info);
19676        newInfo.uid = applyUserId(info.uid, userId);
19677        newInfo.dataDir = PackageManager.getDataDirForUser(info.volumeUuid, info.packageName,
19678                userId).getAbsolutePath();
19679        return newInfo;
19680    }
19681
19682    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19683        if (aInfo == null
19684                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19685            return aInfo;
19686        }
19687
19688        ActivityInfo info = new ActivityInfo(aInfo);
19689        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19690        return info;
19691    }
19692
19693    private final class LocalService extends ActivityManagerInternal {
19694        @Override
19695        public void onWakefulnessChanged(int wakefulness) {
19696            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
19697        }
19698
19699        @Override
19700        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19701                String processName, String abiOverride, int uid, Runnable crashHandler) {
19702            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19703                    processName, abiOverride, uid, crashHandler);
19704        }
19705    }
19706
19707    /**
19708     * An implementation of IAppTask, that allows an app to manage its own tasks via
19709     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19710     * only the process that calls getAppTasks() can call the AppTask methods.
19711     */
19712    class AppTaskImpl extends IAppTask.Stub {
19713        private int mTaskId;
19714        private int mCallingUid;
19715
19716        public AppTaskImpl(int taskId, int callingUid) {
19717            mTaskId = taskId;
19718            mCallingUid = callingUid;
19719        }
19720
19721        private void checkCaller() {
19722            if (mCallingUid != Binder.getCallingUid()) {
19723                throw new SecurityException("Caller " + mCallingUid
19724                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19725            }
19726        }
19727
19728        @Override
19729        public void finishAndRemoveTask() {
19730            checkCaller();
19731
19732            synchronized (ActivityManagerService.this) {
19733                long origId = Binder.clearCallingIdentity();
19734                try {
19735                    if (!removeTaskByIdLocked(mTaskId, false)) {
19736                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19737                    }
19738                } finally {
19739                    Binder.restoreCallingIdentity(origId);
19740                }
19741            }
19742        }
19743
19744        @Override
19745        public ActivityManager.RecentTaskInfo getTaskInfo() {
19746            checkCaller();
19747
19748            synchronized (ActivityManagerService.this) {
19749                long origId = Binder.clearCallingIdentity();
19750                try {
19751                    TaskRecord tr = mRecentTasks.taskForIdLocked(mTaskId);
19752                    if (tr == null) {
19753                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19754                    }
19755                    return createRecentTaskInfoFromTaskRecord(tr);
19756                } finally {
19757                    Binder.restoreCallingIdentity(origId);
19758                }
19759            }
19760        }
19761
19762        @Override
19763        public void moveToFront() {
19764            checkCaller();
19765            // Will bring task to front if it already has a root activity.
19766            startActivityFromRecentsInner(mTaskId, null);
19767        }
19768
19769        @Override
19770        public int startActivity(IBinder whoThread, String callingPackage,
19771                Intent intent, String resolvedType, Bundle options) {
19772            checkCaller();
19773
19774            int callingUser = UserHandle.getCallingUserId();
19775            TaskRecord tr;
19776            IApplicationThread appThread;
19777            synchronized (ActivityManagerService.this) {
19778                tr = mRecentTasks.taskForIdLocked(mTaskId);
19779                if (tr == null) {
19780                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19781                }
19782                appThread = ApplicationThreadNative.asInterface(whoThread);
19783                if (appThread == null) {
19784                    throw new IllegalArgumentException("Bad app thread " + appThread);
19785                }
19786            }
19787            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19788                    resolvedType, null, null, null, null, 0, 0, null, null,
19789                    null, options, callingUser, null, tr);
19790        }
19791
19792        @Override
19793        public void setExcludeFromRecents(boolean exclude) {
19794            checkCaller();
19795
19796            synchronized (ActivityManagerService.this) {
19797                long origId = Binder.clearCallingIdentity();
19798                try {
19799                    TaskRecord tr = mRecentTasks.taskForIdLocked(mTaskId);
19800                    if (tr == null) {
19801                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19802                    }
19803                    Intent intent = tr.getBaseIntent();
19804                    if (exclude) {
19805                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19806                    } else {
19807                        intent.setFlags(intent.getFlags()
19808                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19809                    }
19810                } finally {
19811                    Binder.restoreCallingIdentity(origId);
19812                }
19813            }
19814        }
19815    }
19816}
19817